@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.
Files changed (572) hide show
  1. package/README.md +117 -59
  2. package/README.zh-CN.md +123 -79
  3. package/dist/clis/_shared/common.d.ts +3 -0
  4. package/dist/clis/_shared/common.js +22 -0
  5. package/dist/clis/bilibili/hot.d.ts +1 -0
  6. package/dist/clis/bilibili/hot.js +35 -0
  7. package/dist/clis/bluesky/feeds.d.ts +1 -0
  8. package/dist/clis/bluesky/feeds.js +27 -0
  9. package/dist/clis/bluesky/followers.d.ts +1 -0
  10. package/dist/clis/bluesky/followers.js +27 -0
  11. package/dist/clis/bluesky/following.d.ts +1 -0
  12. package/dist/clis/bluesky/following.js +27 -0
  13. package/dist/clis/bluesky/profile.d.ts +1 -0
  14. package/dist/clis/bluesky/profile.js +29 -0
  15. package/dist/clis/bluesky/search.d.ts +1 -0
  16. package/dist/clis/bluesky/search.js +28 -0
  17. package/dist/clis/bluesky/starter-packs.d.ts +1 -0
  18. package/dist/clis/bluesky/starter-packs.js +28 -0
  19. package/dist/clis/bluesky/thread.d.ts +1 -0
  20. package/dist/clis/bluesky/thread.js +30 -0
  21. package/dist/clis/bluesky/trending.d.ts +1 -0
  22. package/dist/clis/bluesky/trending.js +19 -0
  23. package/dist/clis/bluesky/user.d.ts +1 -0
  24. package/dist/clis/bluesky/user.js +33 -0
  25. package/dist/clis/cnki/search.d.ts +1 -0
  26. package/dist/clis/cnki/search.js +60 -0
  27. package/dist/clis/cnki/search.test.d.ts +1 -0
  28. package/dist/clis/cnki/search.test.js +18 -0
  29. package/dist/clis/devto/tag.d.ts +1 -0
  30. package/dist/clis/devto/tag.js +32 -0
  31. package/dist/clis/devto/top.d.ts +1 -0
  32. package/dist/clis/devto/top.js +26 -0
  33. package/dist/clis/devto/user.d.ts +1 -0
  34. package/dist/clis/devto/user.js +31 -0
  35. package/dist/clis/dictionary/examples.d.ts +1 -0
  36. package/dist/clis/dictionary/examples.js +27 -0
  37. package/dist/clis/dictionary/search.d.ts +1 -0
  38. package/dist/clis/dictionary/search.js +29 -0
  39. package/dist/clis/dictionary/synonyms.d.ts +1 -0
  40. package/dist/clis/dictionary/synonyms.js +27 -0
  41. package/dist/clis/douban/subject.d.ts +1 -0
  42. package/dist/clis/douban/subject.js +118 -0
  43. package/dist/clis/douban/top250.d.ts +1 -0
  44. package/dist/clis/douban/top250.js +67 -0
  45. package/dist/clis/facebook/add-friend.d.ts +1 -0
  46. package/dist/clis/facebook/add-friend.js +43 -0
  47. package/dist/clis/facebook/events.d.ts +1 -0
  48. package/dist/clis/facebook/events.js +40 -0
  49. package/dist/clis/facebook/feed.d.ts +1 -0
  50. package/dist/clis/facebook/feed.js +59 -0
  51. package/dist/clis/facebook/friends.d.ts +1 -0
  52. package/dist/clis/facebook/friends.js +38 -0
  53. package/dist/clis/facebook/groups.d.ts +1 -0
  54. package/dist/clis/facebook/groups.js +46 -0
  55. package/dist/clis/facebook/join-group.d.ts +1 -0
  56. package/dist/clis/facebook/join-group.js +44 -0
  57. package/dist/clis/facebook/memories.d.ts +1 -0
  58. package/dist/clis/facebook/memories.js +35 -0
  59. package/dist/clis/facebook/notifications.d.ts +1 -0
  60. package/dist/clis/facebook/notifications.js +36 -0
  61. package/dist/clis/facebook/profile.d.ts +1 -0
  62. package/dist/clis/facebook/profile.js +37 -0
  63. package/dist/clis/facebook/search.d.ts +1 -0
  64. package/dist/clis/facebook/search.js +38 -0
  65. package/dist/clis/facebook/search.test.d.ts +1 -1
  66. package/dist/clis/facebook/search.test.js +6 -9
  67. package/dist/clis/gitee/index.d.ts +3 -0
  68. package/dist/clis/gitee/index.js +3 -0
  69. package/dist/clis/gitee/search.d.ts +1 -0
  70. package/dist/clis/gitee/search.js +136 -0
  71. package/dist/clis/gitee/trending.d.ts +1 -0
  72. package/dist/clis/gitee/trending.js +567 -0
  73. package/dist/clis/gitee/user.d.ts +1 -0
  74. package/dist/clis/gitee/user.js +199 -0
  75. package/dist/clis/gitee/user.test.d.ts +1 -0
  76. package/dist/clis/gitee/user.test.js +63 -0
  77. package/dist/clis/hackernews/ask.d.ts +1 -0
  78. package/dist/clis/hackernews/ask.js +29 -0
  79. package/dist/clis/hackernews/best.d.ts +1 -0
  80. package/dist/clis/hackernews/best.js +29 -0
  81. package/dist/clis/hackernews/jobs.d.ts +1 -0
  82. package/dist/clis/hackernews/jobs.js +27 -0
  83. package/dist/clis/hackernews/new.d.ts +1 -0
  84. package/dist/clis/hackernews/new.js +29 -0
  85. package/dist/clis/hackernews/search.d.ts +1 -0
  86. package/dist/clis/hackernews/search.js +36 -0
  87. package/dist/clis/hackernews/show.d.ts +1 -0
  88. package/dist/clis/hackernews/show.js +29 -0
  89. package/dist/clis/hackernews/top.d.ts +1 -0
  90. package/dist/clis/hackernews/top.js +29 -0
  91. package/dist/clis/hackernews/user.d.ts +1 -0
  92. package/dist/clis/hackernews/user.js +22 -0
  93. package/dist/clis/hupu/hot.d.ts +1 -0
  94. package/dist/clis/hupu/hot.js +40 -0
  95. package/dist/clis/instagram/comment.d.ts +1 -0
  96. package/dist/clis/instagram/comment.js +47 -0
  97. package/dist/clis/instagram/explore.d.ts +1 -0
  98. package/dist/clis/instagram/explore.js +41 -0
  99. package/dist/clis/instagram/follow.d.ts +1 -0
  100. package/dist/clis/instagram/follow.js +43 -0
  101. package/dist/clis/instagram/followers.d.ts +1 -0
  102. package/dist/clis/instagram/followers.js +45 -0
  103. package/dist/clis/instagram/following.d.ts +1 -0
  104. package/dist/clis/instagram/following.js +45 -0
  105. package/dist/clis/instagram/like.d.ts +1 -0
  106. package/dist/clis/instagram/like.js +45 -0
  107. package/dist/clis/instagram/profile.d.ts +1 -0
  108. package/dist/clis/instagram/profile.js +39 -0
  109. package/dist/clis/instagram/save.d.ts +1 -0
  110. package/dist/clis/instagram/save.js +45 -0
  111. package/dist/clis/instagram/saved.d.ts +1 -0
  112. package/dist/clis/instagram/saved.js +38 -0
  113. package/dist/clis/instagram/search.d.ts +1 -0
  114. package/dist/clis/instagram/search.js +38 -0
  115. package/dist/clis/instagram/unfollow.d.ts +1 -0
  116. package/dist/clis/instagram/unfollow.js +40 -0
  117. package/dist/clis/instagram/unlike.d.ts +1 -0
  118. package/dist/clis/instagram/unlike.js +45 -0
  119. package/dist/clis/instagram/unsave.d.ts +1 -0
  120. package/dist/clis/instagram/unsave.js +45 -0
  121. package/dist/clis/instagram/user.d.ts +1 -0
  122. package/dist/clis/instagram/user.js +48 -0
  123. package/dist/clis/jd/add-cart.d.ts +1 -0
  124. package/dist/clis/jd/add-cart.js +71 -0
  125. package/dist/clis/jd/cart.d.ts +1 -0
  126. package/dist/clis/jd/cart.js +79 -0
  127. package/dist/clis/jd/commands.test.d.ts +5 -0
  128. package/dist/clis/jd/commands.test.js +64 -0
  129. package/dist/clis/jd/detail.d.ts +1 -0
  130. package/dist/clis/jd/detail.js +62 -0
  131. package/dist/clis/jd/reviews.d.ts +1 -0
  132. package/dist/clis/jd/reviews.js +54 -0
  133. package/dist/clis/jd/search.d.ts +1 -0
  134. package/dist/clis/jd/search.js +65 -0
  135. package/dist/clis/jianyu/search.d.ts +14 -0
  136. package/dist/clis/jianyu/search.js +135 -0
  137. package/dist/clis/jianyu/search.test.d.ts +1 -0
  138. package/dist/clis/jianyu/search.test.js +23 -0
  139. package/dist/clis/jike/post.d.ts +1 -0
  140. package/dist/clis/jike/post.js +61 -0
  141. package/dist/clis/jike/topic.d.ts +1 -0
  142. package/dist/clis/jike/topic.js +51 -0
  143. package/dist/clis/jike/user.d.ts +1 -0
  144. package/dist/clis/jike/user.js +50 -0
  145. package/dist/clis/jimeng/generate.d.ts +1 -0
  146. package/dist/clis/jimeng/generate.js +83 -0
  147. package/dist/clis/jimeng/history.d.ts +1 -0
  148. package/dist/clis/jimeng/history.js +47 -0
  149. package/dist/clis/jimeng/new.d.ts +1 -0
  150. package/dist/clis/jimeng/new.js +43 -0
  151. package/dist/clis/jimeng/workspaces.d.ts +1 -0
  152. package/dist/clis/jimeng/workspaces.js +41 -0
  153. package/dist/clis/linux-do/categories.d.ts +1 -0
  154. package/dist/clis/linux-do/categories.js +65 -0
  155. package/dist/clis/linux-do/search.d.ts +1 -0
  156. package/dist/clis/linux-do/search.js +41 -0
  157. package/dist/clis/linux-do/tags.d.ts +1 -0
  158. package/dist/clis/linux-do/tags.js +39 -0
  159. package/dist/clis/linux-do/topic-content.test.js +5 -5
  160. package/dist/clis/linux-do/topic.d.ts +1 -0
  161. package/dist/clis/linux-do/topic.js +56 -0
  162. package/dist/clis/linux-do/user-posts.d.ts +1 -0
  163. package/dist/clis/linux-do/user-posts.js +61 -0
  164. package/dist/clis/linux-do/user-topics.d.ts +1 -0
  165. package/dist/clis/linux-do/user-topics.js +48 -0
  166. package/dist/clis/lobsters/active.d.ts +1 -0
  167. package/dist/clis/lobsters/active.js +26 -0
  168. package/dist/clis/lobsters/hot.d.ts +1 -0
  169. package/dist/clis/lobsters/hot.js +26 -0
  170. package/dist/clis/lobsters/newest.d.ts +1 -0
  171. package/dist/clis/lobsters/newest.js +26 -0
  172. package/dist/clis/lobsters/tag.d.ts +1 -0
  173. package/dist/clis/lobsters/tag.js +32 -0
  174. package/dist/clis/pixiv/detail.d.ts +1 -0
  175. package/dist/clis/pixiv/detail.js +58 -0
  176. package/dist/clis/pixiv/ranking.d.ts +1 -0
  177. package/dist/clis/pixiv/ranking.js +59 -0
  178. package/dist/clis/pixiv/user.d.ts +1 -0
  179. package/dist/clis/pixiv/user.js +52 -0
  180. package/dist/clis/quark/ls.d.ts +1 -0
  181. package/dist/clis/quark/ls.js +63 -0
  182. package/dist/clis/quark/mkdir.d.ts +1 -0
  183. package/dist/clis/quark/mkdir.js +36 -0
  184. package/dist/clis/quark/mv.d.ts +1 -0
  185. package/dist/clis/quark/mv.js +53 -0
  186. package/dist/clis/quark/rename.d.ts +1 -0
  187. package/dist/clis/quark/rename.js +26 -0
  188. package/dist/clis/quark/rm.d.ts +1 -0
  189. package/dist/clis/quark/rm.js +24 -0
  190. package/dist/clis/quark/save.d.ts +1 -0
  191. package/dist/clis/quark/save.js +80 -0
  192. package/dist/clis/quark/share-tree.d.ts +1 -0
  193. package/dist/clis/quark/share-tree.js +45 -0
  194. package/dist/clis/quark/utils.d.ts +50 -0
  195. package/dist/clis/quark/utils.js +146 -0
  196. package/dist/clis/quark/utils.test.d.ts +1 -0
  197. package/dist/clis/quark/utils.test.js +58 -0
  198. package/dist/clis/reddit/frontpage.d.ts +1 -0
  199. package/dist/clis/reddit/frontpage.js +31 -0
  200. package/dist/clis/reddit/hot.d.ts +1 -0
  201. package/dist/clis/reddit/hot.js +45 -0
  202. package/dist/clis/reddit/popular.d.ts +1 -0
  203. package/dist/clis/reddit/popular.js +41 -0
  204. package/dist/clis/reddit/search.d.ts +1 -0
  205. package/dist/clis/reddit/search.js +65 -0
  206. package/dist/clis/reddit/subreddit.d.ts +1 -0
  207. package/dist/clis/reddit/subreddit.js +52 -0
  208. package/dist/clis/reddit/user-comments.d.ts +1 -0
  209. package/dist/clis/reddit/user-comments.js +44 -0
  210. package/dist/clis/reddit/user-posts.d.ts +1 -0
  211. package/dist/clis/reddit/user-posts.js +42 -0
  212. package/dist/clis/reddit/user.d.ts +1 -0
  213. package/dist/clis/reddit/user.js +37 -0
  214. package/dist/clis/stackoverflow/bounties.d.ts +1 -0
  215. package/dist/clis/stackoverflow/bounties.js +27 -0
  216. package/dist/clis/stackoverflow/hot.d.ts +1 -0
  217. package/dist/clis/stackoverflow/hot.js +24 -0
  218. package/dist/clis/stackoverflow/search.d.ts +1 -0
  219. package/dist/clis/stackoverflow/search.js +27 -0
  220. package/dist/clis/stackoverflow/unanswered.d.ts +1 -0
  221. package/dist/clis/stackoverflow/unanswered.js +26 -0
  222. package/dist/clis/steam/top-sellers.d.ts +1 -0
  223. package/dist/clis/steam/top-sellers.js +25 -0
  224. package/dist/clis/taobao/add-cart.d.ts +1 -0
  225. package/dist/clis/taobao/add-cart.js +149 -0
  226. package/dist/clis/taobao/cart.d.ts +1 -0
  227. package/dist/clis/taobao/cart.js +95 -0
  228. package/dist/clis/taobao/commands.test.d.ts +5 -0
  229. package/dist/clis/taobao/commands.test.js +64 -0
  230. package/dist/clis/taobao/detail.d.ts +1 -0
  231. package/dist/clis/taobao/detail.js +70 -0
  232. package/dist/clis/taobao/reviews.d.ts +1 -0
  233. package/dist/clis/taobao/reviews.js +76 -0
  234. package/dist/clis/taobao/search.d.ts +1 -0
  235. package/dist/clis/taobao/search.js +96 -0
  236. package/dist/clis/tiktok/comment.d.ts +1 -0
  237. package/dist/clis/tiktok/comment.js +57 -0
  238. package/dist/clis/tiktok/explore.d.ts +1 -0
  239. package/dist/clis/tiktok/explore.js +35 -0
  240. package/dist/clis/tiktok/follow.d.ts +1 -0
  241. package/dist/clis/tiktok/follow.js +39 -0
  242. package/dist/clis/tiktok/following.d.ts +1 -0
  243. package/dist/clis/tiktok/following.js +42 -0
  244. package/dist/clis/tiktok/friends.d.ts +1 -0
  245. package/dist/clis/tiktok/friends.js +43 -0
  246. package/dist/clis/tiktok/like.d.ts +1 -0
  247. package/dist/clis/tiktok/like.js +33 -0
  248. package/dist/clis/tiktok/live.d.ts +1 -0
  249. package/dist/clis/tiktok/live.js +47 -0
  250. package/dist/clis/tiktok/notifications.d.ts +1 -0
  251. package/dist/clis/tiktok/notifications.js +49 -0
  252. package/dist/clis/tiktok/profile.d.ts +1 -0
  253. package/dist/clis/tiktok/profile.js +54 -0
  254. package/dist/clis/tiktok/save.d.ts +1 -0
  255. package/dist/clis/tiktok/save.js +29 -0
  256. package/dist/clis/tiktok/search.d.ts +1 -0
  257. package/dist/clis/tiktok/search.js +39 -0
  258. package/dist/clis/tiktok/unfollow.d.ts +1 -0
  259. package/dist/clis/tiktok/unfollow.js +44 -0
  260. package/dist/clis/tiktok/unlike.d.ts +1 -0
  261. package/dist/clis/tiktok/unlike.js +33 -0
  262. package/dist/clis/tiktok/unsave.d.ts +1 -0
  263. package/dist/clis/tiktok/unsave.js +31 -0
  264. package/dist/clis/tiktok/user.d.ts +1 -0
  265. package/dist/clis/tiktok/user.js +41 -0
  266. package/dist/clis/twitter/reply.js +3 -8
  267. package/dist/clis/twitter/reply.test.js +5 -5
  268. package/dist/clis/v2ex/hot.d.ts +1 -0
  269. package/dist/clis/v2ex/hot.js +25 -0
  270. package/dist/clis/v2ex/latest.d.ts +1 -0
  271. package/dist/clis/v2ex/latest.js +25 -0
  272. package/dist/clis/v2ex/member.d.ts +1 -0
  273. package/dist/clis/v2ex/member.js +27 -0
  274. package/dist/clis/v2ex/node.d.ts +1 -0
  275. package/dist/clis/v2ex/node.js +38 -0
  276. package/dist/clis/v2ex/nodes.d.ts +1 -0
  277. package/dist/clis/v2ex/nodes.js +25 -0
  278. package/dist/clis/v2ex/replies.d.ts +1 -0
  279. package/dist/clis/v2ex/replies.js +26 -0
  280. package/dist/clis/v2ex/topic.d.ts +1 -0
  281. package/dist/clis/v2ex/topic.js +30 -0
  282. package/dist/clis/v2ex/user.d.ts +1 -0
  283. package/dist/clis/v2ex/user.js +33 -0
  284. package/dist/clis/xiaoe/catalog.d.ts +1 -0
  285. package/dist/clis/xiaoe/catalog.js +125 -0
  286. package/dist/clis/xiaoe/content.d.ts +1 -0
  287. package/dist/clis/xiaoe/content.js +39 -0
  288. package/dist/clis/xiaoe/courses.d.ts +1 -0
  289. package/dist/clis/xiaoe/courses.js +69 -0
  290. package/dist/clis/xiaoe/detail.d.ts +1 -0
  291. package/dist/clis/xiaoe/detail.js +35 -0
  292. package/dist/clis/xiaoe/play-url.d.ts +1 -0
  293. package/dist/clis/xiaoe/play-url.js +120 -0
  294. package/dist/clis/xiaohongshu/feed.d.ts +1 -0
  295. package/dist/clis/xiaohongshu/feed.js +32 -0
  296. package/dist/clis/xiaohongshu/note.js +8 -3
  297. package/dist/clis/xiaohongshu/note.test.js +11 -0
  298. package/dist/clis/xiaohongshu/notifications.d.ts +1 -0
  299. package/dist/clis/xiaohongshu/notifications.js +38 -0
  300. package/dist/clis/xueqiu/earnings-date.d.ts +1 -0
  301. package/dist/clis/xueqiu/earnings-date.js +61 -0
  302. package/dist/clis/xueqiu/feed.d.ts +1 -0
  303. package/dist/clis/xueqiu/feed.js +48 -0
  304. package/dist/clis/xueqiu/groups.d.ts +1 -0
  305. package/dist/clis/xueqiu/groups.js +25 -0
  306. package/dist/clis/xueqiu/hot-stock.d.ts +1 -0
  307. package/dist/clis/xueqiu/hot-stock.js +44 -0
  308. package/dist/clis/xueqiu/hot.d.ts +1 -0
  309. package/dist/clis/xueqiu/hot.js +44 -0
  310. package/dist/clis/xueqiu/kline.d.ts +1 -0
  311. package/dist/clis/xueqiu/kline.js +64 -0
  312. package/dist/clis/xueqiu/search.d.ts +1 -0
  313. package/dist/clis/xueqiu/search.js +49 -0
  314. package/dist/clis/xueqiu/stock.d.ts +1 -0
  315. package/dist/clis/xueqiu/stock.js +72 -0
  316. package/dist/clis/xueqiu/watchlist.d.ts +1 -0
  317. package/dist/clis/xueqiu/watchlist.js +45 -0
  318. package/dist/clis/zhihu/answer.d.ts +1 -0
  319. package/dist/clis/zhihu/answer.js +194 -0
  320. package/dist/clis/zhihu/answer.test.d.ts +1 -0
  321. package/dist/clis/zhihu/answer.test.js +81 -0
  322. package/dist/clis/zhihu/comment.d.ts +1 -0
  323. package/dist/clis/zhihu/comment.js +335 -0
  324. package/dist/clis/zhihu/comment.test.d.ts +1 -0
  325. package/dist/clis/zhihu/comment.test.js +54 -0
  326. package/dist/clis/zhihu/favorite.d.ts +1 -0
  327. package/dist/clis/zhihu/favorite.js +224 -0
  328. package/dist/clis/zhihu/favorite.test.d.ts +1 -0
  329. package/dist/clis/zhihu/favorite.test.js +196 -0
  330. package/dist/clis/zhihu/follow.d.ts +1 -0
  331. package/dist/clis/zhihu/follow.js +80 -0
  332. package/dist/clis/zhihu/follow.test.d.ts +1 -0
  333. package/dist/clis/zhihu/follow.test.js +45 -0
  334. package/dist/clis/zhihu/hot.d.ts +1 -0
  335. package/dist/clis/zhihu/hot.js +43 -0
  336. package/dist/clis/zhihu/like.d.ts +1 -0
  337. package/dist/clis/zhihu/like.js +91 -0
  338. package/dist/clis/zhihu/like.test.d.ts +1 -0
  339. package/dist/clis/zhihu/like.test.js +64 -0
  340. package/dist/clis/zhihu/search.d.ts +1 -0
  341. package/dist/clis/zhihu/search.js +52 -0
  342. package/dist/clis/zhihu/target.d.ts +24 -0
  343. package/dist/clis/zhihu/target.js +91 -0
  344. package/dist/clis/zhihu/target.test.d.ts +1 -0
  345. package/dist/clis/zhihu/target.test.js +77 -0
  346. package/dist/clis/zhihu/write-shared.d.ts +32 -0
  347. package/dist/clis/zhihu/write-shared.js +221 -0
  348. package/dist/clis/zhihu/write-shared.test.d.ts +1 -0
  349. package/dist/clis/zhihu/write-shared.test.js +175 -0
  350. package/dist/src/browser/bridge.d.ts +2 -0
  351. package/dist/src/browser/bridge.js +30 -24
  352. package/dist/src/browser/daemon-client.d.ts +30 -10
  353. package/dist/src/browser/daemon-client.js +42 -27
  354. package/dist/src/browser/daemon-client.test.js +32 -25
  355. package/dist/src/browser/dom-helpers.test.js +3 -2
  356. package/dist/src/browser/errors.d.ts +26 -1
  357. package/dist/src/browser/errors.js +40 -7
  358. package/dist/src/browser/errors.test.d.ts +1 -0
  359. package/dist/src/browser/errors.test.js +51 -0
  360. package/dist/src/browser/index.d.ts +2 -1
  361. package/dist/src/browser/index.js +1 -1
  362. package/dist/src/browser/page.d.ts +9 -8
  363. package/dist/src/browser/page.js +33 -31
  364. package/dist/src/browser.test.js +27 -8
  365. package/dist/src/build-manifest.d.ts +5 -11
  366. package/dist/src/build-manifest.js +6 -75
  367. package/dist/src/build-manifest.test.js +1 -39
  368. package/dist/src/cascade.js +3 -2
  369. package/dist/src/cli.d.ts +3 -3
  370. package/dist/src/cli.js +73 -65
  371. package/dist/src/cli.test.js +20 -15
  372. package/dist/src/clis/binance/asks.d.ts +1 -0
  373. package/dist/src/clis/binance/asks.js +20 -0
  374. package/dist/src/clis/binance/commands.test.d.ts +3 -0
  375. package/dist/src/clis/binance/commands.test.js +58 -0
  376. package/dist/src/clis/binance/depth.d.ts +1 -0
  377. package/dist/src/clis/binance/depth.js +20 -0
  378. package/dist/src/clis/binance/gainers.d.ts +1 -0
  379. package/dist/src/clis/binance/gainers.js +21 -0
  380. package/dist/src/clis/binance/klines.d.ts +1 -0
  381. package/dist/src/clis/binance/klines.js +20 -0
  382. package/dist/src/clis/binance/losers.d.ts +1 -0
  383. package/dist/src/clis/binance/losers.js +21 -0
  384. package/dist/src/clis/binance/pairs.d.ts +1 -0
  385. package/dist/src/clis/binance/pairs.js +20 -0
  386. package/dist/src/clis/binance/price.d.ts +1 -0
  387. package/dist/src/clis/binance/price.js +17 -0
  388. package/dist/src/clis/binance/prices.d.ts +1 -0
  389. package/dist/src/clis/binance/prices.js +18 -0
  390. package/dist/src/clis/binance/ticker.d.ts +1 -0
  391. package/dist/src/clis/binance/ticker.js +20 -0
  392. package/dist/src/clis/binance/top.d.ts +1 -0
  393. package/dist/src/clis/binance/top.js +20 -0
  394. package/dist/src/clis/binance/trades.d.ts +1 -0
  395. package/dist/src/clis/binance/trades.js +19 -0
  396. package/dist/src/commanderAdapter.js +19 -6
  397. package/dist/src/completion-fast.d.ts +25 -0
  398. package/dist/src/completion-fast.js +140 -0
  399. package/dist/src/completion.d.ts +1 -0
  400. package/dist/src/completion.js +1 -0
  401. package/dist/src/diagnostic.d.ts +1 -0
  402. package/dist/src/diagnostic.js +64 -2
  403. package/dist/src/diagnostic.test.js +93 -3
  404. package/dist/src/discovery.d.ts +3 -3
  405. package/dist/src/discovery.js +34 -97
  406. package/dist/src/doctor.d.ts +2 -0
  407. package/dist/src/doctor.js +59 -31
  408. package/dist/src/doctor.test.js +89 -16
  409. package/dist/src/download/index.d.ts +1 -1
  410. package/dist/src/engine.test.js +4 -19
  411. package/dist/src/execution.js +1 -13
  412. package/dist/src/explore.js +1 -1
  413. package/dist/src/generate-verified.d.ts +105 -0
  414. package/dist/src/generate-verified.js +696 -0
  415. package/dist/src/generate-verified.test.d.ts +1 -0
  416. package/dist/src/generate-verified.test.js +925 -0
  417. package/dist/src/generate.d.ts +11 -6
  418. package/dist/src/generate.js +4 -7
  419. package/dist/src/main.js +65 -12
  420. package/dist/src/pipeline/steps/download.d.ts +1 -17
  421. package/dist/src/pipeline/steps/download.js +20 -31
  422. package/dist/src/pipeline/steps/intercept.d.ts +1 -1
  423. package/dist/src/pipeline/steps/intercept.js +1 -1
  424. package/dist/src/pipeline/steps/tap.d.ts +1 -1
  425. package/dist/src/pipeline/steps/tap.js +1 -1
  426. package/dist/src/plugin-scaffold.d.ts +2 -2
  427. package/dist/src/plugin-scaffold.js +24 -21
  428. package/dist/src/plugin-scaffold.test.js +1 -1
  429. package/dist/src/plugin.d.ts +3 -2
  430. package/dist/src/plugin.js +29 -14
  431. package/dist/src/plugin.test.js +47 -32
  432. package/dist/src/record.js +26 -25
  433. package/dist/src/runtime-detect.js +3 -7
  434. package/dist/src/scripts/framework.d.ts +3 -0
  435. package/dist/src/scripts/framework.js +8 -4
  436. package/dist/src/scripts/store.d.ts +5 -1
  437. package/dist/src/scripts/store.js +5 -1
  438. package/dist/src/skill-generate.d.ts +30 -0
  439. package/dist/src/skill-generate.js +75 -0
  440. package/dist/src/skill-generate.test.d.ts +1 -0
  441. package/dist/src/skill-generate.test.js +173 -0
  442. package/dist/src/synthesize.d.ts +1 -1
  443. package/dist/src/synthesize.js +7 -8
  444. package/dist/src/types.d.ts +3 -1
  445. package/package.json +5 -5
  446. package/dist/clis/bilibili/hot.yaml +0 -38
  447. package/dist/clis/bluesky/feeds.yaml +0 -29
  448. package/dist/clis/bluesky/followers.yaml +0 -33
  449. package/dist/clis/bluesky/following.yaml +0 -33
  450. package/dist/clis/bluesky/profile.yaml +0 -27
  451. package/dist/clis/bluesky/search.yaml +0 -34
  452. package/dist/clis/bluesky/starter-packs.yaml +0 -34
  453. package/dist/clis/bluesky/thread.yaml +0 -32
  454. package/dist/clis/bluesky/trending.yaml +0 -27
  455. package/dist/clis/bluesky/user.yaml +0 -34
  456. package/dist/clis/devto/tag.yaml +0 -34
  457. package/dist/clis/devto/top.yaml +0 -29
  458. package/dist/clis/devto/user.yaml +0 -33
  459. package/dist/clis/dictionary/examples.yaml +0 -25
  460. package/dist/clis/dictionary/search.yaml +0 -27
  461. package/dist/clis/dictionary/synonyms.yaml +0 -25
  462. package/dist/clis/douban/subject.yaml +0 -107
  463. package/dist/clis/douban/top250.yaml +0 -70
  464. package/dist/clis/facebook/add-friend.yaml +0 -43
  465. package/dist/clis/facebook/events.yaml +0 -44
  466. package/dist/clis/facebook/feed.yaml +0 -63
  467. package/dist/clis/facebook/friends.yaml +0 -42
  468. package/dist/clis/facebook/groups.yaml +0 -50
  469. package/dist/clis/facebook/join-group.yaml +0 -44
  470. package/dist/clis/facebook/memories.yaml +0 -39
  471. package/dist/clis/facebook/notifications.yaml +0 -40
  472. package/dist/clis/facebook/profile.yaml +0 -37
  473. package/dist/clis/facebook/search.yaml +0 -47
  474. package/dist/clis/hackernews/ask.yaml +0 -38
  475. package/dist/clis/hackernews/best.yaml +0 -38
  476. package/dist/clis/hackernews/jobs.yaml +0 -36
  477. package/dist/clis/hackernews/new.yaml +0 -38
  478. package/dist/clis/hackernews/search.yaml +0 -44
  479. package/dist/clis/hackernews/show.yaml +0 -38
  480. package/dist/clis/hackernews/top.yaml +0 -38
  481. package/dist/clis/hackernews/user.yaml +0 -25
  482. package/dist/clis/hupu/hot.yaml +0 -43
  483. package/dist/clis/instagram/comment.yaml +0 -52
  484. package/dist/clis/instagram/explore.yaml +0 -43
  485. package/dist/clis/instagram/follow.yaml +0 -41
  486. package/dist/clis/instagram/followers.yaml +0 -51
  487. package/dist/clis/instagram/following.yaml +0 -51
  488. package/dist/clis/instagram/like.yaml +0 -46
  489. package/dist/clis/instagram/profile.yaml +0 -42
  490. package/dist/clis/instagram/save.yaml +0 -46
  491. package/dist/clis/instagram/saved.yaml +0 -40
  492. package/dist/clis/instagram/search.yaml +0 -44
  493. package/dist/clis/instagram/unfollow.yaml +0 -38
  494. package/dist/clis/instagram/unlike.yaml +0 -46
  495. package/dist/clis/instagram/unsave.yaml +0 -46
  496. package/dist/clis/instagram/user.yaml +0 -54
  497. package/dist/clis/jike/post.yaml +0 -59
  498. package/dist/clis/jike/topic.yaml +0 -53
  499. package/dist/clis/jike/user.yaml +0 -52
  500. package/dist/clis/jimeng/generate.yaml +0 -85
  501. package/dist/clis/jimeng/history.yaml +0 -46
  502. package/dist/clis/linux-do/categories.yaml +0 -70
  503. package/dist/clis/linux-do/search.yaml +0 -48
  504. package/dist/clis/linux-do/tags.yaml +0 -41
  505. package/dist/clis/linux-do/topic.yaml +0 -62
  506. package/dist/clis/linux-do/user-posts.yaml +0 -67
  507. package/dist/clis/linux-do/user-topics.yaml +0 -54
  508. package/dist/clis/lobsters/active.yaml +0 -29
  509. package/dist/clis/lobsters/hot.yaml +0 -29
  510. package/dist/clis/lobsters/newest.yaml +0 -29
  511. package/dist/clis/lobsters/tag.yaml +0 -34
  512. package/dist/clis/pixiv/detail.yaml +0 -49
  513. package/dist/clis/pixiv/ranking.yaml +0 -53
  514. package/dist/clis/pixiv/user.yaml +0 -46
  515. package/dist/clis/reddit/frontpage.yaml +0 -30
  516. package/dist/clis/reddit/hot.yaml +0 -47
  517. package/dist/clis/reddit/popular.yaml +0 -40
  518. package/dist/clis/reddit/search.yaml +0 -61
  519. package/dist/clis/reddit/subreddit.yaml +0 -50
  520. package/dist/clis/reddit/user-comments.yaml +0 -46
  521. package/dist/clis/reddit/user-posts.yaml +0 -44
  522. package/dist/clis/reddit/user.yaml +0 -40
  523. package/dist/clis/stackoverflow/bounties.yaml +0 -29
  524. package/dist/clis/stackoverflow/hot.yaml +0 -28
  525. package/dist/clis/stackoverflow/search.yaml +0 -33
  526. package/dist/clis/stackoverflow/unanswered.yaml +0 -28
  527. package/dist/clis/steam/top-sellers.yaml +0 -29
  528. package/dist/clis/tiktok/comment.yaml +0 -66
  529. package/dist/clis/tiktok/explore.yaml +0 -39
  530. package/dist/clis/tiktok/follow.yaml +0 -39
  531. package/dist/clis/tiktok/following.yaml +0 -46
  532. package/dist/clis/tiktok/friends.yaml +0 -47
  533. package/dist/clis/tiktok/like.yaml +0 -38
  534. package/dist/clis/tiktok/live.yaml +0 -51
  535. package/dist/clis/tiktok/notifications.yaml +0 -52
  536. package/dist/clis/tiktok/profile.yaml +0 -45
  537. package/dist/clis/tiktok/save.yaml +0 -34
  538. package/dist/clis/tiktok/search.yaml +0 -47
  539. package/dist/clis/tiktok/unfollow.yaml +0 -44
  540. package/dist/clis/tiktok/unlike.yaml +0 -38
  541. package/dist/clis/tiktok/unsave.yaml +0 -36
  542. package/dist/clis/tiktok/user.yaml +0 -44
  543. package/dist/clis/v2ex/hot.yaml +0 -28
  544. package/dist/clis/v2ex/latest.yaml +0 -28
  545. package/dist/clis/v2ex/member.yaml +0 -29
  546. package/dist/clis/v2ex/node.yaml +0 -34
  547. package/dist/clis/v2ex/nodes.yaml +0 -31
  548. package/dist/clis/v2ex/replies.yaml +0 -32
  549. package/dist/clis/v2ex/topic.yaml +0 -33
  550. package/dist/clis/v2ex/user.yaml +0 -34
  551. package/dist/clis/xiaoe/catalog.yaml +0 -129
  552. package/dist/clis/xiaoe/content.yaml +0 -43
  553. package/dist/clis/xiaoe/courses.yaml +0 -73
  554. package/dist/clis/xiaoe/detail.yaml +0 -39
  555. package/dist/clis/xiaoe/play-url.yaml +0 -124
  556. package/dist/clis/xiaohongshu/feed.yaml +0 -31
  557. package/dist/clis/xiaohongshu/notifications.yaml +0 -37
  558. package/dist/clis/xueqiu/earnings-date.yaml +0 -69
  559. package/dist/clis/xueqiu/feed.yaml +0 -53
  560. package/dist/clis/xueqiu/groups.yaml +0 -23
  561. package/dist/clis/xueqiu/hot-stock.yaml +0 -49
  562. package/dist/clis/xueqiu/hot.yaml +0 -46
  563. package/dist/clis/xueqiu/kline.yaml +0 -65
  564. package/dist/clis/xueqiu/search.yaml +0 -55
  565. package/dist/clis/xueqiu/stock.yaml +0 -69
  566. package/dist/clis/xueqiu/watchlist.yaml +0 -46
  567. package/dist/clis/zhihu/hot.yaml +0 -46
  568. package/dist/clis/zhihu/search.yaml +0 -59
  569. package/dist/src/browser/discover.d.ts +0 -15
  570. package/dist/src/browser/discover.js +0 -19
  571. package/dist/src/yaml-schema.d.ts +0 -29
  572. package/dist/src/yaml-schema.js +0 -22
