@jackwener/opencli 1.7.11 → 1.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (730) hide show
  1. package/README.zh-CN.md +2 -1
  2. package/cli-manifest.json +1417 -24
  3. package/clis/1688/assets.js +1 -0
  4. package/clis/1688/download.js +1 -0
  5. package/clis/1688/item.js +1 -0
  6. package/clis/1688/search.js +2 -1
  7. package/clis/1688/store.js +1 -0
  8. package/clis/36kr/article.js +1 -0
  9. package/clis/36kr/hot.js +1 -0
  10. package/clis/36kr/news.js +1 -0
  11. package/clis/36kr/search.js +1 -0
  12. package/clis/51job/company.js +1 -0
  13. package/clis/51job/detail.js +1 -0
  14. package/clis/51job/hot.js +1 -0
  15. package/clis/51job/search.js +1 -0
  16. package/clis/amazon/bestsellers.js +1 -0
  17. package/clis/amazon/discussion.js +1 -0
  18. package/clis/amazon/movers-shakers.js +1 -0
  19. package/clis/amazon/new-releases.js +1 -0
  20. package/clis/amazon/offer.js +1 -0
  21. package/clis/amazon/product.js +1 -0
  22. package/clis/amazon/rankings.js +1 -0
  23. package/clis/amazon/search.js +1 -0
  24. package/clis/antigravity/dump.js +1 -0
  25. package/clis/antigravity/extract-code.js +1 -0
  26. package/clis/antigravity/model.js +1 -0
  27. package/clis/antigravity/new.js +1 -0
  28. package/clis/antigravity/read.js +1 -0
  29. package/clis/antigravity/send.js +1 -0
  30. package/clis/antigravity/status.js +1 -0
  31. package/clis/antigravity/watch.js +1 -0
  32. package/clis/apple-podcasts/episodes.js +1 -0
  33. package/clis/apple-podcasts/search.js +1 -0
  34. package/clis/apple-podcasts/top.js +1 -0
  35. package/clis/arxiv/arxiv.test.js +112 -0
  36. package/clis/arxiv/paper.js +4 -3
  37. package/clis/arxiv/recent.js +33 -0
  38. package/clis/arxiv/search.js +19 -7
  39. package/clis/arxiv/utils.js +68 -5
  40. package/clis/baidu-scholar/search.js +1 -0
  41. package/clis/band/bands.js +1 -0
  42. package/clis/band/mentions.js +1 -0
  43. package/clis/band/post.js +1 -0
  44. package/clis/band/posts.js +1 -0
  45. package/clis/barchart/flow.js +1 -0
  46. package/clis/barchart/greeks.js +1 -0
  47. package/clis/barchart/options.js +1 -0
  48. package/clis/barchart/quote.js +1 -0
  49. package/clis/bbc/news.js +1 -0
  50. package/clis/bilibili/comments.js +1 -0
  51. package/clis/bilibili/download.js +1 -0
  52. package/clis/bilibili/dynamic.js +1 -0
  53. package/clis/bilibili/favorite.js +1 -0
  54. package/clis/bilibili/feed.js +2 -0
  55. package/clis/bilibili/following.js +1 -0
  56. package/clis/bilibili/history.js +1 -0
  57. package/clis/bilibili/hot.js +6 -1
  58. package/clis/bilibili/hot.test.js +17 -0
  59. package/clis/bilibili/me.js +1 -1
  60. package/clis/bilibili/ranking.js +1 -0
  61. package/clis/bilibili/search.js +1 -1
  62. package/clis/bilibili/subtitle.js +1 -0
  63. package/clis/bilibili/user-videos.js +1 -0
  64. package/clis/bilibili/video.js +1 -0
  65. package/clis/binance/asks.js +1 -0
  66. package/clis/binance/depth.js +1 -0
  67. package/clis/binance/gainers.js +1 -0
  68. package/clis/binance/klines.js +1 -0
  69. package/clis/binance/losers.js +1 -0
  70. package/clis/binance/pairs.js +1 -0
  71. package/clis/binance/price.js +1 -0
  72. package/clis/binance/prices.js +1 -0
  73. package/clis/binance/ticker.js +1 -0
  74. package/clis/binance/top.js +1 -0
  75. package/clis/binance/trades.js +1 -0
  76. package/clis/bloomberg/businessweek.js +1 -0
  77. package/clis/bloomberg/economics.js +1 -0
  78. package/clis/bloomberg/feeds.js +1 -0
  79. package/clis/bloomberg/industries.js +1 -0
  80. package/clis/bloomberg/main.js +1 -0
  81. package/clis/bloomberg/markets.js +1 -0
  82. package/clis/bloomberg/news.js +1 -0
  83. package/clis/bloomberg/opinions.js +1 -0
  84. package/clis/bloomberg/politics.js +1 -0
  85. package/clis/bloomberg/tech.js +1 -0
  86. package/clis/bluesky/feeds.js +1 -0
  87. package/clis/bluesky/followers.js +1 -0
  88. package/clis/bluesky/following.js +1 -0
  89. package/clis/bluesky/profile.js +1 -0
  90. package/clis/bluesky/search.js +1 -0
  91. package/clis/bluesky/starter-packs.js +1 -0
  92. package/clis/bluesky/thread.js +1 -0
  93. package/clis/bluesky/trending.js +1 -0
  94. package/clis/bluesky/user.js +3 -1
  95. package/clis/boss/batchgreet.js +1 -0
  96. package/clis/boss/chatlist.js +1 -0
  97. package/clis/boss/chatmsg.js +1 -0
  98. package/clis/boss/detail.js +1 -0
  99. package/clis/boss/exchange.js +1 -0
  100. package/clis/boss/greet.js +1 -0
  101. package/clis/boss/invite.js +1 -0
  102. package/clis/boss/joblist.js +1 -0
  103. package/clis/boss/mark.js +1 -0
  104. package/clis/boss/recommend.js +1 -0
  105. package/clis/boss/resume.js +1 -0
  106. package/clis/boss/search.js +1 -0
  107. package/clis/boss/send.js +1 -0
  108. package/clis/boss/stats.js +1 -0
  109. package/clis/chaoxing/assignments.js +1 -0
  110. package/clis/chaoxing/exams.js +1 -0
  111. package/clis/chatgpt/image.js +1 -0
  112. package/clis/chatgpt-app/ask.js +1 -0
  113. package/clis/chatgpt-app/model.js +1 -0
  114. package/clis/chatgpt-app/new.js +1 -0
  115. package/clis/chatgpt-app/read.js +1 -0
  116. package/clis/chatgpt-app/send.js +1 -0
  117. package/clis/chatgpt-app/status.js +1 -0
  118. package/clis/chatwise/ask.js +1 -0
  119. package/clis/chatwise/export.js +1 -0
  120. package/clis/chatwise/history.js +1 -0
  121. package/clis/chatwise/model.js +1 -0
  122. package/clis/chatwise/read.js +1 -0
  123. package/clis/chatwise/send.js +1 -0
  124. package/clis/claude/ask.js +1 -0
  125. package/clis/claude/detail.js +1 -0
  126. package/clis/claude/history.js +1 -0
  127. package/clis/claude/new.js +1 -0
  128. package/clis/claude/read.js +1 -0
  129. package/clis/claude/send.js +1 -0
  130. package/clis/claude/status.js +1 -0
  131. package/clis/cnki/search.js +1 -0
  132. package/clis/codex/ask.js +1 -0
  133. package/clis/codex/export.js +1 -0
  134. package/clis/codex/extract-diff.js +1 -0
  135. package/clis/codex/history.js +1 -0
  136. package/clis/codex/model.js +1 -0
  137. package/clis/codex/read.js +1 -0
  138. package/clis/codex/send.js +1 -0
  139. package/clis/coupang/add-to-cart.js +1 -0
  140. package/clis/coupang/search.js +1 -0
  141. package/clis/ctrip/search.js +1 -0
  142. package/clis/cursor/ask.js +1 -0
  143. package/clis/cursor/composer.js +1 -0
  144. package/clis/cursor/export.js +1 -0
  145. package/clis/cursor/extract-code.js +1 -0
  146. package/clis/cursor/history.js +1 -0
  147. package/clis/cursor/model.js +1 -0
  148. package/clis/cursor/read.js +1 -0
  149. package/clis/cursor/send.js +1 -0
  150. package/clis/dblp/dblp.test.js +397 -0
  151. package/clis/dblp/paper.js +40 -0
  152. package/clis/dblp/search.js +45 -0
  153. package/clis/dblp/utils.js +290 -0
  154. package/clis/deepseek/ask.js +1 -0
  155. package/clis/deepseek/history.js +1 -0
  156. package/clis/deepseek/new.js +1 -0
  157. package/clis/deepseek/read.js +1 -0
  158. package/clis/deepseek/status.js +1 -0
  159. package/clis/devto/devto.test.js +236 -0
  160. package/clis/devto/read.js +103 -0
  161. package/clis/devto/tag.js +5 -1
  162. package/clis/devto/top.js +5 -1
  163. package/clis/devto/user.js +5 -1
  164. package/clis/dianping/__fixtures__/search.html +168 -0
  165. package/clis/dianping/__fixtures__/shop.html +6 -0
  166. package/clis/dianping/dianping.test.js +424 -0
  167. package/clis/dianping/search.js +154 -0
  168. package/clis/dianping/shop.js +173 -0
  169. package/clis/dianping/utils.js +157 -0
  170. package/clis/dictionary/examples.js +1 -0
  171. package/clis/dictionary/search.js +1 -0
  172. package/clis/dictionary/synonyms.js +1 -0
  173. package/clis/discord-app/channels.js +1 -0
  174. package/clis/discord-app/delete.js +1 -0
  175. package/clis/discord-app/members.js +1 -0
  176. package/clis/discord-app/read.js +1 -0
  177. package/clis/discord-app/search.js +1 -0
  178. package/clis/discord-app/send.js +1 -0
  179. package/clis/discord-app/servers.js +1 -0
  180. package/clis/discord-app/status.js +1 -0
  181. package/clis/douban/book-hot.js +1 -0
  182. package/clis/douban/download.js +1 -0
  183. package/clis/douban/marks.js +1 -0
  184. package/clis/douban/movie-hot.js +2 -1
  185. package/clis/douban/movie-hot.test.js +14 -0
  186. package/clis/douban/photos.js +2 -1
  187. package/clis/douban/reviews.js +1 -0
  188. package/clis/douban/search.js +1 -0
  189. package/clis/douban/subject.js +1 -0
  190. package/clis/douban/top250.js +1 -0
  191. package/clis/douban/utils.js +11 -13
  192. package/clis/douban/utils.test.js +79 -0
  193. package/clis/doubao/ask.js +1 -0
  194. package/clis/doubao/detail.js +1 -0
  195. package/clis/doubao/history.js +1 -0
  196. package/clis/doubao/meeting-summary.js +1 -0
  197. package/clis/doubao/meeting-transcript.js +1 -0
  198. package/clis/doubao/new.js +1 -0
  199. package/clis/doubao/read.js +1 -0
  200. package/clis/doubao/send.js +1 -0
  201. package/clis/doubao/status.js +1 -0
  202. package/clis/doubao-app/ask.js +1 -0
  203. package/clis/doubao-app/dump.js +1 -0
  204. package/clis/doubao-app/new.js +1 -0
  205. package/clis/doubao-app/read.js +1 -0
  206. package/clis/doubao-app/screenshot.js +1 -0
  207. package/clis/doubao-app/send.js +1 -0
  208. package/clis/doubao-app/status.js +1 -0
  209. package/clis/douyin/activities.js +1 -0
  210. package/clis/douyin/collections.js +1 -0
  211. package/clis/douyin/delete.js +1 -0
  212. package/clis/douyin/draft.js +1 -0
  213. package/clis/douyin/drafts.js +1 -0
  214. package/clis/douyin/hashtag.js +1 -0
  215. package/clis/douyin/location.js +1 -0
  216. package/clis/douyin/profile.js +1 -0
  217. package/clis/douyin/publish.js +1 -0
  218. package/clis/douyin/stats.js +1 -0
  219. package/clis/douyin/update.js +1 -0
  220. package/clis/douyin/user-videos.js +1 -0
  221. package/clis/douyin/videos.js +1 -0
  222. package/clis/eastmoney/announcement.js +1 -0
  223. package/clis/eastmoney/convertible.js +1 -0
  224. package/clis/eastmoney/etf.js +1 -0
  225. package/clis/eastmoney/holders.js +1 -0
  226. package/clis/eastmoney/hot-rank.js +1 -0
  227. package/clis/eastmoney/index-board.js +1 -0
  228. package/clis/eastmoney/kline.js +1 -0
  229. package/clis/eastmoney/kuaixun.js +1 -0
  230. package/clis/eastmoney/longhu.js +1 -0
  231. package/clis/eastmoney/money-flow.js +1 -0
  232. package/clis/eastmoney/northbound.js +1 -0
  233. package/clis/eastmoney/quote.js +1 -0
  234. package/clis/eastmoney/rank.js +1 -0
  235. package/clis/eastmoney/sectors.js +1 -0
  236. package/clis/facebook/add-friend.js +1 -0
  237. package/clis/facebook/events.js +1 -0
  238. package/clis/facebook/feed.js +1 -0
  239. package/clis/facebook/friends.js +1 -0
  240. package/clis/facebook/groups.js +1 -0
  241. package/clis/facebook/join-group.js +1 -0
  242. package/clis/facebook/marketplace-inbox.js +1 -0
  243. package/clis/facebook/marketplace-listings.js +1 -0
  244. package/clis/facebook/memories.js +1 -0
  245. package/clis/facebook/notifications.js +1 -0
  246. package/clis/facebook/profile.js +1 -0
  247. package/clis/facebook/search.js +1 -0
  248. package/clis/gemini/ask.js +1 -0
  249. package/clis/gemini/deep-research-result.js +1 -0
  250. package/clis/gemini/deep-research.js +1 -0
  251. package/clis/gemini/image.js +1 -0
  252. package/clis/gemini/new.js +1 -0
  253. package/clis/gitee/search.js +1 -0
  254. package/clis/gitee/trending.js +1 -0
  255. package/clis/gitee/user.js +1 -0
  256. package/clis/google/news.js +1 -0
  257. package/clis/google/search.js +1 -0
  258. package/clis/google/suggest.js +1 -0
  259. package/clis/google/trends.js +1 -0
  260. package/clis/google-scholar/cite.js +1 -0
  261. package/clis/google-scholar/profile.js +1 -0
  262. package/clis/google-scholar/search.js +1 -0
  263. package/clis/gov-law/recent.js +1 -0
  264. package/clis/gov-law/search.js +1 -0
  265. package/clis/gov-policy/recent.js +1 -0
  266. package/clis/gov-policy/search.js +1 -0
  267. package/clis/grok/ask.js +1 -0
  268. package/clis/grok/image.ts +1 -0
  269. package/clis/hackernews/ask.js +3 -1
  270. package/clis/hackernews/best.js +3 -1
  271. package/clis/hackernews/hackernews.test.js +132 -0
  272. package/clis/hackernews/jobs.js +3 -1
  273. package/clis/hackernews/new.js +3 -1
  274. package/clis/hackernews/read.js +188 -0
  275. package/clis/hackernews/search.js +3 -1
  276. package/clis/hackernews/show.js +3 -1
  277. package/clis/hackernews/top.js +3 -1
  278. package/clis/hackernews/user.js +1 -0
  279. package/clis/hf/top.js +1 -0
  280. package/clis/hupu/detail.js +1 -0
  281. package/clis/hupu/hot.js +3 -1
  282. package/clis/hupu/like.js +1 -0
  283. package/clis/hupu/mentions.js +2 -1
  284. package/clis/hupu/reply.js +1 -0
  285. package/clis/hupu/search.js +3 -1
  286. package/clis/hupu/unlike.js +1 -0
  287. package/clis/imdb/person.js +1 -0
  288. package/clis/imdb/reviews.js +1 -0
  289. package/clis/imdb/search.js +1 -0
  290. package/clis/imdb/title.js +1 -0
  291. package/clis/imdb/top.js +1 -0
  292. package/clis/imdb/trending.js +1 -0
  293. package/clis/indeed/indeed.test.js +375 -0
  294. package/clis/indeed/job.js +86 -0
  295. package/clis/indeed/search.js +110 -0
  296. package/clis/indeed/utils.js +152 -0
  297. package/clis/instagram/collection-create.js +1 -0
  298. package/clis/instagram/collection-delete.js +1 -0
  299. package/clis/instagram/comment.js +1 -0
  300. package/clis/instagram/download.js +1 -0
  301. package/clis/instagram/explore.js +1 -0
  302. package/clis/instagram/follow.js +1 -0
  303. package/clis/instagram/followers.js +1 -0
  304. package/clis/instagram/following.js +1 -0
  305. package/clis/instagram/like.js +1 -0
  306. package/clis/instagram/note.js +1 -0
  307. package/clis/instagram/post.js +1 -0
  308. package/clis/instagram/profile.js +1 -0
  309. package/clis/instagram/reel.js +1 -0
  310. package/clis/instagram/save.js +1 -0
  311. package/clis/instagram/saved.js +1 -0
  312. package/clis/instagram/search.js +1 -0
  313. package/clis/instagram/story.js +1 -0
  314. package/clis/instagram/unfollow.js +1 -0
  315. package/clis/instagram/unlike.js +1 -0
  316. package/clis/instagram/unsave.js +1 -0
  317. package/clis/instagram/user.js +1 -0
  318. package/clis/jd/add-cart.js +1 -0
  319. package/clis/jd/cart.js +1 -0
  320. package/clis/jd/detail.js +1 -0
  321. package/clis/jd/item.js +1 -0
  322. package/clis/jd/reviews.js +1 -0
  323. package/clis/jd/search.js +1 -0
  324. package/clis/jianyu/detail.js +1 -0
  325. package/clis/jianyu/search.js +1 -0
  326. package/clis/jike/comment.js +1 -0
  327. package/clis/jike/create.js +1 -0
  328. package/clis/jike/feed.js +3 -1
  329. package/clis/jike/like.js +1 -0
  330. package/clis/jike/notifications.js +1 -0
  331. package/clis/jike/post.js +1 -0
  332. package/clis/jike/repost.js +1 -0
  333. package/clis/jike/search.js +3 -1
  334. package/clis/jike/topic.js +1 -0
  335. package/clis/jike/user.js +3 -1
  336. package/clis/jimeng/generate.js +1 -0
  337. package/clis/jimeng/history.js +1 -0
  338. package/clis/jimeng/new.js +1 -0
  339. package/clis/jimeng/workspaces.js +1 -0
  340. package/clis/ke/chengjiao.js +1 -0
  341. package/clis/ke/ershoufang.js +1 -0
  342. package/clis/ke/xiaoqu.js +1 -0
  343. package/clis/ke/zufang.js +1 -0
  344. package/clis/lesswrong/comments.js +1 -0
  345. package/clis/lesswrong/curated.js +1 -0
  346. package/clis/lesswrong/frontpage.js +1 -0
  347. package/clis/lesswrong/new.js +1 -0
  348. package/clis/lesswrong/read.js +1 -0
  349. package/clis/lesswrong/sequences.js +1 -0
  350. package/clis/lesswrong/shortform.js +1 -0
  351. package/clis/lesswrong/tag.js +1 -0
  352. package/clis/lesswrong/tags.js +1 -0
  353. package/clis/lesswrong/top-month.js +1 -0
  354. package/clis/lesswrong/top-week.js +1 -0
  355. package/clis/lesswrong/top-year.js +1 -0
  356. package/clis/lesswrong/top.js +1 -0
  357. package/clis/lesswrong/user-posts.js +1 -0
  358. package/clis/lesswrong/user.js +1 -0
  359. package/clis/linkedin/search.js +1 -0
  360. package/clis/linkedin/timeline.js +1 -0
  361. package/clis/linux-do/categories.js +1 -0
  362. package/clis/linux-do/category.js +1 -0
  363. package/clis/linux-do/feed.js +1 -0
  364. package/clis/linux-do/hot.js +1 -0
  365. package/clis/linux-do/latest.js +1 -0
  366. package/clis/linux-do/search.js +1 -0
  367. package/clis/linux-do/tags.js +2 -1
  368. package/clis/linux-do/topic-content.js +1 -0
  369. package/clis/linux-do/topic.js +1 -0
  370. package/clis/linux-do/user-posts.js +1 -0
  371. package/clis/linux-do/user-topics.js +1 -0
  372. package/clis/lobsters/active.js +4 -1
  373. package/clis/lobsters/hot.js +4 -1
  374. package/clis/lobsters/lobsters.test.js +169 -0
  375. package/clis/lobsters/newest.js +4 -1
  376. package/clis/lobsters/read.js +196 -0
  377. package/clis/lobsters/tag.js +4 -1
  378. package/clis/maimai/search-talents.js +1 -0
  379. package/clis/medium/feed.js +1 -0
  380. package/clis/medium/search.js +1 -0
  381. package/clis/medium/user.js +1 -0
  382. package/clis/mubu/doc.js +1 -0
  383. package/clis/mubu/docs.js +1 -0
  384. package/clis/mubu/notes.js +1 -0
  385. package/clis/mubu/recent.js +1 -0
  386. package/clis/mubu/search.js +1 -0
  387. package/clis/notebooklm/current.js +1 -0
  388. package/clis/notebooklm/get.js +1 -0
  389. package/clis/notebooklm/history.js +1 -0
  390. package/clis/notebooklm/list.js +1 -0
  391. package/clis/notebooklm/note-list.js +1 -0
  392. package/clis/notebooklm/notes-get.js +1 -0
  393. package/clis/notebooklm/open.js +1 -0
  394. package/clis/notebooklm/source-fulltext.js +1 -0
  395. package/clis/notebooklm/source-get.js +1 -0
  396. package/clis/notebooklm/source-guide.js +1 -0
  397. package/clis/notebooklm/source-list.js +1 -0
  398. package/clis/notebooklm/status.js +1 -0
  399. package/clis/notebooklm/summary.js +1 -0
  400. package/clis/notion/export.js +1 -0
  401. package/clis/notion/favorites.js +1 -0
  402. package/clis/notion/new.js +1 -0
  403. package/clis/notion/read.js +1 -0
  404. package/clis/notion/search.js +1 -0
  405. package/clis/notion/sidebar.js +1 -0
  406. package/clis/notion/status.js +1 -0
  407. package/clis/notion/write.js +1 -0
  408. package/clis/nowcoder/companies.js +1 -0
  409. package/clis/nowcoder/creators.js +1 -0
  410. package/clis/nowcoder/detail.js +1 -0
  411. package/clis/nowcoder/experience.js +1 -0
  412. package/clis/nowcoder/hot.js +1 -0
  413. package/clis/nowcoder/jobs.js +1 -0
  414. package/clis/nowcoder/notifications.js +1 -0
  415. package/clis/nowcoder/papers.js +1 -0
  416. package/clis/nowcoder/practice.js +1 -0
  417. package/clis/nowcoder/recommend.js +1 -0
  418. package/clis/nowcoder/referral.js +1 -0
  419. package/clis/nowcoder/salary.js +1 -0
  420. package/clis/nowcoder/search.js +1 -0
  421. package/clis/nowcoder/suggest.js +1 -0
  422. package/clis/nowcoder/topics.js +1 -0
  423. package/clis/nowcoder/trending.js +1 -0
  424. package/clis/ones/login.js +1 -0
  425. package/clis/ones/logout.js +1 -0
  426. package/clis/ones/me.js +1 -0
  427. package/clis/ones/my-tasks.js +1 -0
  428. package/clis/ones/task.js +1 -0
  429. package/clis/ones/tasks.js +1 -0
  430. package/clis/ones/token-info.js +1 -0
  431. package/clis/ones/worklog.js +1 -0
  432. package/clis/openreview/openreview.test.js +345 -0
  433. package/clis/openreview/paper.js +43 -0
  434. package/clis/openreview/reviews.js +131 -0
  435. package/clis/openreview/search.js +46 -0
  436. package/clis/openreview/utils.js +158 -0
  437. package/clis/openreview/venue.js +63 -0
  438. package/clis/paperreview/feedback.js +1 -0
  439. package/clis/paperreview/review.js +1 -0
  440. package/clis/paperreview/submit.js +1 -0
  441. package/clis/pixiv/detail.js +1 -0
  442. package/clis/pixiv/download.js +1 -0
  443. package/clis/pixiv/illusts.js +2 -1
  444. package/clis/pixiv/ranking.js +2 -1
  445. package/clis/pixiv/search.js +2 -1
  446. package/clis/pixiv/user.js +2 -0
  447. package/clis/powerchina/search.js +1 -0
  448. package/clis/producthunt/browse.js +1 -0
  449. package/clis/producthunt/hot.js +1 -0
  450. package/clis/producthunt/posts.js +1 -0
  451. package/clis/producthunt/today.js +1 -0
  452. package/clis/quark/ls.js +1 -0
  453. package/clis/quark/mkdir.js +1 -0
  454. package/clis/quark/mv.js +1 -0
  455. package/clis/quark/rename.js +1 -0
  456. package/clis/quark/rm.js +1 -0
  457. package/clis/quark/save.js +1 -0
  458. package/clis/quark/share-tree.js +1 -0
  459. package/clis/reddit/comment.js +1 -0
  460. package/clis/reddit/frontpage.js +1 -0
  461. package/clis/reddit/hot.js +6 -1
  462. package/clis/reddit/hot.test.js +18 -0
  463. package/clis/reddit/popular.js +1 -0
  464. package/clis/reddit/read.js +1 -0
  465. package/clis/reddit/save.js +1 -0
  466. package/clis/reddit/saved.js +1 -0
  467. package/clis/reddit/search.js +1 -0
  468. package/clis/reddit/subreddit.js +1 -0
  469. package/clis/reddit/subscribe.js +1 -0
  470. package/clis/reddit/upvote.js +1 -0
  471. package/clis/reddit/upvoted.js +1 -0
  472. package/clis/reddit/user-comments.js +1 -0
  473. package/clis/reddit/user-posts.js +1 -0
  474. package/clis/reddit/user.js +1 -0
  475. package/clis/reuters/search.js +1 -0
  476. package/clis/sinablog/article.js +1 -0
  477. package/clis/sinablog/hot.js +1 -0
  478. package/clis/sinablog/search.js +1 -0
  479. package/clis/sinablog/user.js +1 -0
  480. package/clis/sinafinance/news.js +1 -0
  481. package/clis/sinafinance/rolling-news.js +1 -0
  482. package/clis/sinafinance/stock-rank.js +1 -0
  483. package/clis/sinafinance/stock.js +1 -0
  484. package/clis/smzdm/search.js +1 -0
  485. package/clis/spotify/spotify.js +11 -0
  486. package/clis/stackoverflow/bounties.js +11 -3
  487. package/clis/stackoverflow/hot.js +10 -2
  488. package/clis/stackoverflow/read.js +314 -0
  489. package/clis/stackoverflow/search.js +10 -2
  490. package/clis/stackoverflow/stackoverflow.test.js +346 -0
  491. package/clis/stackoverflow/unanswered.js +9 -2
  492. package/clis/steam/top-sellers.js +1 -0
  493. package/clis/substack/feed.js +1 -0
  494. package/clis/substack/publication.js +1 -0
  495. package/clis/substack/search.js +1 -0
  496. package/clis/taobao/add-cart.js +1 -0
  497. package/clis/taobao/cart.js +1 -0
  498. package/clis/taobao/detail.js +1 -0
  499. package/clis/taobao/reviews.js +1 -0
  500. package/clis/taobao/search.js +1 -0
  501. package/clis/tdx/hot-rank.js +1 -0
  502. package/clis/ths/hot-rank.js +1 -0
  503. package/clis/tieba/hot.js +2 -1
  504. package/clis/tieba/posts.js +1 -0
  505. package/clis/tieba/read.js +1 -0
  506. package/clis/tieba/search.js +2 -1
  507. package/clis/tiktok/comment.js +1 -0
  508. package/clis/tiktok/explore.js +1 -0
  509. package/clis/tiktok/follow.js +1 -0
  510. package/clis/tiktok/following.js +1 -0
  511. package/clis/tiktok/friends.js +1 -0
  512. package/clis/tiktok/like.js +1 -0
  513. package/clis/tiktok/live.js +1 -0
  514. package/clis/tiktok/notifications.js +1 -0
  515. package/clis/tiktok/profile.js +1 -0
  516. package/clis/tiktok/save.js +1 -0
  517. package/clis/tiktok/search.js +1 -0
  518. package/clis/tiktok/unfollow.js +1 -0
  519. package/clis/tiktok/unlike.js +1 -0
  520. package/clis/tiktok/unsave.js +1 -0
  521. package/clis/tiktok/user.js +1 -0
  522. package/clis/toutiao/articles.js +1 -0
  523. package/clis/twitter/accept.js +1 -0
  524. package/clis/twitter/article.js +1 -0
  525. package/clis/twitter/block.js +1 -0
  526. package/clis/twitter/bookmark.js +1 -0
  527. package/clis/twitter/bookmarks.js +2 -1
  528. package/clis/twitter/delete.js +1 -0
  529. package/clis/twitter/download.js +1 -0
  530. package/clis/twitter/follow.js +1 -0
  531. package/clis/twitter/followers.js +1 -0
  532. package/clis/twitter/following.js +1 -0
  533. package/clis/twitter/hide-reply.js +1 -0
  534. package/clis/twitter/like.js +1 -0
  535. package/clis/twitter/likes.js +2 -1
  536. package/clis/twitter/list-add.js +1 -0
  537. package/clis/twitter/list-remove.js +1 -0
  538. package/clis/twitter/list-tweets.js +1 -0
  539. package/clis/twitter/lists.js +1 -0
  540. package/clis/twitter/notifications.js +1 -0
  541. package/clis/twitter/post.js +1 -0
  542. package/clis/twitter/profile.js +1 -0
  543. package/clis/twitter/reply-dm.js +1 -0
  544. package/clis/twitter/reply.js +1 -0
  545. package/clis/twitter/search.js +1 -0
  546. package/clis/twitter/thread.js +1 -0
  547. package/clis/twitter/timeline.js +1 -0
  548. package/clis/twitter/trending.js +11 -12
  549. package/clis/twitter/trending.test.js +15 -0
  550. package/clis/twitter/tweets.js +2 -1
  551. package/clis/twitter/tweets.test.js +2 -2
  552. package/clis/twitter/unblock.js +1 -0
  553. package/clis/twitter/unbookmark.js +1 -0
  554. package/clis/twitter/unfollow.js +1 -0
  555. package/clis/uiverse/code.js +1 -0
  556. package/clis/uiverse/preview.js +1 -0
  557. package/clis/v2ex/daily.js +1 -0
  558. package/clis/v2ex/hot.js +1 -0
  559. package/clis/v2ex/latest.js +1 -0
  560. package/clis/v2ex/me.js +1 -0
  561. package/clis/v2ex/member.js +1 -0
  562. package/clis/v2ex/node.js +1 -0
  563. package/clis/v2ex/nodes.js +1 -0
  564. package/clis/v2ex/notifications.js +1 -0
  565. package/clis/v2ex/replies.js +1 -0
  566. package/clis/v2ex/topic.js +1 -0
  567. package/clis/v2ex/user.js +1 -0
  568. package/clis/wanfang/search.js +1 -0
  569. package/clis/web/read.js +1 -0
  570. package/clis/weibo/comments.js +1 -0
  571. package/clis/weibo/favorites.js +1 -0
  572. package/clis/weibo/feed.js +3 -1
  573. package/clis/weibo/hot.js +1 -0
  574. package/clis/weibo/me.js +1 -0
  575. package/clis/weibo/post.js +1 -0
  576. package/clis/weibo/publish.js +1 -0
  577. package/clis/weibo/search.js +8 -2
  578. package/clis/weibo/user.js +1 -0
  579. package/clis/weixin/create-draft.js +1 -0
  580. package/clis/weixin/download.js +1 -0
  581. package/clis/weixin/drafts.js +1 -0
  582. package/clis/weread/ai-outline.js +1 -0
  583. package/clis/weread/book.js +1 -0
  584. package/clis/weread/highlights.js +1 -0
  585. package/clis/weread/notebooks.js +1 -0
  586. package/clis/weread/notes.js +1 -0
  587. package/clis/weread/ranking.js +1 -0
  588. package/clis/weread/search.js +1 -0
  589. package/clis/weread/shelf.js +1 -0
  590. package/clis/wikipedia/random.js +1 -0
  591. package/clis/wikipedia/search.js +1 -0
  592. package/clis/wikipedia/summary.js +1 -0
  593. package/clis/wikipedia/trending.js +1 -0
  594. package/clis/xianyu/chat.js +1 -0
  595. package/clis/xianyu/item.js +1 -0
  596. package/clis/xianyu/search.js +1 -0
  597. package/clis/xiaoe/catalog.js +2 -1
  598. package/clis/xiaoe/content.js +1 -0
  599. package/clis/xiaoe/courses.js +1 -0
  600. package/clis/xiaoe/detail.js +1 -0
  601. package/clis/xiaoe/play-url.js +1 -0
  602. package/clis/xiaohongshu/comments.js +1 -0
  603. package/clis/xiaohongshu/creator-note-detail.js +1 -0
  604. package/clis/xiaohongshu/creator-notes-summary.js +1 -0
  605. package/clis/xiaohongshu/creator-notes.js +1 -0
  606. package/clis/xiaohongshu/creator-profile.js +1 -0
  607. package/clis/xiaohongshu/creator-stats.js +1 -0
  608. package/clis/xiaohongshu/download.js +1 -0
  609. package/clis/xiaohongshu/feed.js +2 -1
  610. package/clis/xiaohongshu/note.js +1 -0
  611. package/clis/xiaohongshu/notifications.js +1 -0
  612. package/clis/xiaohongshu/publish.js +1 -0
  613. package/clis/xiaohongshu/search.js +1 -0
  614. package/clis/xiaohongshu/user.js +1 -0
  615. package/clis/xiaoyuzhou/download.js +1 -0
  616. package/clis/xiaoyuzhou/episode.js +1 -0
  617. package/clis/xiaoyuzhou/podcast-episodes.js +1 -0
  618. package/clis/xiaoyuzhou/podcast.js +1 -0
  619. package/clis/xiaoyuzhou/transcript.js +1 -0
  620. package/clis/xueqiu/comments.js +1 -0
  621. package/clis/xueqiu/earnings-date.js +1 -0
  622. package/clis/xueqiu/feed.js +1 -0
  623. package/clis/xueqiu/fund-holdings.js +1 -0
  624. package/clis/xueqiu/fund-snapshot.js +1 -0
  625. package/clis/xueqiu/groups.js +1 -0
  626. package/clis/xueqiu/hot-stock.js +1 -0
  627. package/clis/xueqiu/hot.js +1 -0
  628. package/clis/xueqiu/kline.js +1 -0
  629. package/clis/xueqiu/search.js +1 -0
  630. package/clis/xueqiu/stock.js +1 -0
  631. package/clis/xueqiu/watchlist.js +1 -0
  632. package/clis/yahoo-finance/quote.js +1 -0
  633. package/clis/yollomi/background.js +1 -0
  634. package/clis/yollomi/edit.js +1 -0
  635. package/clis/yollomi/face-swap.js +1 -0
  636. package/clis/yollomi/generate.js +1 -0
  637. package/clis/yollomi/models.js +1 -0
  638. package/clis/yollomi/object-remover.js +1 -0
  639. package/clis/yollomi/remove-bg.js +1 -0
  640. package/clis/yollomi/restore.js +1 -0
  641. package/clis/yollomi/try-on.js +1 -0
  642. package/clis/yollomi/upload.js +1 -0
  643. package/clis/yollomi/upscale.js +1 -0
  644. package/clis/yollomi/video.js +1 -0
  645. package/clis/youtube/channel.js +1 -0
  646. package/clis/youtube/comments.js +1 -0
  647. package/clis/youtube/feed.js +8 -7
  648. package/clis/youtube/feed.test.js +131 -0
  649. package/clis/youtube/history.js +1 -0
  650. package/clis/youtube/like.js +1 -0
  651. package/clis/youtube/playlist.js +1 -0
  652. package/clis/youtube/search.js +1 -0
  653. package/clis/youtube/subscribe.js +1 -0
  654. package/clis/youtube/subscriptions.js +1 -0
  655. package/clis/youtube/transcript.js +1 -0
  656. package/clis/youtube/unlike.js +1 -0
  657. package/clis/youtube/unsubscribe.js +1 -0
  658. package/clis/youtube/video.js +1 -0
  659. package/clis/youtube/watch-later.js +1 -0
  660. package/clis/yuanbao/ask.js +1 -0
  661. package/clis/yuanbao/new.js +1 -0
  662. package/clis/zhihu/answer.js +1 -0
  663. package/clis/zhihu/collection.js +1 -0
  664. package/clis/zhihu/collections.js +1 -0
  665. package/clis/zhihu/comment.js +1 -0
  666. package/clis/zhihu/download.js +1 -0
  667. package/clis/zhihu/favorite.js +1 -0
  668. package/clis/zhihu/follow.js +1 -0
  669. package/clis/zhihu/hot.js +1 -0
  670. package/clis/zhihu/like.js +1 -0
  671. package/clis/zhihu/question.js +1 -0
  672. package/clis/zhihu/search.js +1 -0
  673. package/clis/zlibrary/info.js +1 -0
  674. package/clis/zlibrary/search.js +1 -0
  675. package/clis/zsxq/dynamics.js +1 -0
  676. package/clis/zsxq/groups.js +1 -0
  677. package/clis/zsxq/search.js +1 -0
  678. package/clis/zsxq/topic.js +1 -0
  679. package/clis/zsxq/topics.js +1 -0
  680. package/dist/src/adapter-source.test.js +1 -1
  681. package/dist/src/browser/analyze.test.js +2 -0
  682. package/dist/src/browser/base-page.d.ts +9 -0
  683. package/dist/src/browser/base-page.js +72 -3
  684. package/dist/src/browser/base-page.test.js +42 -0
  685. package/dist/src/browser/cdp.js +6 -0
  686. package/dist/src/browser/cdp.test.js +3 -0
  687. package/dist/src/browser/page.d.ts +1 -0
  688. package/dist/src/browser/page.js +6 -0
  689. package/dist/src/browser/page.test.js +17 -0
  690. package/dist/src/browser/target-resolver.d.ts +10 -3
  691. package/dist/src/browser/target-resolver.js +16 -10
  692. package/dist/src/browser/verify-fixture.d.ts +6 -1
  693. package/dist/src/browser/verify-fixture.js +87 -0
  694. package/dist/src/browser/verify-fixture.test.js +44 -1
  695. package/dist/src/build-manifest.js +3 -0
  696. package/dist/src/build-manifest.test.js +18 -12
  697. package/dist/src/capabilityRouting.test.js +1 -1
  698. package/dist/src/cli.js +141 -5
  699. package/dist/src/cli.test.js +179 -0
  700. package/dist/src/commanderAdapter.d.ts +1 -1
  701. package/dist/src/commanderAdapter.js +17 -7
  702. package/dist/src/commanderAdapter.test.js +7 -6
  703. package/dist/src/convention-audit.d.ts +50 -0
  704. package/dist/src/convention-audit.js +546 -0
  705. package/dist/src/convention-audit.test.d.ts +1 -0
  706. package/dist/src/convention-audit.test.js +226 -0
  707. package/dist/src/discovery.js +2 -0
  708. package/dist/src/doctor.js +0 -1
  709. package/dist/src/doctor.test.js +1 -1
  710. package/dist/src/engine.test.js +10 -10
  711. package/dist/src/execution.js +1 -1
  712. package/dist/src/execution.test.js +9 -9
  713. package/dist/src/help.d.ts +15 -0
  714. package/dist/src/help.js +149 -0
  715. package/dist/src/main.js +13 -7
  716. package/dist/src/manifest-types.d.ts +2 -0
  717. package/dist/src/plugin.test.js +26 -26
  718. package/dist/src/registry.d.ts +5 -0
  719. package/dist/src/registry.js +8 -0
  720. package/dist/src/registry.test.js +27 -20
  721. package/dist/src/serialization.d.ts +4 -0
  722. package/dist/src/serialization.js +27 -1
  723. package/dist/src/serialization.test.js +24 -2
  724. package/dist/src/types.d.ts +2 -0
  725. package/package.json +4 -1
  726. package/scripts/check-listing-id-pairing.mjs +193 -0
  727. package/scripts/check-silent-column-drop.mjs +105 -0
  728. package/scripts/check-typed-error-lint.mjs +118 -0
  729. package/scripts/silent-column-drop-baseline.json +962 -0
  730. package/scripts/typed-error-lint-baseline.json +1586 -0
