@jackwener/opencli 1.6.8 → 1.6.10
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.md +117 -59
- package/README.zh-CN.md +123 -79
- package/dist/clis/_shared/common.d.ts +3 -0
- package/dist/clis/_shared/common.js +22 -0
- package/dist/clis/bilibili/hot.d.ts +1 -0
- package/dist/clis/bilibili/hot.js +35 -0
- package/dist/clis/bluesky/feeds.d.ts +1 -0
- package/dist/clis/bluesky/feeds.js +27 -0
- package/dist/clis/bluesky/followers.d.ts +1 -0
- package/dist/clis/bluesky/followers.js +27 -0
- package/dist/clis/bluesky/following.d.ts +1 -0
- package/dist/clis/bluesky/following.js +27 -0
- package/dist/clis/bluesky/profile.d.ts +1 -0
- package/dist/clis/bluesky/profile.js +29 -0
- package/dist/clis/bluesky/search.d.ts +1 -0
- package/dist/clis/bluesky/search.js +28 -0
- package/dist/clis/bluesky/starter-packs.d.ts +1 -0
- package/dist/clis/bluesky/starter-packs.js +28 -0
- package/dist/clis/bluesky/thread.d.ts +1 -0
- package/dist/clis/bluesky/thread.js +30 -0
- package/dist/clis/bluesky/trending.d.ts +1 -0
- package/dist/clis/bluesky/trending.js +19 -0
- package/dist/clis/bluesky/user.d.ts +1 -0
- package/dist/clis/bluesky/user.js +33 -0
- package/dist/clis/cnki/search.d.ts +1 -0
- package/dist/clis/cnki/search.js +60 -0
- package/dist/clis/cnki/search.test.d.ts +1 -0
- package/dist/clis/cnki/search.test.js +18 -0
- package/dist/clis/devto/tag.d.ts +1 -0
- package/dist/clis/devto/tag.js +32 -0
- package/dist/clis/devto/top.d.ts +1 -0
- package/dist/clis/devto/top.js +26 -0
- package/dist/clis/devto/user.d.ts +1 -0
- package/dist/clis/devto/user.js +31 -0
- package/dist/clis/dictionary/examples.d.ts +1 -0
- package/dist/clis/dictionary/examples.js +27 -0
- package/dist/clis/dictionary/search.d.ts +1 -0
- package/dist/clis/dictionary/search.js +29 -0
- package/dist/clis/dictionary/synonyms.d.ts +1 -0
- package/dist/clis/dictionary/synonyms.js +27 -0
- package/dist/clis/douban/subject.d.ts +1 -0
- package/dist/clis/douban/subject.js +118 -0
- package/dist/clis/douban/top250.d.ts +1 -0
- package/dist/clis/douban/top250.js +67 -0
- package/dist/clis/facebook/add-friend.d.ts +1 -0
- package/dist/clis/facebook/add-friend.js +43 -0
- package/dist/clis/facebook/events.d.ts +1 -0
- package/dist/clis/facebook/events.js +40 -0
- package/dist/clis/facebook/feed.d.ts +1 -0
- package/dist/clis/facebook/feed.js +59 -0
- package/dist/clis/facebook/friends.d.ts +1 -0
- package/dist/clis/facebook/friends.js +38 -0
- package/dist/clis/facebook/groups.d.ts +1 -0
- package/dist/clis/facebook/groups.js +46 -0
- package/dist/clis/facebook/join-group.d.ts +1 -0
- package/dist/clis/facebook/join-group.js +44 -0
- package/dist/clis/facebook/memories.d.ts +1 -0
- package/dist/clis/facebook/memories.js +35 -0
- package/dist/clis/facebook/notifications.d.ts +1 -0
- package/dist/clis/facebook/notifications.js +36 -0
- package/dist/clis/facebook/profile.d.ts +1 -0
- package/dist/clis/facebook/profile.js +37 -0
- package/dist/clis/facebook/search.d.ts +1 -0
- package/dist/clis/facebook/search.js +38 -0
- package/dist/clis/facebook/search.test.d.ts +1 -1
- package/dist/clis/facebook/search.test.js +6 -9
- package/dist/clis/gitee/index.d.ts +3 -0
- package/dist/clis/gitee/index.js +3 -0
- package/dist/clis/gitee/search.d.ts +1 -0
- package/dist/clis/gitee/search.js +136 -0
- package/dist/clis/gitee/trending.d.ts +1 -0
- package/dist/clis/gitee/trending.js +567 -0
- package/dist/clis/gitee/user.d.ts +1 -0
- package/dist/clis/gitee/user.js +199 -0
- package/dist/clis/gitee/user.test.d.ts +1 -0
- package/dist/clis/gitee/user.test.js +63 -0
- package/dist/clis/hackernews/ask.d.ts +1 -0
- package/dist/clis/hackernews/ask.js +29 -0
- package/dist/clis/hackernews/best.d.ts +1 -0
- package/dist/clis/hackernews/best.js +29 -0
- package/dist/clis/hackernews/jobs.d.ts +1 -0
- package/dist/clis/hackernews/jobs.js +27 -0
- package/dist/clis/hackernews/new.d.ts +1 -0
- package/dist/clis/hackernews/new.js +29 -0
- package/dist/clis/hackernews/search.d.ts +1 -0
- package/dist/clis/hackernews/search.js +36 -0
- package/dist/clis/hackernews/show.d.ts +1 -0
- package/dist/clis/hackernews/show.js +29 -0
- package/dist/clis/hackernews/top.d.ts +1 -0
- package/dist/clis/hackernews/top.js +29 -0
- package/dist/clis/hackernews/user.d.ts +1 -0
- package/dist/clis/hackernews/user.js +22 -0
- package/dist/clis/hupu/hot.d.ts +1 -0
- package/dist/clis/hupu/hot.js +40 -0
- package/dist/clis/instagram/comment.d.ts +1 -0
- package/dist/clis/instagram/comment.js +47 -0
- package/dist/clis/instagram/explore.d.ts +1 -0
- package/dist/clis/instagram/explore.js +41 -0
- package/dist/clis/instagram/follow.d.ts +1 -0
- package/dist/clis/instagram/follow.js +43 -0
- package/dist/clis/instagram/followers.d.ts +1 -0
- package/dist/clis/instagram/followers.js +45 -0
- package/dist/clis/instagram/following.d.ts +1 -0
- package/dist/clis/instagram/following.js +45 -0
- package/dist/clis/instagram/like.d.ts +1 -0
- package/dist/clis/instagram/like.js +45 -0
- package/dist/clis/instagram/profile.d.ts +1 -0
- package/dist/clis/instagram/profile.js +39 -0
- package/dist/clis/instagram/save.d.ts +1 -0
- package/dist/clis/instagram/save.js +45 -0
- package/dist/clis/instagram/saved.d.ts +1 -0
- package/dist/clis/instagram/saved.js +38 -0
- package/dist/clis/instagram/search.d.ts +1 -0
- package/dist/clis/instagram/search.js +38 -0
- package/dist/clis/instagram/unfollow.d.ts +1 -0
- package/dist/clis/instagram/unfollow.js +40 -0
- package/dist/clis/instagram/unlike.d.ts +1 -0
- package/dist/clis/instagram/unlike.js +45 -0
- package/dist/clis/instagram/unsave.d.ts +1 -0
- package/dist/clis/instagram/unsave.js +45 -0
- package/dist/clis/instagram/user.d.ts +1 -0
- package/dist/clis/instagram/user.js +48 -0
- package/dist/clis/jd/add-cart.d.ts +1 -0
- package/dist/clis/jd/add-cart.js +71 -0
- package/dist/clis/jd/cart.d.ts +1 -0
- package/dist/clis/jd/cart.js +79 -0
- package/dist/clis/jd/commands.test.d.ts +5 -0
- package/dist/clis/jd/commands.test.js +64 -0
- package/dist/clis/jd/detail.d.ts +1 -0
- package/dist/clis/jd/detail.js +62 -0
- package/dist/clis/jd/reviews.d.ts +1 -0
- package/dist/clis/jd/reviews.js +54 -0
- package/dist/clis/jd/search.d.ts +1 -0
- package/dist/clis/jd/search.js +65 -0
- package/dist/clis/jianyu/search.d.ts +14 -0
- package/dist/clis/jianyu/search.js +135 -0
- package/dist/clis/jianyu/search.test.d.ts +1 -0
- package/dist/clis/jianyu/search.test.js +23 -0
- package/dist/clis/jike/post.d.ts +1 -0
- package/dist/clis/jike/post.js +61 -0
- package/dist/clis/jike/topic.d.ts +1 -0
- package/dist/clis/jike/topic.js +51 -0
- package/dist/clis/jike/user.d.ts +1 -0
- package/dist/clis/jike/user.js +50 -0
- package/dist/clis/jimeng/generate.d.ts +1 -0
- package/dist/clis/jimeng/generate.js +83 -0
- package/dist/clis/jimeng/history.d.ts +1 -0
- package/dist/clis/jimeng/history.js +47 -0
- package/dist/clis/jimeng/new.d.ts +1 -0
- package/dist/clis/jimeng/new.js +43 -0
- package/dist/clis/jimeng/workspaces.d.ts +1 -0
- package/dist/clis/jimeng/workspaces.js +41 -0
- package/dist/clis/linux-do/categories.d.ts +1 -0
- package/dist/clis/linux-do/categories.js +65 -0
- package/dist/clis/linux-do/search.d.ts +1 -0
- package/dist/clis/linux-do/search.js +41 -0
- package/dist/clis/linux-do/tags.d.ts +1 -0
- package/dist/clis/linux-do/tags.js +39 -0
- package/dist/clis/linux-do/topic-content.test.js +5 -5
- package/dist/clis/linux-do/topic.d.ts +1 -0
- package/dist/clis/linux-do/topic.js +56 -0
- package/dist/clis/linux-do/user-posts.d.ts +1 -0
- package/dist/clis/linux-do/user-posts.js +61 -0
- package/dist/clis/linux-do/user-topics.d.ts +1 -0
- package/dist/clis/linux-do/user-topics.js +48 -0
- package/dist/clis/lobsters/active.d.ts +1 -0
- package/dist/clis/lobsters/active.js +26 -0
- package/dist/clis/lobsters/hot.d.ts +1 -0
- package/dist/clis/lobsters/hot.js +26 -0
- package/dist/clis/lobsters/newest.d.ts +1 -0
- package/dist/clis/lobsters/newest.js +26 -0
- package/dist/clis/lobsters/tag.d.ts +1 -0
- package/dist/clis/lobsters/tag.js +32 -0
- package/dist/clis/pixiv/detail.d.ts +1 -0
- package/dist/clis/pixiv/detail.js +58 -0
- package/dist/clis/pixiv/ranking.d.ts +1 -0
- package/dist/clis/pixiv/ranking.js +59 -0
- package/dist/clis/pixiv/user.d.ts +1 -0
- package/dist/clis/pixiv/user.js +52 -0
- package/dist/clis/quark/ls.d.ts +1 -0
- package/dist/clis/quark/ls.js +63 -0
- package/dist/clis/quark/mkdir.d.ts +1 -0
- package/dist/clis/quark/mkdir.js +36 -0
- package/dist/clis/quark/mv.d.ts +1 -0
- package/dist/clis/quark/mv.js +53 -0
- package/dist/clis/quark/rename.d.ts +1 -0
- package/dist/clis/quark/rename.js +26 -0
- package/dist/clis/quark/rm.d.ts +1 -0
- package/dist/clis/quark/rm.js +24 -0
- package/dist/clis/quark/save.d.ts +1 -0
- package/dist/clis/quark/save.js +80 -0
- package/dist/clis/quark/share-tree.d.ts +1 -0
- package/dist/clis/quark/share-tree.js +45 -0
- package/dist/clis/quark/utils.d.ts +50 -0
- package/dist/clis/quark/utils.js +146 -0
- package/dist/clis/quark/utils.test.d.ts +1 -0
- package/dist/clis/quark/utils.test.js +58 -0
- package/dist/clis/reddit/frontpage.d.ts +1 -0
- package/dist/clis/reddit/frontpage.js +31 -0
- package/dist/clis/reddit/hot.d.ts +1 -0
- package/dist/clis/reddit/hot.js +45 -0
- package/dist/clis/reddit/popular.d.ts +1 -0
- package/dist/clis/reddit/popular.js +41 -0
- package/dist/clis/reddit/search.d.ts +1 -0
- package/dist/clis/reddit/search.js +65 -0
- package/dist/clis/reddit/subreddit.d.ts +1 -0
- package/dist/clis/reddit/subreddit.js +52 -0
- package/dist/clis/reddit/user-comments.d.ts +1 -0
- package/dist/clis/reddit/user-comments.js +44 -0
- package/dist/clis/reddit/user-posts.d.ts +1 -0
- package/dist/clis/reddit/user-posts.js +42 -0
- package/dist/clis/reddit/user.d.ts +1 -0
- package/dist/clis/reddit/user.js +37 -0
- package/dist/clis/stackoverflow/bounties.d.ts +1 -0
- package/dist/clis/stackoverflow/bounties.js +27 -0
- package/dist/clis/stackoverflow/hot.d.ts +1 -0
- package/dist/clis/stackoverflow/hot.js +24 -0
- package/dist/clis/stackoverflow/search.d.ts +1 -0
- package/dist/clis/stackoverflow/search.js +27 -0
- package/dist/clis/stackoverflow/unanswered.d.ts +1 -0
- package/dist/clis/stackoverflow/unanswered.js +26 -0
- package/dist/clis/steam/top-sellers.d.ts +1 -0
- package/dist/clis/steam/top-sellers.js +25 -0
- package/dist/clis/taobao/add-cart.d.ts +1 -0
- package/dist/clis/taobao/add-cart.js +149 -0
- package/dist/clis/taobao/cart.d.ts +1 -0
- package/dist/clis/taobao/cart.js +95 -0
- package/dist/clis/taobao/commands.test.d.ts +5 -0
- package/dist/clis/taobao/commands.test.js +64 -0
- package/dist/clis/taobao/detail.d.ts +1 -0
- package/dist/clis/taobao/detail.js +70 -0
- package/dist/clis/taobao/reviews.d.ts +1 -0
- package/dist/clis/taobao/reviews.js +76 -0
- package/dist/clis/taobao/search.d.ts +1 -0
- package/dist/clis/taobao/search.js +96 -0
- package/dist/clis/tiktok/comment.d.ts +1 -0
- package/dist/clis/tiktok/comment.js +57 -0
- package/dist/clis/tiktok/explore.d.ts +1 -0
- package/dist/clis/tiktok/explore.js +35 -0
- package/dist/clis/tiktok/follow.d.ts +1 -0
- package/dist/clis/tiktok/follow.js +39 -0
- package/dist/clis/tiktok/following.d.ts +1 -0
- package/dist/clis/tiktok/following.js +42 -0
- package/dist/clis/tiktok/friends.d.ts +1 -0
- package/dist/clis/tiktok/friends.js +43 -0
- package/dist/clis/tiktok/like.d.ts +1 -0
- package/dist/clis/tiktok/like.js +33 -0
- package/dist/clis/tiktok/live.d.ts +1 -0
- package/dist/clis/tiktok/live.js +47 -0
- package/dist/clis/tiktok/notifications.d.ts +1 -0
- package/dist/clis/tiktok/notifications.js +49 -0
- package/dist/clis/tiktok/profile.d.ts +1 -0
- package/dist/clis/tiktok/profile.js +54 -0
- package/dist/clis/tiktok/save.d.ts +1 -0
- package/dist/clis/tiktok/save.js +29 -0
- package/dist/clis/tiktok/search.d.ts +1 -0
- package/dist/clis/tiktok/search.js +39 -0
- package/dist/clis/tiktok/unfollow.d.ts +1 -0
- package/dist/clis/tiktok/unfollow.js +44 -0
- package/dist/clis/tiktok/unlike.d.ts +1 -0
- package/dist/clis/tiktok/unlike.js +33 -0
- package/dist/clis/tiktok/unsave.d.ts +1 -0
- package/dist/clis/tiktok/unsave.js +31 -0
- package/dist/clis/tiktok/user.d.ts +1 -0
- package/dist/clis/tiktok/user.js +41 -0
- package/dist/clis/twitter/reply.js +3 -8
- package/dist/clis/twitter/reply.test.js +5 -5
- package/dist/clis/v2ex/hot.d.ts +1 -0
- package/dist/clis/v2ex/hot.js +25 -0
- package/dist/clis/v2ex/latest.d.ts +1 -0
- package/dist/clis/v2ex/latest.js +25 -0
- package/dist/clis/v2ex/member.d.ts +1 -0
- package/dist/clis/v2ex/member.js +27 -0
- package/dist/clis/v2ex/node.d.ts +1 -0
- package/dist/clis/v2ex/node.js +38 -0
- package/dist/clis/v2ex/nodes.d.ts +1 -0
- package/dist/clis/v2ex/nodes.js +25 -0
- package/dist/clis/v2ex/replies.d.ts +1 -0
- package/dist/clis/v2ex/replies.js +26 -0
- package/dist/clis/v2ex/topic.d.ts +1 -0
- package/dist/clis/v2ex/topic.js +30 -0
- package/dist/clis/v2ex/user.d.ts +1 -0
- package/dist/clis/v2ex/user.js +33 -0
- package/dist/clis/xiaoe/catalog.d.ts +1 -0
- package/dist/clis/xiaoe/catalog.js +125 -0
- package/dist/clis/xiaoe/content.d.ts +1 -0
- package/dist/clis/xiaoe/content.js +39 -0
- package/dist/clis/xiaoe/courses.d.ts +1 -0
- package/dist/clis/xiaoe/courses.js +69 -0
- package/dist/clis/xiaoe/detail.d.ts +1 -0
- package/dist/clis/xiaoe/detail.js +35 -0
- package/dist/clis/xiaoe/play-url.d.ts +1 -0
- package/dist/clis/xiaoe/play-url.js +120 -0
- package/dist/clis/xiaohongshu/feed.d.ts +1 -0
- package/dist/clis/xiaohongshu/feed.js +32 -0
- package/dist/clis/xiaohongshu/note.js +8 -3
- package/dist/clis/xiaohongshu/note.test.js +11 -0
- package/dist/clis/xiaohongshu/notifications.d.ts +1 -0
- package/dist/clis/xiaohongshu/notifications.js +38 -0
- package/dist/clis/xueqiu/earnings-date.d.ts +1 -0
- package/dist/clis/xueqiu/earnings-date.js +61 -0
- package/dist/clis/xueqiu/feed.d.ts +1 -0
- package/dist/clis/xueqiu/feed.js +48 -0
- package/dist/clis/xueqiu/groups.d.ts +1 -0
- package/dist/clis/xueqiu/groups.js +25 -0
- package/dist/clis/xueqiu/hot-stock.d.ts +1 -0
- package/dist/clis/xueqiu/hot-stock.js +44 -0
- package/dist/clis/xueqiu/hot.d.ts +1 -0
- package/dist/clis/xueqiu/hot.js +44 -0
- package/dist/clis/xueqiu/kline.d.ts +1 -0
- package/dist/clis/xueqiu/kline.js +64 -0
- package/dist/clis/xueqiu/search.d.ts +1 -0
- package/dist/clis/xueqiu/search.js +49 -0
- package/dist/clis/xueqiu/stock.d.ts +1 -0
- package/dist/clis/xueqiu/stock.js +72 -0
- package/dist/clis/xueqiu/watchlist.d.ts +1 -0
- package/dist/clis/xueqiu/watchlist.js +45 -0
- package/dist/clis/zhihu/answer.d.ts +1 -0
- package/dist/clis/zhihu/answer.js +194 -0
- package/dist/clis/zhihu/answer.test.d.ts +1 -0
- package/dist/clis/zhihu/answer.test.js +81 -0
- package/dist/clis/zhihu/comment.d.ts +1 -0
- package/dist/clis/zhihu/comment.js +335 -0
- package/dist/clis/zhihu/comment.test.d.ts +1 -0
- package/dist/clis/zhihu/comment.test.js +54 -0
- package/dist/clis/zhihu/favorite.d.ts +1 -0
- package/dist/clis/zhihu/favorite.js +224 -0
- package/dist/clis/zhihu/favorite.test.d.ts +1 -0
- package/dist/clis/zhihu/favorite.test.js +196 -0
- package/dist/clis/zhihu/follow.d.ts +1 -0
- package/dist/clis/zhihu/follow.js +80 -0
- package/dist/clis/zhihu/follow.test.d.ts +1 -0
- package/dist/clis/zhihu/follow.test.js +45 -0
- package/dist/clis/zhihu/hot.d.ts +1 -0
- package/dist/clis/zhihu/hot.js +43 -0
- package/dist/clis/zhihu/like.d.ts +1 -0
- package/dist/clis/zhihu/like.js +91 -0
- package/dist/clis/zhihu/like.test.d.ts +1 -0
- package/dist/clis/zhihu/like.test.js +64 -0
- package/dist/clis/zhihu/search.d.ts +1 -0
- package/dist/clis/zhihu/search.js +52 -0
- package/dist/clis/zhihu/target.d.ts +24 -0
- package/dist/clis/zhihu/target.js +91 -0
- package/dist/clis/zhihu/target.test.d.ts +1 -0
- package/dist/clis/zhihu/target.test.js +77 -0
- package/dist/clis/zhihu/write-shared.d.ts +32 -0
- package/dist/clis/zhihu/write-shared.js +221 -0
- package/dist/clis/zhihu/write-shared.test.d.ts +1 -0
- package/dist/clis/zhihu/write-shared.test.js +175 -0
- package/dist/src/browser/bridge.d.ts +2 -0
- package/dist/src/browser/bridge.js +30 -24
- package/dist/src/browser/daemon-client.d.ts +30 -10
- package/dist/src/browser/daemon-client.js +42 -27
- package/dist/src/browser/daemon-client.test.js +32 -25
- package/dist/src/browser/dom-helpers.test.js +3 -2
- package/dist/src/browser/errors.d.ts +26 -1
- package/dist/src/browser/errors.js +40 -7
- package/dist/src/browser/errors.test.d.ts +1 -0
- package/dist/src/browser/errors.test.js +51 -0
- package/dist/src/browser/index.d.ts +2 -1
- package/dist/src/browser/index.js +1 -1
- package/dist/src/browser/page.d.ts +9 -8
- package/dist/src/browser/page.js +33 -31
- package/dist/src/browser.test.js +27 -8
- package/dist/src/build-manifest.d.ts +5 -11
- package/dist/src/build-manifest.js +6 -75
- package/dist/src/build-manifest.test.js +1 -39
- package/dist/src/cascade.js +3 -2
- package/dist/src/cli.d.ts +3 -3
- package/dist/src/cli.js +73 -65
- package/dist/src/cli.test.js +20 -15
- package/dist/src/clis/binance/asks.d.ts +1 -0
- package/dist/src/clis/binance/asks.js +20 -0
- package/dist/src/clis/binance/commands.test.d.ts +3 -0
- package/dist/src/clis/binance/commands.test.js +58 -0
- package/dist/src/clis/binance/depth.d.ts +1 -0
- package/dist/src/clis/binance/depth.js +20 -0
- package/dist/src/clis/binance/gainers.d.ts +1 -0
- package/dist/src/clis/binance/gainers.js +21 -0
- package/dist/src/clis/binance/klines.d.ts +1 -0
- package/dist/src/clis/binance/klines.js +20 -0
- package/dist/src/clis/binance/losers.d.ts +1 -0
- package/dist/src/clis/binance/losers.js +21 -0
- package/dist/src/clis/binance/pairs.d.ts +1 -0
- package/dist/src/clis/binance/pairs.js +20 -0
- package/dist/src/clis/binance/price.d.ts +1 -0
- package/dist/src/clis/binance/price.js +17 -0
- package/dist/src/clis/binance/prices.d.ts +1 -0
- package/dist/src/clis/binance/prices.js +18 -0
- package/dist/src/clis/binance/ticker.d.ts +1 -0
- package/dist/src/clis/binance/ticker.js +20 -0
- package/dist/src/clis/binance/top.d.ts +1 -0
- package/dist/src/clis/binance/top.js +20 -0
- package/dist/src/clis/binance/trades.d.ts +1 -0
- package/dist/src/clis/binance/trades.js +19 -0
- package/dist/src/commanderAdapter.js +19 -6
- package/dist/src/completion-fast.d.ts +25 -0
- package/dist/src/completion-fast.js +140 -0
- package/dist/src/completion.d.ts +1 -0
- package/dist/src/completion.js +1 -0
- package/dist/src/diagnostic.d.ts +1 -0
- package/dist/src/diagnostic.js +64 -2
- package/dist/src/diagnostic.test.js +93 -3
- package/dist/src/discovery.d.ts +3 -3
- package/dist/src/discovery.js +34 -97
- package/dist/src/doctor.d.ts +2 -0
- package/dist/src/doctor.js +59 -31
- package/dist/src/doctor.test.js +89 -16
- package/dist/src/download/index.d.ts +1 -1
- package/dist/src/engine.test.js +4 -19
- package/dist/src/execution.js +1 -13
- package/dist/src/explore.js +1 -1
- package/dist/src/generate-verified.d.ts +105 -0
- package/dist/src/generate-verified.js +696 -0
- package/dist/src/generate-verified.test.d.ts +1 -0
- package/dist/src/generate-verified.test.js +925 -0
- package/dist/src/generate.d.ts +11 -6
- package/dist/src/generate.js +4 -7
- package/dist/src/main.js +65 -12
- package/dist/src/pipeline/steps/download.d.ts +1 -17
- package/dist/src/pipeline/steps/download.js +20 -31
- package/dist/src/pipeline/steps/intercept.d.ts +1 -1
- package/dist/src/pipeline/steps/intercept.js +1 -1
- package/dist/src/pipeline/steps/tap.d.ts +1 -1
- package/dist/src/pipeline/steps/tap.js +1 -1
- package/dist/src/plugin-scaffold.d.ts +2 -2
- package/dist/src/plugin-scaffold.js +24 -21
- package/dist/src/plugin-scaffold.test.js +1 -1
- package/dist/src/plugin.d.ts +3 -2
- package/dist/src/plugin.js +29 -14
- package/dist/src/plugin.test.js +47 -32
- package/dist/src/record.js +26 -25
- package/dist/src/runtime-detect.js +3 -7
- package/dist/src/scripts/framework.d.ts +3 -0
- package/dist/src/scripts/framework.js +8 -4
- package/dist/src/scripts/store.d.ts +5 -1
- package/dist/src/scripts/store.js +5 -1
- package/dist/src/skill-generate.d.ts +30 -0
- package/dist/src/skill-generate.js +75 -0
- package/dist/src/skill-generate.test.d.ts +1 -0
- package/dist/src/skill-generate.test.js +173 -0
- package/dist/src/synthesize.d.ts +1 -1
- package/dist/src/synthesize.js +7 -8
- package/dist/src/types.d.ts +3 -1
- package/package.json +5 -5
- package/dist/clis/bilibili/hot.yaml +0 -38
- package/dist/clis/bluesky/feeds.yaml +0 -29
- package/dist/clis/bluesky/followers.yaml +0 -33
- package/dist/clis/bluesky/following.yaml +0 -33
- package/dist/clis/bluesky/profile.yaml +0 -27
- package/dist/clis/bluesky/search.yaml +0 -34
- package/dist/clis/bluesky/starter-packs.yaml +0 -34
- package/dist/clis/bluesky/thread.yaml +0 -32
- package/dist/clis/bluesky/trending.yaml +0 -27
- package/dist/clis/bluesky/user.yaml +0 -34
- package/dist/clis/devto/tag.yaml +0 -34
- package/dist/clis/devto/top.yaml +0 -29
- package/dist/clis/devto/user.yaml +0 -33
- package/dist/clis/dictionary/examples.yaml +0 -25
- package/dist/clis/dictionary/search.yaml +0 -27
- package/dist/clis/dictionary/synonyms.yaml +0 -25
- package/dist/clis/douban/subject.yaml +0 -107
- package/dist/clis/douban/top250.yaml +0 -70
- package/dist/clis/facebook/add-friend.yaml +0 -43
- package/dist/clis/facebook/events.yaml +0 -44
- package/dist/clis/facebook/feed.yaml +0 -63
- package/dist/clis/facebook/friends.yaml +0 -42
- package/dist/clis/facebook/groups.yaml +0 -50
- package/dist/clis/facebook/join-group.yaml +0 -44
- package/dist/clis/facebook/memories.yaml +0 -39
- package/dist/clis/facebook/notifications.yaml +0 -40
- package/dist/clis/facebook/profile.yaml +0 -37
- package/dist/clis/facebook/search.yaml +0 -47
- package/dist/clis/hackernews/ask.yaml +0 -38
- package/dist/clis/hackernews/best.yaml +0 -38
- package/dist/clis/hackernews/jobs.yaml +0 -36
- package/dist/clis/hackernews/new.yaml +0 -38
- package/dist/clis/hackernews/search.yaml +0 -44
- package/dist/clis/hackernews/show.yaml +0 -38
- package/dist/clis/hackernews/top.yaml +0 -38
- package/dist/clis/hackernews/user.yaml +0 -25
- package/dist/clis/hupu/hot.yaml +0 -43
- package/dist/clis/instagram/comment.yaml +0 -52
- package/dist/clis/instagram/explore.yaml +0 -43
- package/dist/clis/instagram/follow.yaml +0 -41
- package/dist/clis/instagram/followers.yaml +0 -51
- package/dist/clis/instagram/following.yaml +0 -51
- package/dist/clis/instagram/like.yaml +0 -46
- package/dist/clis/instagram/profile.yaml +0 -42
- package/dist/clis/instagram/save.yaml +0 -46
- package/dist/clis/instagram/saved.yaml +0 -40
- package/dist/clis/instagram/search.yaml +0 -44
- package/dist/clis/instagram/unfollow.yaml +0 -38
- package/dist/clis/instagram/unlike.yaml +0 -46
- package/dist/clis/instagram/unsave.yaml +0 -46
- package/dist/clis/instagram/user.yaml +0 -54
- package/dist/clis/jike/post.yaml +0 -59
- package/dist/clis/jike/topic.yaml +0 -53
- package/dist/clis/jike/user.yaml +0 -52
- package/dist/clis/jimeng/generate.yaml +0 -85
- package/dist/clis/jimeng/history.yaml +0 -46
- package/dist/clis/linux-do/categories.yaml +0 -70
- package/dist/clis/linux-do/search.yaml +0 -48
- package/dist/clis/linux-do/tags.yaml +0 -41
- package/dist/clis/linux-do/topic.yaml +0 -62
- package/dist/clis/linux-do/user-posts.yaml +0 -67
- package/dist/clis/linux-do/user-topics.yaml +0 -54
- package/dist/clis/lobsters/active.yaml +0 -29
- package/dist/clis/lobsters/hot.yaml +0 -29
- package/dist/clis/lobsters/newest.yaml +0 -29
- package/dist/clis/lobsters/tag.yaml +0 -34
- package/dist/clis/pixiv/detail.yaml +0 -49
- package/dist/clis/pixiv/ranking.yaml +0 -53
- package/dist/clis/pixiv/user.yaml +0 -46
- package/dist/clis/reddit/frontpage.yaml +0 -30
- package/dist/clis/reddit/hot.yaml +0 -47
- package/dist/clis/reddit/popular.yaml +0 -40
- package/dist/clis/reddit/search.yaml +0 -61
- package/dist/clis/reddit/subreddit.yaml +0 -50
- package/dist/clis/reddit/user-comments.yaml +0 -46
- package/dist/clis/reddit/user-posts.yaml +0 -44
- package/dist/clis/reddit/user.yaml +0 -40
- package/dist/clis/stackoverflow/bounties.yaml +0 -29
- package/dist/clis/stackoverflow/hot.yaml +0 -28
- package/dist/clis/stackoverflow/search.yaml +0 -33
- package/dist/clis/stackoverflow/unanswered.yaml +0 -28
- package/dist/clis/steam/top-sellers.yaml +0 -29
- package/dist/clis/tiktok/comment.yaml +0 -66
- package/dist/clis/tiktok/explore.yaml +0 -39
- package/dist/clis/tiktok/follow.yaml +0 -39
- package/dist/clis/tiktok/following.yaml +0 -46
- package/dist/clis/tiktok/friends.yaml +0 -47
- package/dist/clis/tiktok/like.yaml +0 -38
- package/dist/clis/tiktok/live.yaml +0 -51
- package/dist/clis/tiktok/notifications.yaml +0 -52
- package/dist/clis/tiktok/profile.yaml +0 -45
- package/dist/clis/tiktok/save.yaml +0 -34
- package/dist/clis/tiktok/search.yaml +0 -47
- package/dist/clis/tiktok/unfollow.yaml +0 -44
- package/dist/clis/tiktok/unlike.yaml +0 -38
- package/dist/clis/tiktok/unsave.yaml +0 -36
- package/dist/clis/tiktok/user.yaml +0 -44
- package/dist/clis/v2ex/hot.yaml +0 -28
- package/dist/clis/v2ex/latest.yaml +0 -28
- package/dist/clis/v2ex/member.yaml +0 -29
- package/dist/clis/v2ex/node.yaml +0 -34
- package/dist/clis/v2ex/nodes.yaml +0 -31
- package/dist/clis/v2ex/replies.yaml +0 -32
- package/dist/clis/v2ex/topic.yaml +0 -33
- package/dist/clis/v2ex/user.yaml +0 -34
- package/dist/clis/xiaoe/catalog.yaml +0 -129
- package/dist/clis/xiaoe/content.yaml +0 -43
- package/dist/clis/xiaoe/courses.yaml +0 -73
- package/dist/clis/xiaoe/detail.yaml +0 -39
- package/dist/clis/xiaoe/play-url.yaml +0 -124
- package/dist/clis/xiaohongshu/feed.yaml +0 -31
- package/dist/clis/xiaohongshu/notifications.yaml +0 -37
- package/dist/clis/xueqiu/earnings-date.yaml +0 -69
- package/dist/clis/xueqiu/feed.yaml +0 -53
- package/dist/clis/xueqiu/groups.yaml +0 -23
- package/dist/clis/xueqiu/hot-stock.yaml +0 -49
- package/dist/clis/xueqiu/hot.yaml +0 -46
- package/dist/clis/xueqiu/kline.yaml +0 -65
- package/dist/clis/xueqiu/search.yaml +0 -55
- package/dist/clis/xueqiu/stock.yaml +0 -69
- package/dist/clis/xueqiu/watchlist.yaml +0 -46
- package/dist/clis/zhihu/hot.yaml +0 -46
- package/dist/clis/zhihu/search.yaml +0 -59
- package/dist/src/browser/discover.d.ts +0 -15
- package/dist/src/browser/discover.js +0 -19
- package/dist/src/yaml-schema.d.ts +0 -29
- package/dist/src/yaml-schema.js +0 -22
package/dist/src/browser/page.js
CHANGED
|
@@ -4,22 +4,17 @@
|
|
|
4
4
|
* All browser operations are ultimately 'exec' (JS evaluation via CDP)
|
|
5
5
|
* plus a few native Chrome Extension APIs (tabs, cookies, navigate).
|
|
6
6
|
*
|
|
7
|
-
* IMPORTANT: After goto(), we remember the
|
|
8
|
-
* action and pass it to all subsequent commands. This
|
|
9
|
-
*
|
|
10
|
-
* chrome-extension:// tab that can't be debugged.
|
|
7
|
+
* IMPORTANT: After goto(), we remember the page identity (targetId) returned
|
|
8
|
+
* by the navigate action and pass it to all subsequent commands. This ensures
|
|
9
|
+
* page-scoped operations target the correct page without guessing.
|
|
11
10
|
*/
|
|
12
|
-
import { sendCommand } from './daemon-client.js';
|
|
11
|
+
import { sendCommand, sendCommandFull } from './daemon-client.js';
|
|
13
12
|
import { wrapForEval } from './utils.js';
|
|
14
13
|
import { saveBase64ToFile } from '../utils.js';
|
|
15
14
|
import { generateStealthJs } from './stealth.js';
|
|
16
15
|
import { waitForDomStableJs } from './dom-helpers.js';
|
|
17
16
|
import { BasePage } from './base-page.js';
|
|
18
|
-
|
|
19
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
20
|
-
return message.includes('Inspected target navigated or closed')
|
|
21
|
-
|| (message.includes('-32000') && message.toLowerCase().includes('target'));
|
|
22
|
-
}
|
|
17
|
+
import { classifyBrowserError } from './errors.js';
|
|
23
18
|
/**
|
|
24
19
|
* Page — implements IPage by talking to the daemon via HTTP.
|
|
25
20
|
*/
|
|
@@ -29,27 +24,27 @@ export class Page extends BasePage {
|
|
|
29
24
|
super();
|
|
30
25
|
this.workspace = workspace;
|
|
31
26
|
}
|
|
32
|
-
/** Active
|
|
33
|
-
|
|
27
|
+
/** Active page identity (targetId), set after navigate and used in all subsequent commands */
|
|
28
|
+
_page;
|
|
34
29
|
/** Helper: spread workspace into command params */
|
|
35
30
|
_wsOpt() {
|
|
36
31
|
return { workspace: this.workspace };
|
|
37
32
|
}
|
|
38
|
-
/** Helper: spread workspace +
|
|
33
|
+
/** Helper: spread workspace + page identity into command params */
|
|
39
34
|
_cmdOpts() {
|
|
40
35
|
return {
|
|
41
36
|
workspace: this.workspace,
|
|
42
|
-
...(this.
|
|
37
|
+
...(this._page !== undefined && { page: this._page }),
|
|
43
38
|
};
|
|
44
39
|
}
|
|
45
40
|
async goto(url, options) {
|
|
46
|
-
const result = await
|
|
41
|
+
const result = await sendCommandFull('navigate', {
|
|
47
42
|
url,
|
|
48
43
|
...this._cmdOpts(),
|
|
49
44
|
});
|
|
50
|
-
// Remember the
|
|
51
|
-
if (result
|
|
52
|
-
this.
|
|
45
|
+
// Remember the page identity (targetId) for subsequent calls
|
|
46
|
+
if (result.page) {
|
|
47
|
+
this._page = result.page;
|
|
53
48
|
}
|
|
54
49
|
this._lastUrl = url;
|
|
55
50
|
// Inject stealth + settle in a single round-trip instead of two sequential exec calls.
|
|
@@ -65,17 +60,18 @@ export class Page extends BasePage {
|
|
|
65
60
|
await sendCommand('exec', combinedOpts);
|
|
66
61
|
}
|
|
67
62
|
catch (err) {
|
|
68
|
-
|
|
63
|
+
const advice = classifyBrowserError(err);
|
|
64
|
+
// Only settle-retry on target navigation (SPA client-side redirects).
|
|
65
|
+
// Extension/daemon errors are already retried by sendCommandRaw —
|
|
66
|
+
// retrying them here would silently swallow real failures.
|
|
67
|
+
if (advice.kind !== 'target-navigation')
|
|
69
68
|
throw err;
|
|
70
|
-
// SPA client-side redirects can invalidate the CDP target after
|
|
71
|
-
// chrome.tabs reports 'complete'. Wait briefly for the new document
|
|
72
|
-
// to load, then retry the settle probe once.
|
|
73
69
|
try {
|
|
74
|
-
await new Promise((r) => setTimeout(r,
|
|
70
|
+
await new Promise((r) => setTimeout(r, advice.delayMs));
|
|
75
71
|
await sendCommand('exec', combinedOpts);
|
|
76
72
|
}
|
|
77
73
|
catch (retryErr) {
|
|
78
|
-
if (
|
|
74
|
+
if (classifyBrowserError(retryErr).kind !== 'target-navigation')
|
|
79
75
|
throw retryErr;
|
|
80
76
|
}
|
|
81
77
|
}
|
|
@@ -93,8 +89,13 @@ export class Page extends BasePage {
|
|
|
93
89
|
}
|
|
94
90
|
}
|
|
95
91
|
}
|
|
92
|
+
/** Get the active page identity (targetId) */
|
|
93
|
+
getActivePage() {
|
|
94
|
+
return this._page;
|
|
95
|
+
}
|
|
96
|
+
/** @deprecated Use getActivePage() instead */
|
|
96
97
|
getActiveTabId() {
|
|
97
|
-
return
|
|
98
|
+
return undefined;
|
|
98
99
|
}
|
|
99
100
|
async evaluate(js) {
|
|
100
101
|
const code = wrapForEval(js);
|
|
@@ -102,9 +103,10 @@ export class Page extends BasePage {
|
|
|
102
103
|
return await sendCommand('exec', { code, ...this._cmdOpts() });
|
|
103
104
|
}
|
|
104
105
|
catch (err) {
|
|
105
|
-
|
|
106
|
+
const advice = classifyBrowserError(err);
|
|
107
|
+
if (advice.kind !== 'target-navigation')
|
|
106
108
|
throw err;
|
|
107
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
109
|
+
await new Promise((resolve) => setTimeout(resolve, advice.delayMs));
|
|
108
110
|
return sendCommand('exec', { code, ...this._cmdOpts() });
|
|
109
111
|
}
|
|
110
112
|
}
|
|
@@ -121,7 +123,7 @@ export class Page extends BasePage {
|
|
|
121
123
|
// Window may already be closed or daemon may be down
|
|
122
124
|
}
|
|
123
125
|
finally {
|
|
124
|
-
this.
|
|
126
|
+
this._page = undefined;
|
|
125
127
|
this._lastUrl = null;
|
|
126
128
|
}
|
|
127
129
|
}
|
|
@@ -130,9 +132,9 @@ export class Page extends BasePage {
|
|
|
130
132
|
return Array.isArray(result) ? result : [];
|
|
131
133
|
}
|
|
132
134
|
async selectTab(index) {
|
|
133
|
-
const result = await
|
|
134
|
-
if (result
|
|
135
|
-
this.
|
|
135
|
+
const result = await sendCommandFull('tabs', { op: 'select', index, ...this._wsOpt() });
|
|
136
|
+
if (result.page)
|
|
137
|
+
this._page = result.page;
|
|
136
138
|
}
|
|
137
139
|
/**
|
|
138
140
|
* Capture a screenshot via CDP Page.captureScreenshot.
|
package/dist/src/browser.test.js
CHANGED
|
@@ -3,7 +3,7 @@ import { BrowserBridge, generateStealthJs } from './browser/index.js';
|
|
|
3
3
|
import { extractTabEntries, diffTabIndexes, appendLimited } from './browser/tabs.js';
|
|
4
4
|
import { withTimeoutMs } from './runtime.js';
|
|
5
5
|
import { __test__ as cdpTest } from './browser/cdp.js';
|
|
6
|
-
import {
|
|
6
|
+
import { classifyBrowserError } from './browser/errors.js';
|
|
7
7
|
import * as daemonClient from './browser/daemon-client.js';
|
|
8
8
|
describe('browser helpers', () => {
|
|
9
9
|
it('extracts tab entries from string snapshots', () => {
|
|
@@ -35,10 +35,18 @@ describe('browser helpers', () => {
|
|
|
35
35
|
it('times out slow promises', async () => {
|
|
36
36
|
await expect(withTimeoutMs(new Promise(() => { }), 10, 'timeout')).rejects.toThrow('timeout');
|
|
37
37
|
});
|
|
38
|
-
it('
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
expect(
|
|
38
|
+
it('classifies browser errors with correct kind and retry advice', () => {
|
|
39
|
+
// CDP target navigation — page-level settle retry
|
|
40
|
+
const nav = classifyBrowserError(new Error('{"code":-32000,"message":"Inspected target navigated or closed"}'));
|
|
41
|
+
expect(nav.kind).toBe('target-navigation');
|
|
42
|
+
expect(nav.delayMs).toBe(200);
|
|
43
|
+
// Extension transient — daemon-client retry only, NOT page-level
|
|
44
|
+
const ext = classifyBrowserError(new Error('Extension disconnected'));
|
|
45
|
+
expect(ext.kind).toBe('extension-transient');
|
|
46
|
+
expect(ext.delayMs).toBe(1500);
|
|
47
|
+
// Non-transient errors — not retryable
|
|
48
|
+
expect(classifyBrowserError(new Error('malformed exec payload')).kind).toBe('non-retryable');
|
|
49
|
+
expect(classifyBrowserError(new Error('Permission denied')).kind).toBe('non-retryable');
|
|
42
50
|
});
|
|
43
51
|
it('prefers the real Electron app target over DevTools and blank pages', () => {
|
|
44
52
|
const target = cdpTest.selectCDPTarget([
|
|
@@ -105,10 +113,21 @@ describe('BrowserBridge state', () => {
|
|
|
105
113
|
await expect(bridge.connect()).rejects.toThrow('Session is closing');
|
|
106
114
|
});
|
|
107
115
|
it('fails fast when daemon is running but extension is disconnected', async () => {
|
|
108
|
-
vi.spyOn(daemonClient, '
|
|
109
|
-
|
|
116
|
+
vi.spyOn(daemonClient, 'getDaemonHealth').mockResolvedValue({
|
|
117
|
+
state: 'no-extension',
|
|
118
|
+
status: {
|
|
119
|
+
ok: true,
|
|
120
|
+
pid: 1,
|
|
121
|
+
uptime: 0,
|
|
122
|
+
extensionConnected: false,
|
|
123
|
+
pending: 0,
|
|
124
|
+
lastCliRequestTime: 0,
|
|
125
|
+
memoryMB: 0,
|
|
126
|
+
port: 0,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
110
129
|
const bridge = new BrowserBridge();
|
|
111
|
-
await expect(bridge.connect({ timeout: 0.1 })).rejects.toThrow('Browser
|
|
130
|
+
await expect(bridge.connect({ timeout: 0.1 })).rejects.toThrow('Browser Bridge extension not connected');
|
|
112
131
|
});
|
|
113
132
|
});
|
|
114
133
|
describe('stealth anti-detection', () => {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Build-time CLI manifest compiler.
|
|
4
4
|
*
|
|
5
|
-
* Scans all
|
|
6
|
-
* manifest.json for instant cold-start registration
|
|
5
|
+
* Scans all TS CLI definitions and pre-compiles them into a single
|
|
6
|
+
* manifest.json for instant cold-start registration.
|
|
7
7
|
*
|
|
8
8
|
* Usage: npx tsx src/build-manifest.ts
|
|
9
9
|
* Output: cli-manifest.json at the package root
|
|
@@ -31,19 +31,13 @@ export interface ManifestEntry {
|
|
|
31
31
|
timeout?: number;
|
|
32
32
|
deprecated?: boolean | string;
|
|
33
33
|
replacedBy?: string;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/** Relative path from clis/ dir, e.g. 'bilibili/hot.yaml' or 'bilibili/search.js' */
|
|
34
|
+
type: 'ts';
|
|
35
|
+
/** Relative path from clis/ dir, e.g. 'bilibili/search.js' */
|
|
37
36
|
modulePath?: string;
|
|
38
|
-
/** Relative path to the original source file from clis/ dir (
|
|
37
|
+
/** Relative path to the original source file from clis/ dir (e.g. 'site/cmd.ts') */
|
|
39
38
|
sourceFile?: string;
|
|
40
39
|
/** Pre-navigation control — see CliCommand.navigateBefore */
|
|
41
40
|
navigateBefore?: boolean | string;
|
|
42
41
|
}
|
|
43
42
|
export declare function loadTsManifestEntries(filePath: string, site: string, importer?: (moduleHref: string) => Promise<unknown>): Promise<ManifestEntry[]>;
|
|
44
|
-
/**
|
|
45
|
-
* When both YAML and TS adapters exist for the same site/name,
|
|
46
|
-
* prefer the TS version (it self-registers and typically has richer logic).
|
|
47
|
-
*/
|
|
48
|
-
export declare function shouldReplaceManifestEntry(current: ManifestEntry, next: ManifestEntry): boolean;
|
|
49
43
|
export declare function buildManifest(): Promise<ManifestEntry[]>;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Build-time CLI manifest compiler.
|
|
4
4
|
*
|
|
5
|
-
* Scans all
|
|
6
|
-
* manifest.json for instant cold-start registration
|
|
5
|
+
* Scans all TS CLI definitions and pre-compiles them into a single
|
|
6
|
+
* manifest.json for instant cold-start registration.
|
|
7
7
|
*
|
|
8
8
|
* Usage: npx tsx src/build-manifest.ts
|
|
9
9
|
* Output: cli-manifest.json at the package root
|
|
@@ -11,14 +11,12 @@
|
|
|
11
11
|
import * as fs from 'node:fs';
|
|
12
12
|
import * as path from 'node:path';
|
|
13
13
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
14
|
-
import yaml from 'js-yaml';
|
|
15
14
|
import { getErrorMessage } from './errors.js';
|
|
16
15
|
import { fullName, getRegistry } from './registry.js';
|
|
17
16
|
import { findPackageRoot, getCliManifestPath } from './package-paths.js';
|
|
18
17
|
const PACKAGE_ROOT = findPackageRoot(fileURLToPath(import.meta.url));
|
|
19
18
|
const CLIS_DIR = path.join(PACKAGE_ROOT, 'clis');
|
|
20
19
|
const OUTPUT = getCliManifestPath(CLIS_DIR);
|
|
21
|
-
import { parseYamlArgs } from './yaml-schema.js';
|
|
22
20
|
import { isRecord } from './utils.js';
|
|
23
21
|
const CLI_MODULE_PATTERN = /\bcli\s*\(/;
|
|
24
22
|
function toManifestArgs(args) {
|
|
@@ -64,43 +62,6 @@ function toManifestEntry(cmd, modulePath, sourceFile) {
|
|
|
64
62
|
navigateBefore: cmd.navigateBefore,
|
|
65
63
|
};
|
|
66
64
|
}
|
|
67
|
-
function scanYaml(filePath, site) {
|
|
68
|
-
try {
|
|
69
|
-
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
70
|
-
const def = yaml.load(raw);
|
|
71
|
-
if (!isRecord(def))
|
|
72
|
-
return null;
|
|
73
|
-
const cliDef = def;
|
|
74
|
-
const strategyStr = cliDef.strategy ?? (cliDef.browser === false ? 'public' : 'cookie');
|
|
75
|
-
const strategy = strategyStr.toUpperCase();
|
|
76
|
-
const browser = cliDef.browser ?? (strategy !== 'PUBLIC');
|
|
77
|
-
const args = parseYamlArgs(cliDef.args);
|
|
78
|
-
return {
|
|
79
|
-
site: cliDef.site ?? site,
|
|
80
|
-
name: cliDef.name ?? path.basename(filePath, path.extname(filePath)),
|
|
81
|
-
description: cliDef.description ?? '',
|
|
82
|
-
domain: cliDef.domain,
|
|
83
|
-
strategy: strategy.toLowerCase(),
|
|
84
|
-
browser,
|
|
85
|
-
aliases: isRecord(cliDef) && Array.isArray(cliDef.aliases)
|
|
86
|
-
? cliDef.aliases.filter((value) => typeof value === 'string')
|
|
87
|
-
: undefined,
|
|
88
|
-
args,
|
|
89
|
-
columns: cliDef.columns,
|
|
90
|
-
pipeline: cliDef.pipeline,
|
|
91
|
-
timeout: cliDef.timeout,
|
|
92
|
-
deprecated: cliDef.deprecated,
|
|
93
|
-
replacedBy: cliDef.replacedBy,
|
|
94
|
-
type: 'yaml',
|
|
95
|
-
sourceFile: path.relative(CLIS_DIR, filePath),
|
|
96
|
-
navigateBefore: cliDef.navigateBefore,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
process.stderr.write(`Warning: failed to parse ${filePath}: ${getErrorMessage(err)}\n`);
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
65
|
export async function loadTsManifestEntries(filePath, site, importer = moduleHref => import(moduleHref)) {
|
|
105
66
|
try {
|
|
106
67
|
const src = fs.readFileSync(filePath, 'utf-8');
|
|
@@ -141,15 +102,6 @@ export async function loadTsManifestEntries(filePath, site, importer = moduleHre
|
|
|
141
102
|
return [];
|
|
142
103
|
}
|
|
143
104
|
}
|
|
144
|
-
/**
|
|
145
|
-
* When both YAML and TS adapters exist for the same site/name,
|
|
146
|
-
* prefer the TS version (it self-registers and typically has richer logic).
|
|
147
|
-
*/
|
|
148
|
-
export function shouldReplaceManifestEntry(current, next) {
|
|
149
|
-
if (current.type === next.type)
|
|
150
|
-
return false;
|
|
151
|
-
return current.type === 'yaml' && next.type === 'ts';
|
|
152
|
-
}
|
|
153
105
|
export async function buildManifest() {
|
|
154
106
|
const manifest = new Map();
|
|
155
107
|
if (fs.existsSync(CLIS_DIR)) {
|
|
@@ -158,32 +110,13 @@ export async function buildManifest() {
|
|
|
158
110
|
if (!fs.statSync(siteDir).isDirectory())
|
|
159
111
|
continue;
|
|
160
112
|
for (const file of fs.readdirSync(siteDir)) {
|
|
161
|
-
|
|
162
|
-
if (file.endsWith('.yaml') || file.endsWith('.yml')) {
|
|
163
|
-
const entry = scanYaml(filePath, site);
|
|
164
|
-
if (entry) {
|
|
165
|
-
const key = `${entry.site}/${entry.name}`;
|
|
166
|
-
const existing = manifest.get(key);
|
|
167
|
-
if (!existing || shouldReplaceManifestEntry(existing, entry)) {
|
|
168
|
-
if (existing && existing.type !== entry.type) {
|
|
169
|
-
process.stderr.write(`⚠️ Duplicate adapter ${key}: ${existing.type} superseded by ${entry.type}\n`);
|
|
170
|
-
}
|
|
171
|
-
manifest.set(key, entry);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
else if ((file.endsWith('.ts') && !file.endsWith('.d.ts') && !file.endsWith('.test.ts') && file !== 'index.ts') ||
|
|
113
|
+
if ((file.endsWith('.ts') && !file.endsWith('.d.ts') && !file.endsWith('.test.ts') && file !== 'index.ts') ||
|
|
176
114
|
(file.endsWith('.js') && !file.endsWith('.d.js') && !file.endsWith('.test.js') && file !== 'index.js')) {
|
|
115
|
+
const filePath = path.join(siteDir, file);
|
|
177
116
|
const entries = await loadTsManifestEntries(filePath, site);
|
|
178
117
|
for (const entry of entries) {
|
|
179
118
|
const key = `${entry.site}/${entry.name}`;
|
|
180
|
-
|
|
181
|
-
if (!existing || shouldReplaceManifestEntry(existing, entry)) {
|
|
182
|
-
if (existing && existing.type !== entry.type) {
|
|
183
|
-
process.stderr.write(`⚠️ Duplicate adapter ${key}: ${existing.type} superseded by ${entry.type}\n`);
|
|
184
|
-
}
|
|
185
|
-
manifest.set(key, entry);
|
|
186
|
-
}
|
|
119
|
+
manifest.set(key, entry);
|
|
187
120
|
}
|
|
188
121
|
}
|
|
189
122
|
}
|
|
@@ -195,9 +128,7 @@ async function main() {
|
|
|
195
128
|
const manifest = await buildManifest();
|
|
196
129
|
fs.mkdirSync(path.dirname(OUTPUT), { recursive: true });
|
|
197
130
|
fs.writeFileSync(OUTPUT, JSON.stringify(manifest, null, 2));
|
|
198
|
-
|
|
199
|
-
const tsCount = manifest.filter(e => e.type === 'ts').length;
|
|
200
|
-
console.log(`✅ Manifest compiled: ${manifest.length} entries (${yamlCount} YAML, ${tsCount} TS) → ${OUTPUT}`);
|
|
131
|
+
console.log(`✅ Manifest compiled: ${manifest.length} entries → ${OUTPUT}`);
|
|
201
132
|
// Restore executable permissions on bin entries.
|
|
202
133
|
// tsc does not preserve the +x bit, so after a clean rebuild the CLI
|
|
203
134
|
// entry-point loses its executable permission, causing "Permission denied".
|
|
@@ -3,7 +3,7 @@ import * as fs from 'node:fs';
|
|
|
3
3
|
import * as os from 'node:os';
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import { cli, getRegistry, Strategy } from './registry.js';
|
|
6
|
-
import { loadTsManifestEntries
|
|
6
|
+
import { loadTsManifestEntries } from './build-manifest.js';
|
|
7
7
|
describe('manifest helper rules', () => {
|
|
8
8
|
const tempDirs = [];
|
|
9
9
|
afterEach(() => {
|
|
@@ -11,44 +11,6 @@ describe('manifest helper rules', () => {
|
|
|
11
11
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
it('prefers TS adapters over duplicate YAML adapters', () => {
|
|
15
|
-
expect(shouldReplaceManifestEntry({
|
|
16
|
-
site: 'demo',
|
|
17
|
-
name: 'search',
|
|
18
|
-
description: 'yaml',
|
|
19
|
-
strategy: 'public',
|
|
20
|
-
browser: false,
|
|
21
|
-
args: [],
|
|
22
|
-
type: 'yaml',
|
|
23
|
-
}, {
|
|
24
|
-
site: 'demo',
|
|
25
|
-
name: 'search',
|
|
26
|
-
description: 'ts',
|
|
27
|
-
strategy: 'public',
|
|
28
|
-
browser: false,
|
|
29
|
-
args: [],
|
|
30
|
-
type: 'ts',
|
|
31
|
-
modulePath: 'demo/search.js',
|
|
32
|
-
})).toBe(true);
|
|
33
|
-
expect(shouldReplaceManifestEntry({
|
|
34
|
-
site: 'demo',
|
|
35
|
-
name: 'search',
|
|
36
|
-
description: 'ts',
|
|
37
|
-
strategy: 'public',
|
|
38
|
-
browser: false,
|
|
39
|
-
args: [],
|
|
40
|
-
type: 'ts',
|
|
41
|
-
modulePath: 'demo/search.js',
|
|
42
|
-
}, {
|
|
43
|
-
site: 'demo',
|
|
44
|
-
name: 'search',
|
|
45
|
-
description: 'yaml',
|
|
46
|
-
strategy: 'public',
|
|
47
|
-
browser: false,
|
|
48
|
-
args: [],
|
|
49
|
-
type: 'yaml',
|
|
50
|
-
})).toBe(false);
|
|
51
|
-
});
|
|
52
14
|
it('skips TS files that do not register a cli', () => {
|
|
53
15
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-manifest-'));
|
|
54
16
|
tempDirs.push(dir);
|
package/dist/src/cascade.js
CHANGED
|
@@ -72,13 +72,14 @@ export async function probeEndpoint(page, url, strategy, _opts = {}) {
|
|
|
72
72
|
try {
|
|
73
73
|
const opts = PROBE_OPTIONS[strategy];
|
|
74
74
|
if (opts) {
|
|
75
|
-
const resp = await page.evaluate(buildFetchProbeJs(url, opts));
|
|
75
|
+
const resp = (await page.evaluate(buildFetchProbeJs(url, opts)));
|
|
76
76
|
result.statusCode = resp?.status;
|
|
77
|
-
result.success = resp?.ok && resp?.hasData;
|
|
77
|
+
result.success = !!(resp?.ok && resp?.hasData);
|
|
78
78
|
result.hasData = resp?.hasData;
|
|
79
79
|
result.responsePreview = resp?.preview;
|
|
80
80
|
}
|
|
81
81
|
else {
|
|
82
|
+
// INTERCEPT / UI require site-specific implementation.
|
|
82
83
|
result.error = `Strategy ${strategy} requires site-specific implementation`;
|
|
83
84
|
}
|
|
84
85
|
}
|
package/dist/src/cli.d.ts
CHANGED
|
@@ -8,16 +8,16 @@ import { Command } from 'commander';
|
|
|
8
8
|
import { findPackageRoot } from './package-paths.js';
|
|
9
9
|
export declare function createProgram(BUILTIN_CLIS: string, USER_CLIS: string): Command;
|
|
10
10
|
export declare function runCli(BUILTIN_CLIS: string, USER_CLIS: string): void;
|
|
11
|
-
export interface
|
|
11
|
+
export interface BrowserVerifyInvocation {
|
|
12
12
|
binary: string;
|
|
13
13
|
args: string[];
|
|
14
14
|
cwd: string;
|
|
15
15
|
shell?: boolean;
|
|
16
16
|
}
|
|
17
17
|
export { findPackageRoot };
|
|
18
|
-
export declare function
|
|
18
|
+
export declare function resolveBrowserVerifyInvocation(opts?: {
|
|
19
19
|
projectRoot?: string;
|
|
20
20
|
platform?: NodeJS.Platform;
|
|
21
21
|
fileExists?: (path: string) => boolean;
|
|
22
22
|
readFile?: (path: string) => string;
|
|
23
|
-
}):
|
|
23
|
+
}): BrowserVerifyInvocation;
|