@@ -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 tabId returned by the navigate
8
- * action and pass it to all subsequent commands. This avoids the issue
9
- * where resolveTabId() in the extension picks a chrome:// or
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
- export function isRetryableSettleError(err) {
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 tab ID, set after navigate and used in all subsequent commands */
33
- _tabId;
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 + tabId into command params */
33
+ /** Helper: spread workspace + page identity into command params */
39
34
  _cmdOpts() {
40
35
  return {
41
36
  workspace: this.workspace,
42
- ...(this._tabId !== undefined && { tabId: this._tabId }),
37
+ ...(this._page !== undefined && { page: this._page }),
43
38
  };
44
39
  }
45
40
  async goto(url, options) {
46
- const result = await sendCommand('navigate', {
41
+ const result = await sendCommandFull('navigate', {
47
42
  url,
48
43
  ...this._cmdOpts(),
49
44
  });
50
- // Remember the tabId and URL for subsequent calls
51
- if (result?.tabId) {
52
- this._tabId = result.tabId;
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
- if (!isRetryableSettleError(err))
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, 200));
70
+ await new Promise((r) => setTimeout(r, advice.delayMs));
75
71
  await sendCommand('exec', combinedOpts);
76
72
  }
77
73
  catch (retryErr) {
78
- if (!isRetryableSettleError(retryErr))
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 this._tabId;
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
- if (!isRetryableSettleError(err))
106
+ const advice = classifyBrowserError(err);
107
+ if (advice.kind !== 'target-navigation')
106
108
  throw err;
107
- await new Promise((resolve) => setTimeout(resolve, 200));
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._tabId = undefined;
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 sendCommand('tabs', { op: 'select', index, ...this._wsOpt() });
134
- if (result?.selected)
135
- this._tabId = result.selected;
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.
@@ -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 { isRetryableSettleError } from './browser/page.js';
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('retries settle only for target-invalidated errors', () => {
39
- expect(isRetryableSettleError(new Error('{"code":-32000,"message":"Inspected target navigated or closed"}'))).toBe(true);
40
- expect(isRetryableSettleError(new Error('attach failed: target no longer exists'))).toBe(false);
41
- expect(isRetryableSettleError(new Error('malformed exec payload'))).toBe(false);
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, 'isExtensionConnected').mockResolvedValue(false);
109
- vi.spyOn(daemonClient, 'fetchDaemonStatus').mockResolvedValue({ extensionConnected: false });
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 Extension is not connected');
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 YAML/TS CLI definitions and pre-compiles them into a single
6
- * manifest.json for instant cold-start registration (no runtime YAML parsing).
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
- /** 'yaml' or 'ts' — determines how executeCommand loads the handler */
35
- type: 'yaml' | 'ts';
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 (for YAML: 'site/cmd.yaml') */
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 YAML/TS CLI definitions and pre-compiles them into a single
6
- * manifest.json for instant cold-start registration (no runtime YAML parsing).
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
- const filePath = path.join(siteDir, file);
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
- const existing = manifest.get(key);
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
- const yamlCount = manifest.filter(e => e.type === 'yaml').length;
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, shouldReplaceManifestEntry } from './build-manifest.js';
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);
@@ -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 OperateVerifyInvocation {
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 resolveOperateVerifyInvocation(opts?: {
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
- }): OperateVerifyInvocation;
23
+ }): BrowserVerifyInvocation;