@@ -361,7 +361,7 @@ describe('listPlugins', () => {
361
361
  });
362
362
  it('lists installed plugins', () => {
363
363
  fs.mkdirSync(testDir, { recursive: true });
364
- fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
364
+ fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
365
365
  const plugins = listPlugins();
366
366
  const found = plugins.find(p => p.name === '__test-list-plugin__');
367
367
  expect(found).toBeDefined();
@@ -369,7 +369,7 @@ describe('listPlugins', () => {
369
369
  });
370
370
  it('includes version metadata from the lock file', () => {
371
371
  fs.mkdirSync(testDir, { recursive: true });
372
- fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
372
+ fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
373
373
  const lock = _readLockFile();
374
374
  lock['__test-list-plugin__'] = {
375
375
  source: { kind: 'git', url: 'https://github.com/user/repo.git' },
@@ -393,7 +393,7 @@ describe('listPlugins', () => {
393
393
  const localTarget = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-local-list-'));
394
394
  const linkPath = path.join(PLUGINS_DIR, '__test-list-plugin__');
395
395
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
396
- fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello" })');
396
+ fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
397
397
  try {
398
398
  fs.unlinkSync(linkPath);
399
399
  }
@@ -435,13 +435,13 @@ describe('uninstallPlugin', () => {
435
435
  });
436
436
  it('removes plugin directory', () => {
437
437
  fs.mkdirSync(testDir, { recursive: true });
438
- fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test" })');
438
+ fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test", access: "read" })');
439
439
  uninstallPlugin('__test-uninstall__');
440
440
  expect(fs.existsSync(testDir)).toBe(false);
441
441
  });
442
442
  it('removes lock entry on uninstall', () => {
443
443
  fs.mkdirSync(testDir, { recursive: true });
444
- fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test" })');
444
+ fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test", access: "read" })');
445
445
  const lock = _readLockFile();
446
446
  lock['__test-uninstall__'] = {
447
447
  source: { kind: 'git', url: 'https://github.com/user/repo.git' },
@@ -464,7 +464,7 @@ describe('updatePlugin', () => {
464
464
  const localTarget = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-local-update-'));
465
465
  const linkPath = path.join(PLUGINS_DIR, '__test-local-update__');
466
466
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
467
- fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello" })');
467
+ fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
468
468
  fs.symlinkSync(localTarget, linkPath, 'dir');
469
469
  const lock = _readLockFile();
470
470
  lock['__test-local-update__'] = {
@@ -540,7 +540,7 @@ describe('postInstallMonorepoLifecycle', () => {
540
540
  private: true,
541
541
  workspaces: ['packages/*'],
542
542
  }));
543
- fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
543
+ fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
544
544
  });
545
545
  afterEach(() => {
546
546
  fs.rmSync(repoDir, { recursive: true, force: true });
@@ -575,9 +575,9 @@ describe('updateAllPlugins', () => {
575
575
  fs.mkdirSync(testDirA, { recursive: true });
576
576
  fs.mkdirSync(testDirB, { recursive: true });
577
577
  fs.mkdirSync(testDirC, { recursive: true });
578
- fs.writeFileSync(path.join(testDirA, 'cmd.js'), 'cli({ site: "a", name: "cmd" })');
579
- fs.writeFileSync(path.join(testDirB, 'cmd.js'), 'cli({ site: "b", name: "cmd" })');
580
- fs.writeFileSync(path.join(testDirC, 'cmd.js'), 'cli({ site: "c", name: "cmd" })');
578
+ fs.writeFileSync(path.join(testDirA, 'cmd.js'), 'cli({ site: "a", name: "cmd", access: "read" })');
579
+ fs.writeFileSync(path.join(testDirB, 'cmd.js'), 'cli({ site: "b", name: "cmd", access: "read" })');
580
+ fs.writeFileSync(path.join(testDirC, 'cmd.js'), 'cli({ site: "c", name: "cmd", access: "read" })');
581
581
  const lock = _readLockFile();
582
582
  lock['plugin-a'] = {
583
583
  source: { kind: 'git', url: 'https://github.com/user/plugin-a.git' },
@@ -622,7 +622,7 @@ describe('updateAllPlugins', () => {
622
622
  const cloneUrl = String(args[3]);
623
623
  const cloneDir = String(args[4]);
624
624
  fs.mkdirSync(cloneDir, { recursive: true });
625
- fs.writeFileSync(path.join(cloneDir, 'cmd.js'), 'cli({ site: "test", name: "hello" })');
625
+ fs.writeFileSync(path.join(cloneDir, 'cmd.js'), 'cli({ site: "test", name: "hello", access: "read" })');
626
626
  if (cloneUrl.includes('plugin-b')) {
627
627
  fs.writeFileSync(path.join(cloneDir, 'package.json'), JSON.stringify({ name: 'plugin-b' }));
628
628
  }
@@ -709,7 +709,7 @@ describe('monorepo uninstall with symlink', () => {
709
709
  monoDir = path.join(_getMonoreposDir(), '__test-mono__');
710
710
  const subDir = path.join(monoDir, 'packages', 'sub');
711
711
  fs.mkdirSync(subDir, { recursive: true });
712
- fs.writeFileSync(path.join(subDir, 'cmd.js'), 'cli({ site: "test", name: "cmd" })');
712
+ fs.writeFileSync(path.join(subDir, 'cmd.js'), 'cli({ site: "test", name: "cmd", access: "read" })');
713
713
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
714
714
  fs.symlinkSync(subDir, pluginDir, 'dir');
715
715
  const lock = _readLockFile();
@@ -776,7 +776,7 @@ describe('listPlugins with monorepo metadata', () => {
776
776
  const testLink = path.join(PLUGINS_DIR, '__test-mono-list__');
777
777
  beforeEach(() => {
778
778
  fs.mkdirSync(testSymlinkTarget, { recursive: true });
779
- fs.writeFileSync(path.join(testSymlinkTarget, 'hello.js'), 'cli({ site: "test", name: "hello" })');
779
+ fs.writeFileSync(path.join(testSymlinkTarget, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
780
780
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
781
781
  try {
782
782
  fs.unlinkSync(testLink);
@@ -823,7 +823,7 @@ describe('installLocalPlugin', () => {
823
823
  const pluginName = '__test-local-plugin__';
824
824
  beforeEach(() => {
825
825
  tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-local-install-'));
826
- fs.writeFileSync(path.join(tmpDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
826
+ fs.writeFileSync(path.join(tmpDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
827
827
  });
828
828
  afterEach(() => {
829
829
  const linkPath = path.join(PLUGINS_DIR, pluginName);
@@ -963,7 +963,7 @@ describe('installPlugin transactional staging', () => {
963
963
  if (cmd === 'git' && Array.isArray(args) && args[0] === 'clone') {
964
964
  const cloneDir = String(args[args.length - 1]);
965
965
  fs.mkdirSync(cloneDir, { recursive: true });
966
- fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
966
+ fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
967
967
  fs.writeFileSync(path.join(cloneDir, 'package.json'), JSON.stringify({ name: standaloneName }));
968
968
  return '';
969
969
  }
@@ -994,7 +994,7 @@ describe('installPlugin transactional staging', () => {
994
994
  alpha: { path: 'packages/alpha' },
995
995
  },
996
996
  }));
997
- fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
997
+ fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
998
998
  return '';
999
999
  }
1000
1000
  if (cmd === 'npm' && Array.isArray(args) && args[0] === 'install') {
@@ -1051,7 +1051,7 @@ describe('installPlugin with existing monorepo', () => {
1051
1051
  [pluginName]: { path: `packages/${pluginName}` },
1052
1052
  },
1053
1053
  }));
1054
- fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
1054
+ fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
1055
1055
  mockExecFileSync.mockImplementation((cmd, args) => {
1056
1056
  if (cmd === 'git' && Array.isArray(args) && args[0] === 'clone') {
1057
1057
  const cloneDir = String(args[4]);
@@ -1110,7 +1110,7 @@ describe('updatePlugin transactional staging', () => {
1110
1110
  });
1111
1111
  it('keeps the existing standalone plugin when staged update preparation fails', () => {
1112
1112
  fs.mkdirSync(standaloneDir, { recursive: true });
1113
- fs.writeFileSync(path.join(standaloneDir, 'old.js'), 'cli({ site: "old", name: "old" })');
1113
+ fs.writeFileSync(path.join(standaloneDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
1114
1114
  const lock = _readLockFile();
1115
1115
  lock[standaloneName] = {
1116
1116
  source: {
@@ -1125,7 +1125,7 @@ describe('updatePlugin transactional staging', () => {
1125
1125
  if (cmd === 'git' && Array.isArray(args) && args[0] === 'clone') {
1126
1126
  const cloneDir = String(args[4]);
1127
1127
  fs.mkdirSync(cloneDir, { recursive: true });
1128
- fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
1128
+ fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
1129
1129
  fs.writeFileSync(path.join(cloneDir, 'package.json'), JSON.stringify({ name: standaloneName }));
1130
1130
  return '';
1131
1131
  }
@@ -1145,7 +1145,7 @@ describe('updatePlugin transactional staging', () => {
1145
1145
  it('keeps the existing monorepo repo and link when staged update preparation fails', () => {
1146
1146
  const subDir = path.join(monorepoRepoDir, 'packages', monorepoPluginName);
1147
1147
  fs.mkdirSync(subDir, { recursive: true });
1148
- fs.writeFileSync(path.join(subDir, 'old.js'), 'cli({ site: "old", name: "old" })');
1148
+ fs.writeFileSync(path.join(subDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
1149
1149
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
1150
1150
  fs.symlinkSync(subDir, monorepoLink, 'dir');
1151
1151
  const lock = _readLockFile();
@@ -1174,7 +1174,7 @@ describe('updatePlugin transactional staging', () => {
1174
1174
  [monorepoPluginName]: { path: `packages/${monorepoPluginName}` },
1175
1175
  },
1176
1176
  }));
1177
- fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
1177
+ fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
1178
1178
  return '';
1179
1179
  }
1180
1180
  if (cmd === 'npm' && Array.isArray(args) && args[0] === 'install') {
@@ -1194,7 +1194,7 @@ describe('updatePlugin transactional staging', () => {
1194
1194
  it('relinks monorepo plugins when the updated manifest moves their subPath', () => {
1195
1195
  const oldSubDir = path.join(monorepoRepoDir, 'packages', 'old-alpha');
1196
1196
  fs.mkdirSync(oldSubDir, { recursive: true });
1197
- fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old" })');
1197
+ fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
1198
1198
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
1199
1199
  fs.symlinkSync(oldSubDir, monorepoLink, 'dir');
1200
1200
  const lock = _readLockFile();
@@ -1219,7 +1219,7 @@ describe('updatePlugin transactional staging', () => {
1219
1219
  [monorepoPluginName]: { path: 'packages/moved-alpha' },
1220
1220
  },
1221
1221
  }));
1222
- fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
1222
+ fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
1223
1223
  return '';
1224
1224
  }
1225
1225
  if (cmd === 'git' && Array.isArray(args) && args[0] === 'rev-parse' && args[1] === 'HEAD') {
@@ -1238,7 +1238,7 @@ describe('updatePlugin transactional staging', () => {
1238
1238
  it('rejects monorepo updates whose manifest path escapes the repo root', () => {
1239
1239
  const oldSubDir = path.join(monorepoRepoDir, 'packages', 'old-alpha');
1240
1240
  fs.mkdirSync(oldSubDir, { recursive: true });
1241
- fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old" })');
1241
+ fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
1242
1242
  fs.mkdirSync(PLUGINS_DIR, { recursive: true });
1243
1243
  fs.symlinkSync(oldSubDir, monorepoLink, 'dir');
1244
1244
  const lock = _readLockFile();
@@ -1279,7 +1279,7 @@ describe('updatePlugin transactional staging', () => {
1279
1279
  it('rolls back the monorepo repo swap when relinking fails', () => {
1280
1280
  const oldSubDir = path.join(monorepoRepoDir, 'packages', 'old-alpha');
1281
1281
  fs.mkdirSync(oldSubDir, { recursive: true });
1282
- fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old" })');
1282
+ fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
1283
1283
  fs.mkdirSync(monorepoLink, { recursive: true });
1284
1284
  fs.writeFileSync(path.join(monorepoLink, 'blocker.txt'), 'not a symlink');
1285
1285
  const lock = _readLockFile();
@@ -1304,7 +1304,7 @@ describe('updatePlugin transactional staging', () => {
1304
1304
  [monorepoPluginName]: { path: 'packages/moved-alpha' },
1305
1305
  },
1306
1306
  }));
1307
- fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
1307
+ fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
1308
1308
  return '';
1309
1309
  }
1310
1310
  if (cmd === 'git' && Array.isArray(args) && args[0] === 'rev-parse' && args[1] === 'HEAD') {
@@ -27,11 +27,15 @@ export interface RequiredEnv {
27
27
  export type CommandArgs = Record<string, any>;
28
28
  export type BrowserCommandFunc = (page: IPage, kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
29
29
  export type NonBrowserCommandFunc = (kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
30
+ export type CommandAccess = 'read' | 'write';
30
31
  interface BaseCliCommand {
31
32
  site: string;
32
33
  name: string;
33
34
  aliases?: string[];
34
35
  description: string;
36
+ access: CommandAccess;
37
+ /** Canonical invocation shown in agent-facing help. Generated when omitted. */
38
+ example?: string;
35
39
  domain?: string;
36
40
  strategy?: Strategy;
37
41
  args: Arg[];
@@ -89,6 +93,7 @@ export type InternalCliCommand = CliCommand & {
89
93
  type RequiredCliOptions = {
90
94
  site: string;
91
95
  name: string;
96
+ access: CommandAccess;
92
97
  description?: string;
93
98
  args?: Arg[];
94
99
  };
@@ -17,6 +17,7 @@ export function cli(opts) {
17
17
  name: opts.name,
18
18
  aliases: opts.aliases,
19
19
  description: opts.description ?? '',
20
+ access: opts.access,
20
21
  domain: opts.domain,
21
22
  strategy: opts.strategy,
22
23
  browser: opts.browser,
@@ -58,6 +59,7 @@ export function strategyLabel(cmd) {
58
59
  * 2. Derived from strategy + domain (the defaults below)
59
60
  */
60
61
  function normalizeCommand(cmd) {
62
+ assertCommandAccess(cmd);
61
63
  const strategy = cmd.strategy ?? (cmd.browser === false ? Strategy.PUBLIC : Strategy.COOKIE);
62
64
  const browser = cmd.browser ?? (strategy !== Strategy.PUBLIC && strategy !== Strategy.LOCAL);
63
65
  let navigateBefore = cmd.navigateBefore;
@@ -76,6 +78,12 @@ function normalizeCommand(cmd) {
76
78
  ? { ...cmd, strategy, browser: true, navigateBefore }
77
79
  : { ...cmd, strategy, browser: false, navigateBefore };
78
80
  }
81
+ function assertCommandAccess(cmd) {
82
+ if (cmd.access === 'read' || cmd.access === 'write')
83
+ return;
84
+ const key = `${cmd.site}/${cmd.name}`;
85
+ throw new Error(`Command ${key} must declare access: 'read' | 'write'`);
86
+ }
79
87
  export function registerCommand(cmd) {
80
88
  const normalized = normalizeCommand(cmd);
81
89
  const canonicalKey = fullName(normalized);
@@ -7,13 +7,14 @@ describe('cli() registration', () => {
7
7
  it('registers a command and returns it', () => {
8
8
  const cmd = cli({
9
9
  site: 'test-registry',
10
- name: 'hello',
10
+ name: 'hello', access: 'read',
11
11
  description: 'A test command',
12
12
  strategy: Strategy.PUBLIC,
13
13
  browser: false,
14
14
  });
15
15
  expect(cmd.site).toBe('test-registry');
16
16
  expect(cmd.name).toBe('hello');
17
+ expect(cmd.access).toBe('read');
17
18
  expect(cmd.strategy).toBe(Strategy.PUBLIC);
18
19
  expect(cmd.browser).toBe(false);
19
20
  expect(cmd.args).toEqual([]);
@@ -21,7 +22,7 @@ describe('cli() registration', () => {
21
22
  it('puts registered command in the registry', () => {
22
23
  cli({
23
24
  site: 'test-registry',
24
- name: 'registered',
25
+ name: 'registered', access: 'read',
25
26
  description: 'test',
26
27
  });
27
28
  const registry = getRegistry();
@@ -30,7 +31,7 @@ describe('cli() registration', () => {
30
31
  it('defaults strategy to COOKIE when browser is true', () => {
31
32
  const cmd = cli({
32
33
  site: 'test-registry',
33
- name: 'default-strategy',
34
+ name: 'default-strategy', access: 'read',
34
35
  });
35
36
  expect(cmd.strategy).toBe(Strategy.COOKIE);
36
37
  expect(cmd.browser).toBe(true);
@@ -38,7 +39,7 @@ describe('cli() registration', () => {
38
39
  it('defaults strategy to PUBLIC when browser is false', () => {
39
40
  const cmd = cli({
40
41
  site: 'test-registry',
41
- name: 'no-browser',
42
+ name: 'no-browser', access: 'read',
42
43
  browser: false,
43
44
  });
44
45
  expect(cmd.strategy).toBe(Strategy.PUBLIC);
@@ -46,7 +47,7 @@ describe('cli() registration', () => {
46
47
  it('preserves LOCAL strategy on registration', () => {
47
48
  const cmd = cli({
48
49
  site: 'test-registry',
49
- name: 'local-strategy',
50
+ name: 'local-strategy', access: 'read',
50
51
  description: 'reads local credentials',
51
52
  strategy: Strategy.LOCAL,
52
53
  browser: false,
@@ -55,15 +56,15 @@ describe('cli() registration', () => {
55
56
  expect(cmd.browser).toBe(false);
56
57
  });
57
58
  it('overwrites existing command on re-registration', () => {
58
- cli({ site: 'test-registry', name: 'overwrite', description: 'v1' });
59
- cli({ site: 'test-registry', name: 'overwrite', description: 'v2' });
59
+ cli({ site: 'test-registry', name: 'overwrite', access: 'read', description: 'v1' });
60
+ cli({ site: 'test-registry', name: 'overwrite', access: 'read', description: 'v2' });
60
61
  const reg = getRegistry();
61
62
  expect(reg.get('test-registry/overwrite')?.description).toBe('v2');
62
63
  });
63
64
  it('registers aliases as alternate registry keys for the same command', () => {
64
65
  const cmd = cli({
65
66
  site: 'test-registry',
66
- name: 'canonical',
67
+ name: 'canonical', access: 'read',
67
68
  description: 'test aliases',
68
69
  aliases: ['compat', 'legacy-name'],
69
70
  });
@@ -76,18 +77,24 @@ describe('cli() registration', () => {
76
77
  it('preserves defaultFormat on the registered command', () => {
77
78
  const cmd = cli({
78
79
  site: 'test-registry',
79
- name: 'plain-default',
80
+ name: 'plain-default', access: 'read',
80
81
  description: 'prefers plain output',
81
82
  defaultFormat: 'plain',
82
83
  });
83
84
  expect(cmd.defaultFormat).toBe('plain');
84
85
  expect(getRegistry().get('test-registry/plain-default')?.defaultFormat).toBe('plain');
85
86
  });
87
+ it('rejects commands without explicit access metadata', () => {
88
+ expect(() => cli({
89
+ site: 'test-registry',
90
+ name: 'missing-access',
91
+ })).toThrow("Command test-registry/missing-access must declare access: 'read' | 'write'");
92
+ });
86
93
  });
87
94
  describe('fullName', () => {
88
95
  it('returns site/name', () => {
89
96
  const cmd = {
90
- site: 'bilibili', name: 'hot', description: '', args: [],
97
+ site: 'bilibili', name: 'hot', access: 'read', description: '', args: [],
91
98
  };
92
99
  expect(fullName(cmd)).toBe('bilibili/hot');
93
100
  });
@@ -95,14 +102,14 @@ describe('fullName', () => {
95
102
  describe('strategyLabel', () => {
96
103
  it('returns strategy string', () => {
97
104
  const cmd = {
98
- site: 'test', name: 'test', description: '', args: [],
105
+ site: 'test', name: 'test', access: 'read', description: '', args: [],
99
106
  strategy: Strategy.INTERCEPT,
100
107
  };
101
108
  expect(strategyLabel(cmd)).toBe('intercept');
102
109
  });
103
110
  it('returns public when no strategy set', () => {
104
111
  const cmd = {
105
- site: 'test', name: 'test', description: '', args: [],
112
+ site: 'test', name: 'test', access: 'read', description: '', args: [],
106
113
  };
107
114
  expect(strategyLabel(cmd)).toBe('public');
108
115
  });
@@ -111,7 +118,7 @@ describe('registerCommand', () => {
111
118
  it('registers a pre-built command', () => {
112
119
  const cmd = {
113
120
  site: 'test-registry',
114
- name: 'direct-reg',
121
+ name: 'direct-reg', access: 'read',
115
122
  description: 'directly registered',
116
123
  args: [],
117
124
  strategy: Strategy.HEADER,
@@ -125,7 +132,7 @@ describe('registerCommand', () => {
125
132
  describe('normalizeCommand (via registerCommand)', () => {
126
133
  it('COOKIE + domain → navigateBefore is the domain URL', () => {
127
134
  registerCommand({
128
- site: 'test-norm', name: 'cookie-domain', description: '', args: [],
135
+ site: 'test-norm', name: 'cookie-domain', access: 'read', description: '', args: [],
129
136
  strategy: Strategy.COOKIE, domain: 'x.com',
130
137
  });
131
138
  const cmd = getRegistry().get('test-norm/cookie-domain');
@@ -134,7 +141,7 @@ describe('normalizeCommand (via registerCommand)', () => {
134
141
  });
135
142
  it('COOKIE without domain → navigateBefore is true (auth context, no URL)', () => {
136
143
  registerCommand({
137
- site: 'test-norm', name: 'cookie-nodomain', description: '', args: [],
144
+ site: 'test-norm', name: 'cookie-nodomain', access: 'read', description: '', args: [],
138
145
  strategy: Strategy.COOKIE,
139
146
  });
140
147
  const cmd = getRegistry().get('test-norm/cookie-nodomain');
@@ -143,7 +150,7 @@ describe('normalizeCommand (via registerCommand)', () => {
143
150
  });
144
151
  it('INTERCEPT → navigateBefore is true (auth context)', () => {
145
152
  registerCommand({
146
- site: 'test-norm', name: 'intercept', description: '', args: [],
153
+ site: 'test-norm', name: 'intercept', access: 'read', description: '', args: [],
147
154
  strategy: Strategy.INTERCEPT, domain: 'example.com',
148
155
  });
149
156
  const cmd = getRegistry().get('test-norm/intercept');
@@ -152,7 +159,7 @@ describe('normalizeCommand (via registerCommand)', () => {
152
159
  });
153
160
  it('PUBLIC → browser false, navigateBefore undefined', () => {
154
161
  registerCommand({
155
- site: 'test-norm', name: 'public', description: '', args: [],
162
+ site: 'test-norm', name: 'public', access: 'read', description: '', args: [],
156
163
  strategy: Strategy.PUBLIC,
157
164
  });
158
165
  const cmd = getRegistry().get('test-norm/public');
@@ -161,7 +168,7 @@ describe('normalizeCommand (via registerCommand)', () => {
161
168
  });
162
169
  it('LOCAL → browser false, navigateBefore undefined', () => {
163
170
  registerCommand({
164
- site: 'test-norm', name: 'local', description: '', args: [],
171
+ site: 'test-norm', name: 'local', access: 'read', description: '', args: [],
165
172
  strategy: Strategy.LOCAL,
166
173
  });
167
174
  const cmd = getRegistry().get('test-norm/local');
@@ -172,7 +179,7 @@ describe('normalizeCommand (via registerCommand)', () => {
172
179
  });
173
180
  it('explicit navigateBefore: false overrides COOKIE + domain', () => {
174
181
  registerCommand({
175
- site: 'test-norm', name: 'cookie-override', description: '', args: [],
182
+ site: 'test-norm', name: 'cookie-override', access: 'read', description: '', args: [],
176
183
  strategy: Strategy.COOKIE, domain: 'amazon.com', navigateBefore: false,
177
184
  });
178
185
  const cmd = getRegistry().get('test-norm/cookie-override');
@@ -181,7 +188,7 @@ describe('normalizeCommand (via registerCommand)', () => {
181
188
  });
182
189
  it('explicit navigateBefore URL overrides strategy default', () => {
183
190
  registerCommand({
184
- site: 'test-norm', name: 'explicit-url', description: '', args: [],
191
+ site: 'test-norm', name: 'explicit-url', access: 'read', description: '', args: [],
185
192
  strategy: Strategy.COOKIE, domain: 'x.com',
186
193
  navigateBefore: 'https://x.com/explore',
187
194
  });
@@ -24,15 +24,19 @@ export declare function serializeCommand(cmd: CliCommand): {
24
24
  name: string;
25
25
  aliases: string[];
26
26
  description: string;
27
+ access: import("./registry.js").CommandAccess;
27
28
  strategy: string;
28
29
  browser: boolean;
29
30
  args: SerializedArg[];
30
31
  columns: string[];
31
32
  domain: string | null;
33
+ example: string;
32
34
  deprecated: string | boolean | null;
33
35
  replacedBy: string | null;
34
36
  };
35
37
  /** Human-readable arg summary: `<required> [optional]` style. */
36
38
  export declare function formatArgSummary(args: Arg[]): string;
39
+ /** Agent-facing canonical invocation. Adapter authors may override with `example`. */
40
+ export declare function formatCommandExample(cmd: CliCommand): string;
37
41
  /** Generate the --help appendix showing registry metadata not exposed by Commander. */
38
42
  export declare function formatRegistryHelpText(cmd: CliCommand): string;
@@ -26,11 +26,13 @@ export function serializeCommand(cmd) {
26
26
  name: cmd.name,
27
27
  aliases: cmd.aliases ?? [],
28
28
  description: cmd.description,
29
+ access: cmd.access,
29
30
  strategy: strategyLabel(cmd),
30
31
  browser: !!cmd.browser,
31
32
  args: cmd.args.map(serializeArg),
32
33
  columns: cmd.columns ?? [],
33
34
  domain: cmd.domain ?? null,
35
+ example: formatCommandExample(cmd),
34
36
  deprecated: cmd.deprecated ?? null,
35
37
  replacedBy: cmd.replacedBy ?? null,
36
38
  };
@@ -51,6 +53,29 @@ function summarizeChoices(choices) {
51
53
  return choices.join(', ');
52
54
  return `${choices.slice(0, 4).join(', ')}, ... (+${choices.length - 4} more)`;
53
55
  }
56
+ function formatValuePlaceholder(name) {
57
+ return `<${name}>`;
58
+ }
59
+ /** Agent-facing canonical invocation. Adapter authors may override with `example`. */
60
+ export function formatCommandExample(cmd) {
61
+ if (cmd.example?.trim())
62
+ return cmd.example.trim();
63
+ const parts = ['opencli', cmd.site, cmd.name];
64
+ for (const arg of cmd.args) {
65
+ if (arg.positional && arg.required) {
66
+ parts.push(formatValuePlaceholder(arg.name));
67
+ }
68
+ }
69
+ for (const arg of cmd.args) {
70
+ if (arg.positional || !arg.required)
71
+ continue;
72
+ parts.push(`--${arg.name}`);
73
+ if (arg.type !== 'bool' && arg.type !== 'boolean')
74
+ parts.push(formatValuePlaceholder(arg.name));
75
+ }
76
+ parts.push('-f', 'yaml');
77
+ return parts.join(' ');
78
+ }
54
79
  /** Generate the --help appendix showing registry metadata not exposed by Commander. */
55
80
  export function formatRegistryHelpText(cmd) {
56
81
  const lines = [];
@@ -61,7 +86,7 @@ export function formatRegistryHelpText(cmd) {
61
86
  lines.push(` ${prefix}: ${summarizeChoices(a.choices)}${def}`);
62
87
  }
63
88
  const meta = [];
64
- meta.push(`Strategy: ${strategyLabel(cmd)}`);
89
+ meta.push(`Access: ${cmd.access}`);
65
90
  meta.push(`Browser: ${cmd.browser ? 'yes' : 'no'}`);
66
91
  if (cmd.domain)
67
92
  meta.push(`Domain: ${cmd.domain}`);
@@ -72,6 +97,7 @@ export function formatRegistryHelpText(cmd) {
72
97
  if (cmd.aliases?.length)
73
98
  meta.push(`Aliases: ${cmd.aliases.join(', ')}`);
74
99
  lines.push(meta.join(' | '));
100
+ lines.push(`Example: ${formatCommandExample(cmd)}`);
75
101
  if (cmd.columns?.length)
76
102
  lines.push(`Output columns: ${cmd.columns.join(', ')}`);
77
103
  return '\n' + lines.join('\n') + '\n';
@@ -1,11 +1,11 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { Strategy } from './registry.js';
3
- import { formatRegistryHelpText, serializeCommand } from './serialization.js';
3
+ import { formatCommandExample, formatRegistryHelpText, serializeCommand } from './serialization.js';
4
4
  describe('formatRegistryHelpText', () => {
5
5
  it('summarizes long choices lists so help text stays readable', () => {
6
6
  const cmd = {
7
7
  site: 'demo',
8
- name: 'dynamic',
8
+ name: 'dynamic', access: 'read',
9
9
  description: 'Demo command',
10
10
  strategy: Strategy.PUBLIC,
11
11
  browser: false,
@@ -24,6 +24,7 @@ describe('formatRegistryHelpText', () => {
24
24
  const cmd = {
25
25
  site: 'demo',
26
26
  name: 'get',
27
+ access: 'read',
27
28
  aliases: ['metadata'],
28
29
  description: 'Demo command',
29
30
  strategy: Strategy.COOKIE,
@@ -32,8 +33,29 @@ describe('formatRegistryHelpText', () => {
32
33
  };
33
34
  expect(serializeCommand(cmd)).toMatchObject({
34
35
  command: 'demo/get',
36
+ access: 'read',
35
37
  aliases: ['metadata'],
36
38
  });
37
39
  expect(formatRegistryHelpText(cmd)).toContain('Aliases: metadata');
38
40
  });
41
+ it('surfaces access and canonical examples instead of strategy as primary help metadata', () => {
42
+ const cmd = {
43
+ site: 'bilibili',
44
+ name: 'hot',
45
+ access: 'read',
46
+ description: 'Bilibili hot videos',
47
+ strategy: Strategy.COOKIE,
48
+ browser: true,
49
+ args: [],
50
+ };
51
+ expect(formatCommandExample(cmd)).toBe('opencli bilibili hot -f yaml');
52
+ expect(serializeCommand(cmd)).toMatchObject({
53
+ command: 'bilibili/hot',
54
+ access: 'read',
55
+ example: 'opencli bilibili hot -f yaml',
56
+ });
57
+ expect(formatRegistryHelpText(cmd)).toContain('Access: read');
58
+ expect(formatRegistryHelpText(cmd)).toContain('Example: opencli bilibili hot -f yaml');
59
+ expect(formatRegistryHelpText(cmd)).not.toContain('Strategy:');
60
+ });
39
61
  });
@@ -130,6 +130,8 @@ export interface IPage {
130
130
  setActivePage?(page?: string): void;
131
131
  /** Send a raw CDP command via chrome.debugger passthrough. */
132
132
  cdp?(method: string, params?: Record<string, unknown>): Promise<unknown>;
133
+ /** Accept or dismiss the currently open JavaScript alert/confirm/prompt dialog. */
134
+ handleJavaScriptDialog?(accept: boolean, promptText?: string): Promise<void>;
133
135
  /** List cross-origin iframe targets in snapshot order. */
134
136
  frames?(): Promise<Array<{
135
137
  index: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackwener/opencli",
3
- "version": "1.7.11",
3
+ "version": "1.7.12",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -57,6 +57,9 @@
57
57
  "test:adapter": "vitest run --project adapter",
58
58
  "test:all": "vitest run",
59
59
  "test:e2e": "vitest run --project e2e",
60
+ "advise:listing-id-pairing": "node scripts/check-listing-id-pairing.mjs",
61
+ "check:silent-column-drop": "node scripts/check-silent-column-drop.mjs",
62
+ "check:typed-error-lint": "node scripts/check-typed-error-lint.mjs",
60
63
  "docs:dev": "vitepress dev docs",
61
64
  "docs:build": "vitepress build docs",
62
65
  "docs:preview": "vitepress preview docs"