@jackwener/opencli 1.6.9 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -59
- package/README.zh-CN.md +134 -78
- package/dist/clis/_shared/common.d.ts +3 -0
- package/dist/clis/_shared/common.js +22 -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/detail.d.ts +1 -0
- package/dist/clis/jianyu/detail.js +20 -0
- package/dist/clis/jianyu/search.d.ts +41 -4
- package/dist/clis/jianyu/search.js +458 -96
- package/dist/clis/jianyu/search.test.js +105 -0
- package/dist/clis/jianyu/shared/china-bid-search.d.ts +12 -0
- package/dist/clis/jianyu/shared/china-bid-search.js +165 -0
- package/dist/clis/jianyu/shared/procurement-contract.d.ts +68 -0
- package/dist/clis/jianyu/shared/procurement-contract.js +324 -0
- package/dist/clis/jianyu/shared/procurement-contract.test.d.ts +1 -0
- package/dist/clis/jianyu/shared/procurement-contract.test.js +72 -0
- package/dist/clis/jianyu/shared/procurement-detail.d.ts +6 -0
- package/dist/clis/jianyu/shared/procurement-detail.js +92 -0
- package/dist/clis/jianyu/shared/procurement-detail.test.d.ts +1 -0
- package/dist/clis/jianyu/shared/procurement-detail.test.js +72 -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/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/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 +161 -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/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/hot.d.ts +1 -0
- package/dist/clis/zhihu/hot.js +43 -0
- package/dist/clis/zhihu/search.d.ts +1 -0
- package/dist/clis/zhihu/search.js +52 -0
- package/dist/src/browser/bridge.js +1 -1
- package/dist/src/browser/daemon-client.d.ts +16 -4
- package/dist/src/browser/daemon-client.js +33 -15
- package/dist/src/browser/daemon-client.test.js +0 -3
- 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/page.d.ts +9 -8
- package/dist/src/browser/page.js +33 -31
- package/dist/src/browser.test.js +25 -6
- 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 +71 -71
- 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 -1
- package/dist/src/clis/binance/commands.test.js +10 -6
- 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/commands/daemon.d.ts +2 -6
- package/dist/src/commands/daemon.js +2 -58
- package/dist/src/commands/daemon.test.js +24 -120
- 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/constants.d.ts +0 -2
- package/dist/src/constants.js +0 -2
- package/dist/src/daemon.d.ts +1 -1
- package/dist/src/daemon.js +2 -15
- package/dist/src/diagnostic.test.js +2 -2
- package/dist/src/discovery.d.ts +3 -3
- package/dist/src/discovery.js +34 -97
- package/dist/src/download/index.d.ts +1 -1
- package/dist/src/engine.test.js +4 -19
- package/dist/src/execution.js +5 -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 +9 -1
- package/dist/src/generate.js +2 -2
- 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 +1 -1
- package/dist/src/plugin.js +4 -6
- package/dist/src/plugin.test.js +31 -31
- 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 +4 -3
- 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/daemon.test.js +0 -65
- package/dist/src/idle-manager.d.ts +0 -19
- package/dist/src/idle-manager.js +0 -54
- package/dist/src/yaml-schema.d.ts +0 -29
- package/dist/src/yaml-schema.js +0 -22
- /package/dist/{src/daemon.test.d.ts → clis/bilibili/hot.d.ts} +0 -0
|
@@ -6,23 +6,16 @@ const { fetchDaemonStatusMock, requestDaemonShutdownMock, } = vi.hoisted(() => (
|
|
|
6
6
|
vi.mock('chalk', () => ({
|
|
7
7
|
default: {
|
|
8
8
|
green: (s) => s,
|
|
9
|
-
yellow: (s) => s,
|
|
10
9
|
red: (s) => s,
|
|
11
10
|
dim: (s) => s,
|
|
12
11
|
},
|
|
13
12
|
}));
|
|
14
|
-
const mockConnect = vi.fn();
|
|
15
|
-
vi.mock('../browser/bridge.js', () => ({
|
|
16
|
-
BrowserBridge: class {
|
|
17
|
-
connect = mockConnect;
|
|
18
|
-
},
|
|
19
|
-
}));
|
|
20
13
|
vi.mock('../browser/daemon-client.js', () => ({
|
|
21
14
|
fetchDaemonStatus: fetchDaemonStatusMock,
|
|
22
15
|
requestDaemonShutdown: requestDaemonShutdownMock,
|
|
23
16
|
}));
|
|
24
|
-
import {
|
|
25
|
-
describe('
|
|
17
|
+
import { daemonStop } from './daemon.js';
|
|
18
|
+
describe('daemonStop', () => {
|
|
26
19
|
let logSpy;
|
|
27
20
|
let errorSpy;
|
|
28
21
|
beforeEach(() => {
|
|
@@ -33,128 +26,39 @@ describe('daemon commands', () => {
|
|
|
33
26
|
});
|
|
34
27
|
afterEach(() => {
|
|
35
28
|
vi.restoreAllMocks();
|
|
36
|
-
mockConnect.mockReset();
|
|
37
29
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('not running'));
|
|
43
|
-
});
|
|
44
|
-
it('shows "not running" when daemon returns non-ok response', async () => {
|
|
45
|
-
fetchDaemonStatusMock.mockResolvedValue(null);
|
|
46
|
-
await daemonStatus();
|
|
47
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('not running'));
|
|
48
|
-
});
|
|
49
|
-
it('shows daemon info when running', async () => {
|
|
50
|
-
const status = {
|
|
51
|
-
ok: true,
|
|
52
|
-
pid: 12345,
|
|
53
|
-
uptime: 3661,
|
|
54
|
-
extensionConnected: true,
|
|
55
|
-
pending: 0,
|
|
56
|
-
lastCliRequestTime: Date.now() - 30_000,
|
|
57
|
-
memoryMB: 64,
|
|
58
|
-
port: 19825,
|
|
59
|
-
};
|
|
60
|
-
fetchDaemonStatusMock.mockResolvedValue(status);
|
|
61
|
-
await daemonStatus();
|
|
62
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('running'));
|
|
63
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('PID 12345'));
|
|
64
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('1h 1m'));
|
|
65
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('connected'));
|
|
66
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('64 MB'));
|
|
67
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('19825'));
|
|
68
|
-
});
|
|
69
|
-
it('shows disconnected when extension is not connected', async () => {
|
|
70
|
-
const status = {
|
|
71
|
-
ok: true,
|
|
72
|
-
pid: 99,
|
|
73
|
-
uptime: 120,
|
|
74
|
-
extensionConnected: false,
|
|
75
|
-
pending: 0,
|
|
76
|
-
lastCliRequestTime: Date.now() - 5000,
|
|
77
|
-
memoryMB: 32,
|
|
78
|
-
port: 19825,
|
|
79
|
-
};
|
|
80
|
-
fetchDaemonStatusMock.mockResolvedValue(status);
|
|
81
|
-
await daemonStatus();
|
|
82
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('disconnected'));
|
|
83
|
-
});
|
|
30
|
+
it('reports "not running" when daemon is unreachable', async () => {
|
|
31
|
+
fetchDaemonStatusMock.mockResolvedValue(null);
|
|
32
|
+
await daemonStop();
|
|
33
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('not running'));
|
|
84
34
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
pid: 12345,
|
|
95
|
-
uptime: 100,
|
|
96
|
-
extensionConnected: true,
|
|
97
|
-
pending: 0,
|
|
98
|
-
lastCliRequestTime: Date.now(),
|
|
99
|
-
memoryMB: 50,
|
|
100
|
-
port: 19825,
|
|
101
|
-
});
|
|
102
|
-
requestDaemonShutdownMock.mockResolvedValue(true);
|
|
103
|
-
await daemonStop();
|
|
104
|
-
expect(requestDaemonShutdownMock).toHaveBeenCalledTimes(1);
|
|
105
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Daemon stopped'));
|
|
106
|
-
});
|
|
107
|
-
it('reports failure when shutdown request fails', async () => {
|
|
108
|
-
fetchDaemonStatusMock.mockResolvedValue({
|
|
109
|
-
ok: true,
|
|
110
|
-
pid: 12345,
|
|
111
|
-
uptime: 100,
|
|
112
|
-
extensionConnected: true,
|
|
113
|
-
pending: 0,
|
|
114
|
-
lastCliRequestTime: Date.now(),
|
|
115
|
-
memoryMB: 50,
|
|
116
|
-
port: 19825,
|
|
117
|
-
});
|
|
118
|
-
requestDaemonShutdownMock.mockResolvedValue(false);
|
|
119
|
-
await daemonStop();
|
|
120
|
-
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to stop daemon'));
|
|
35
|
+
it('sends shutdown and reports success', async () => {
|
|
36
|
+
fetchDaemonStatusMock.mockResolvedValue({
|
|
37
|
+
ok: true,
|
|
38
|
+
pid: 12345,
|
|
39
|
+
uptime: 100,
|
|
40
|
+
extensionConnected: true,
|
|
41
|
+
pending: 0,
|
|
42
|
+
memoryMB: 50,
|
|
43
|
+
port: 19825,
|
|
121
44
|
});
|
|
45
|
+
requestDaemonShutdownMock.mockResolvedValue(true);
|
|
46
|
+
await daemonStop();
|
|
47
|
+
expect(requestDaemonShutdownMock).toHaveBeenCalledTimes(1);
|
|
48
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Daemon stopped'));
|
|
122
49
|
});
|
|
123
|
-
|
|
124
|
-
|
|
50
|
+
it('reports failure when shutdown request fails', async () => {
|
|
51
|
+
fetchDaemonStatusMock.mockResolvedValue({
|
|
125
52
|
ok: true,
|
|
126
53
|
pid: 12345,
|
|
127
54
|
uptime: 100,
|
|
128
55
|
extensionConnected: true,
|
|
129
56
|
pending: 0,
|
|
130
|
-
lastCliRequestTime: Date.now(),
|
|
131
57
|
memoryMB: 50,
|
|
132
58
|
port: 19825,
|
|
133
|
-
};
|
|
134
|
-
it('starts daemon directly when not running', async () => {
|
|
135
|
-
fetchDaemonStatusMock.mockResolvedValue(null);
|
|
136
|
-
mockConnect.mockResolvedValue(undefined);
|
|
137
|
-
await daemonRestart();
|
|
138
|
-
expect(mockConnect).toHaveBeenCalledWith({ timeout: 10 });
|
|
139
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Daemon restarted'));
|
|
140
|
-
});
|
|
141
|
-
it('stops then starts when daemon is running', async () => {
|
|
142
|
-
fetchDaemonStatusMock
|
|
143
|
-
.mockResolvedValueOnce(statusData)
|
|
144
|
-
.mockResolvedValueOnce(null);
|
|
145
|
-
requestDaemonShutdownMock.mockResolvedValue(true);
|
|
146
|
-
mockConnect.mockResolvedValue(undefined);
|
|
147
|
-
await daemonRestart();
|
|
148
|
-
expect(requestDaemonShutdownMock).toHaveBeenCalledTimes(1);
|
|
149
|
-
expect(mockConnect).toHaveBeenCalledWith({ timeout: 10 });
|
|
150
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Daemon restarted'));
|
|
151
|
-
});
|
|
152
|
-
it('aborts when shutdown fails', async () => {
|
|
153
|
-
fetchDaemonStatusMock.mockResolvedValue(statusData);
|
|
154
|
-
requestDaemonShutdownMock.mockResolvedValue(false);
|
|
155
|
-
await daemonRestart();
|
|
156
|
-
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to stop daemon'));
|
|
157
|
-
expect(mockConnect).not.toHaveBeenCalled();
|
|
158
59
|
});
|
|
60
|
+
requestDaemonShutdownMock.mockResolvedValue(false);
|
|
61
|
+
await daemonStop();
|
|
62
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to stop daemon'));
|
|
159
63
|
});
|
|
160
64
|
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight manifest-based completion for the fast path.
|
|
3
|
+
*
|
|
4
|
+
* This module MUST NOT import registry, discovery, or any heavy module.
|
|
5
|
+
* It only reads pre-compiled cli-manifest.json files synchronously.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Returns true only if ALL manifest files exist and are readable.
|
|
9
|
+
* If any source lacks a manifest (e.g. user adapters without a compiled manifest),
|
|
10
|
+
* the fast path must not be used — otherwise those adapters would silently
|
|
11
|
+
* disappear from completion results.
|
|
12
|
+
*/
|
|
13
|
+
export declare function hasAllManifests(manifestPaths: string[]): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Lightweight completion that reads directly from manifest JSON files,
|
|
16
|
+
* bypassing full CLI discovery and adapter loading.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getCompletionsFromManifest(words: string[], cursor: number, manifestPaths: string[]): string[];
|
|
19
|
+
export declare function bashCompletionScript(): string;
|
|
20
|
+
export declare function zshCompletionScript(): string;
|
|
21
|
+
export declare function fishCompletionScript(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Print completion script for the given shell. Returns true if handled, false if unknown shell.
|
|
24
|
+
*/
|
|
25
|
+
export declare function printCompletionScriptFast(shell: string): boolean;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight manifest-based completion for the fast path.
|
|
3
|
+
*
|
|
4
|
+
* This module MUST NOT import registry, discovery, or any heavy module.
|
|
5
|
+
* It only reads pre-compiled cli-manifest.json files synchronously.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
const BUILTIN_COMMANDS = [
|
|
9
|
+
'list',
|
|
10
|
+
'validate',
|
|
11
|
+
'verify',
|
|
12
|
+
'explore',
|
|
13
|
+
'probe',
|
|
14
|
+
'synthesize',
|
|
15
|
+
'generate',
|
|
16
|
+
'cascade',
|
|
17
|
+
'doctor',
|
|
18
|
+
'plugin',
|
|
19
|
+
'install',
|
|
20
|
+
'register',
|
|
21
|
+
'completion',
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Returns true only if ALL manifest files exist and are readable.
|
|
25
|
+
* If any source lacks a manifest (e.g. user adapters without a compiled manifest),
|
|
26
|
+
* the fast path must not be used — otherwise those adapters would silently
|
|
27
|
+
* disappear from completion results.
|
|
28
|
+
*/
|
|
29
|
+
export function hasAllManifests(manifestPaths) {
|
|
30
|
+
for (const p of manifestPaths) {
|
|
31
|
+
try {
|
|
32
|
+
fs.accessSync(p);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return manifestPaths.length > 0;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Lightweight completion that reads directly from manifest JSON files,
|
|
42
|
+
* bypassing full CLI discovery and adapter loading.
|
|
43
|
+
*/
|
|
44
|
+
export function getCompletionsFromManifest(words, cursor, manifestPaths) {
|
|
45
|
+
const entries = loadManifestEntries(manifestPaths);
|
|
46
|
+
if (entries === null) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
if (cursor <= 1) {
|
|
50
|
+
const sites = new Set();
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
sites.add(entry.site);
|
|
53
|
+
}
|
|
54
|
+
return [...BUILTIN_COMMANDS, ...sites].sort();
|
|
55
|
+
}
|
|
56
|
+
const site = words[0];
|
|
57
|
+
if (BUILTIN_COMMANDS.includes(site)) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (cursor === 2) {
|
|
61
|
+
const subcommands = [];
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
if (entry.site === site) {
|
|
64
|
+
subcommands.push(entry.name);
|
|
65
|
+
if (entry.aliases?.length)
|
|
66
|
+
subcommands.push(...entry.aliases);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return [...new Set(subcommands)].sort();
|
|
70
|
+
}
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
// ── Shell script generators (pure strings, no registry dependency) ───────
|
|
74
|
+
export function bashCompletionScript() {
|
|
75
|
+
return `# Bash completion for opencli
|
|
76
|
+
# Add to ~/.bashrc: eval "$(opencli completion bash)"
|
|
77
|
+
_opencli_completions() {
|
|
78
|
+
local cur words cword
|
|
79
|
+
_get_comp_words_by_ref -n : cur words cword
|
|
80
|
+
|
|
81
|
+
local completions
|
|
82
|
+
completions=$(opencli --get-completions --cursor "$cword" "\${words[@]:1}" 2>/dev/null)
|
|
83
|
+
|
|
84
|
+
COMPREPLY=( $(compgen -W "$completions" -- "$cur") )
|
|
85
|
+
__ltrim_colon_completions "$cur"
|
|
86
|
+
}
|
|
87
|
+
complete -F _opencli_completions opencli
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
export function zshCompletionScript() {
|
|
91
|
+
return `# Zsh completion for opencli
|
|
92
|
+
# Add to ~/.zshrc: eval "$(opencli completion zsh)"
|
|
93
|
+
_opencli() {
|
|
94
|
+
local -a completions
|
|
95
|
+
local cword=$((CURRENT - 1))
|
|
96
|
+
completions=(\${(f)"$(opencli --get-completions --cursor "$cword" "\${words[@]:1}" 2>/dev/null)"})
|
|
97
|
+
compadd -a completions
|
|
98
|
+
}
|
|
99
|
+
compdef _opencli opencli
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
export function fishCompletionScript() {
|
|
103
|
+
return `# Fish completion for opencli
|
|
104
|
+
# Add to ~/.config/fish/config.fish: opencli completion fish | source
|
|
105
|
+
complete -c opencli -f -a '(
|
|
106
|
+
set -l tokens (commandline -cop)
|
|
107
|
+
set -l cursor (count (commandline -cop))
|
|
108
|
+
opencli --get-completions --cursor $cursor $tokens[2..] 2>/dev/null
|
|
109
|
+
)'
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
const SHELL_SCRIPTS = {
|
|
113
|
+
bash: bashCompletionScript,
|
|
114
|
+
zsh: zshCompletionScript,
|
|
115
|
+
fish: fishCompletionScript,
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Print completion script for the given shell. Returns true if handled, false if unknown shell.
|
|
119
|
+
*/
|
|
120
|
+
export function printCompletionScriptFast(shell) {
|
|
121
|
+
const gen = SHELL_SCRIPTS[shell];
|
|
122
|
+
if (!gen)
|
|
123
|
+
return false;
|
|
124
|
+
process.stdout.write(gen());
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
function loadManifestEntries(manifestPaths) {
|
|
128
|
+
const entries = [];
|
|
129
|
+
let found = false;
|
|
130
|
+
for (const manifestPath of manifestPaths) {
|
|
131
|
+
try {
|
|
132
|
+
const raw = fs.readFileSync(manifestPath, 'utf-8');
|
|
133
|
+
const manifest = JSON.parse(raw);
|
|
134
|
+
entries.push(...manifest);
|
|
135
|
+
found = true;
|
|
136
|
+
}
|
|
137
|
+
catch { /* skip missing/unreadable */ }
|
|
138
|
+
}
|
|
139
|
+
return found ? entries : null;
|
|
140
|
+
}
|
package/dist/src/completion.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Return completion candidates given the current command-line words and cursor index.
|
|
10
|
+
* Requires full CLI discovery to have been run (uses getRegistry()).
|
|
10
11
|
*
|
|
11
12
|
* @param words - The argv after 'opencli' (words[0] is the first arg, e.g. site name)
|
|
12
13
|
* @param cursor - 1-based position of the word being completed (1 = first arg)
|
package/dist/src/completion.js
CHANGED
|
@@ -28,6 +28,7 @@ const BUILTIN_COMMANDS = [
|
|
|
28
28
|
];
|
|
29
29
|
/**
|
|
30
30
|
* Return completion candidates given the current command-line words and cursor index.
|
|
31
|
+
* Requires full CLI discovery to have been run (uses getRegistry()).
|
|
31
32
|
*
|
|
32
33
|
* @param words - The argv after 'opencli' (words[0] is the first arg, e.g. site name)
|
|
33
34
|
* @param cursor - 1-based position of the word being completed (1 = first arg)
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/** Default daemon port for HTTP/WebSocket communication with browser extension */
|
|
5
5
|
export declare const DEFAULT_DAEMON_PORT = 19825;
|
|
6
|
-
/** Default idle timeout before daemon auto-exits (ms). Override via OPENCLI_DAEMON_TIMEOUT env var. */
|
|
7
|
-
export declare const DEFAULT_DAEMON_IDLE_TIMEOUT: number;
|
|
8
6
|
/** URL query params that are volatile/ephemeral and should be stripped from patterns */
|
|
9
7
|
export declare const VOLATILE_PARAMS: Set<string>;
|
|
10
8
|
/** Search-related query parameter names */
|
package/dist/src/constants.js
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/** Default daemon port for HTTP/WebSocket communication with browser extension */
|
|
5
5
|
export const DEFAULT_DAEMON_PORT = 19825;
|
|
6
|
-
/** Default idle timeout before daemon auto-exits (ms). Override via OPENCLI_DAEMON_TIMEOUT env var. */
|
|
7
|
-
export const DEFAULT_DAEMON_IDLE_TIMEOUT = 4 * 60 * 60 * 1000; // 4 hours
|
|
8
6
|
/** URL query params that are volatile/ephemeral and should be stripped from patterns */
|
|
9
7
|
export const VOLATILE_PARAMS = new Set([
|
|
10
8
|
'w_rid', 'wts', '_', 'callback', 'timestamp', 't', 'nonce', 'sign',
|
package/dist/src/daemon.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Lifecycle:
|
|
17
17
|
* - Auto-spawned by opencli on first browser command
|
|
18
|
-
* -
|
|
18
|
+
* - Persistent — stays alive until explicit shutdown, SIGTERM, or uninstall
|
|
19
19
|
* - Listens on localhost:19825
|
|
20
20
|
*/
|
|
21
21
|
export {};
|
package/dist/src/daemon.js
CHANGED
|
@@ -15,16 +15,14 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Lifecycle:
|
|
17
17
|
* - Auto-spawned by opencli on first browser command
|
|
18
|
-
* -
|
|
18
|
+
* - Persistent — stays alive until explicit shutdown, SIGTERM, or uninstall
|
|
19
19
|
* - Listens on localhost:19825
|
|
20
20
|
*/
|
|
21
21
|
import { createServer } from 'node:http';
|
|
22
22
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
23
|
-
import { DEFAULT_DAEMON_PORT
|
|
23
|
+
import { DEFAULT_DAEMON_PORT } from './constants.js';
|
|
24
24
|
import { EXIT_CODES } from './errors.js';
|
|
25
|
-
import { IdleManager } from './idle-manager.js';
|
|
26
25
|
const PORT = parseInt(process.env.OPENCLI_DAEMON_PORT ?? String(DEFAULT_DAEMON_PORT), 10);
|
|
27
|
-
const IDLE_TIMEOUT = Number(process.env.OPENCLI_DAEMON_TIMEOUT ?? DEFAULT_DAEMON_IDLE_TIMEOUT);
|
|
28
26
|
// ─── State ───────────────────────────────────────────────────────────
|
|
29
27
|
let extensionWs = null;
|
|
30
28
|
let extensionVersion = null;
|
|
@@ -36,11 +34,6 @@ function pushLog(entry) {
|
|
|
36
34
|
if (logBuffer.length > LOG_BUFFER_SIZE)
|
|
37
35
|
logBuffer.shift();
|
|
38
36
|
}
|
|
39
|
-
// ─── Idle auto-exit ──────────────────────────────────────────────────
|
|
40
|
-
const idleManager = new IdleManager(IDLE_TIMEOUT, () => {
|
|
41
|
-
console.error('[daemon] Idle timeout (no CLI requests + no Extension), shutting down');
|
|
42
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
43
|
-
});
|
|
44
37
|
// ─── HTTP Server ─────────────────────────────────────────────────────
|
|
45
38
|
const MAX_BODY = 1024 * 1024; // 1 MB — commands are tiny; this prevents OOM
|
|
46
39
|
function readBody(req) {
|
|
@@ -118,7 +111,6 @@ async function handleRequest(req, res) {
|
|
|
118
111
|
extensionConnected: extensionWs?.readyState === WebSocket.OPEN,
|
|
119
112
|
extensionVersion,
|
|
120
113
|
pending: pending.size,
|
|
121
|
-
lastCliRequestTime: idleManager.lastCliRequestTime,
|
|
122
114
|
memoryMB: Math.round(mem.rss / 1024 / 1024 * 10) / 10,
|
|
123
115
|
port: PORT,
|
|
124
116
|
});
|
|
@@ -144,7 +136,6 @@ async function handleRequest(req, res) {
|
|
|
144
136
|
return;
|
|
145
137
|
}
|
|
146
138
|
if (req.method === 'POST' && url === '/command') {
|
|
147
|
-
idleManager.onCliRequest();
|
|
148
139
|
try {
|
|
149
140
|
const body = JSON.parse(await readBody(req));
|
|
150
141
|
if (!body.id) {
|
|
@@ -196,7 +187,6 @@ wss.on('connection', (ws) => {
|
|
|
196
187
|
console.error('[daemon] Extension connected');
|
|
197
188
|
extensionWs = ws;
|
|
198
189
|
extensionVersion = null; // cleared until hello message arrives
|
|
199
|
-
idleManager.setExtensionConnected(true);
|
|
200
190
|
// ── Heartbeat: ping every 15s, close if 2 pongs missed ──
|
|
201
191
|
let missedPongs = 0;
|
|
202
192
|
const heartbeatInterval = setInterval(() => {
|
|
@@ -249,7 +239,6 @@ wss.on('connection', (ws) => {
|
|
|
249
239
|
if (extensionWs === ws) {
|
|
250
240
|
extensionWs = null;
|
|
251
241
|
extensionVersion = null;
|
|
252
|
-
idleManager.setExtensionConnected(false);
|
|
253
242
|
// Reject all pending requests since the extension is gone
|
|
254
243
|
for (const [id, p] of pending) {
|
|
255
244
|
clearTimeout(p.timer);
|
|
@@ -263,7 +252,6 @@ wss.on('connection', (ws) => {
|
|
|
263
252
|
if (extensionWs === ws) {
|
|
264
253
|
extensionWs = null;
|
|
265
254
|
extensionVersion = null;
|
|
266
|
-
idleManager.setExtensionConnected(false);
|
|
267
255
|
// Reject pending requests in case 'close' does not follow this 'error'
|
|
268
256
|
for (const [, p] of pending) {
|
|
269
257
|
clearTimeout(p.timer);
|
|
@@ -276,7 +264,6 @@ wss.on('connection', (ws) => {
|
|
|
276
264
|
// ─── Start ───────────────────────────────────────────────────────────
|
|
277
265
|
httpServer.listen(PORT, '127.0.0.1', () => {
|
|
278
266
|
console.error(`[daemon] Listening on http://127.0.0.1:${PORT}`);
|
|
279
|
-
idleManager.onCliRequest();
|
|
280
267
|
});
|
|
281
268
|
httpServer.on('error', (err) => {
|
|
282
269
|
if (err.code === 'EADDRINUSE') {
|
|
@@ -83,8 +83,8 @@ describe('redactText', () => {
|
|
|
83
83
|
});
|
|
84
84
|
describe('resolveAdapterSourcePath', () => {
|
|
85
85
|
it('returns source when it is a real file path (not manifest:)', () => {
|
|
86
|
-
const cmd = makeCmd({ source: '/home/user/.opencli/clis/arxiv/search.
|
|
87
|
-
expect(resolveAdapterSourcePath(cmd)).toBe('/home/user/.opencli/clis/arxiv/search.
|
|
86
|
+
const cmd = makeCmd({ source: '/home/user/.opencli/clis/arxiv/search.ts' });
|
|
87
|
+
expect(resolveAdapterSourcePath(cmd)).toBe('/home/user/.opencli/clis/arxiv/search.ts');
|
|
88
88
|
});
|
|
89
89
|
it('skips manifest: pseudo-paths and falls back to _modulePath', () => {
|
|
90
90
|
const cmd = makeCmd({ source: 'manifest:arxiv/search', _modulePath: '/pkg/dist/clis/arxiv/search.js' });
|
package/dist/src/discovery.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI discovery: finds
|
|
2
|
+
* CLI discovery: finds TS CLI definitions and registers them.
|
|
3
3
|
*
|
|
4
4
|
* Supports two modes:
|
|
5
5
|
* 1. FAST PATH (manifest): If a pre-compiled cli-manifest.json exists,
|
|
6
|
-
* registers
|
|
7
|
-
*
|
|
6
|
+
* registers commands instantly. TS modules are loaded lazily only
|
|
7
|
+
* when their command is executed.
|
|
8
8
|
* 2. FALLBACK (filesystem scan): Traditional runtime discovery for development.
|
|
9
9
|
*/
|
|
10
10
|
/** User runtime directory: ~/.opencli */
|