publishport-opencli 1.0.20 → 1.0.21

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 (1041) hide show
  1. package/clis/12306/me.js +2 -2
  2. package/clis/12306/orders.js +3 -3
  3. package/clis/12306/passengers.js +3 -3
  4. package/clis/12306/price.js +1 -1
  5. package/clis/12306/stations.js +1 -1
  6. package/clis/12306/train.js +1 -1
  7. package/clis/12306/trains.js +1 -1
  8. package/clis/12306/utils.js +1 -1
  9. package/clis/1688/download.js +1 -1
  10. package/clis/1688/item.js +4 -4
  11. package/clis/1688/search.js +4 -4
  12. package/clis/1688/store.js +4 -4
  13. package/clis/1point3acres/forum.js +1 -1
  14. package/clis/1point3acres/forums.js +1 -1
  15. package/clis/1point3acres/notifications.js +1 -1
  16. package/clis/1point3acres/search.js +1 -1
  17. package/clis/1point3acres/thread.js +2 -2
  18. package/clis/1point3acres/user.js +1 -1
  19. package/clis/1point3acres/utils.js +2 -2
  20. package/clis/36kr/article.js +2 -2
  21. package/clis/36kr/hot.js +2 -2
  22. package/clis/36kr/news.js +1 -1
  23. package/clis/36kr/search.js +2 -2
  24. package/clis/51job/company.js +2 -2
  25. package/clis/51job/detail.js +2 -2
  26. package/clis/51job/hot.js +1 -1
  27. package/clis/51job/search.js +1 -1
  28. package/clis/51job/utils.js +7 -7
  29. package/clis/_atlassian/shared.js +9 -9
  30. package/clis/_shared/article/auth.js +4 -4
  31. package/clis/_shared/article/douban-md2draft.js +4 -4
  32. package/clis/_shared/article/format.js +1 -1
  33. package/clis/_shared/article/images.js +7 -7
  34. package/clis/_shared/article/login.js +1 -1
  35. package/clis/_shared/article/publish.js +11 -11
  36. package/clis/_shared/common.js +1 -1
  37. package/clis/_shared/content-guard.js +1 -1
  38. package/clis/_shared/desktop-commands.js +1 -1
  39. package/clis/_shared/file-inject.js +12 -12
  40. package/clis/_shared/self-hosted-sites.js +2 -2
  41. package/clis/_shared/site-auth.js +1 -1
  42. package/clis/_shared/token-auth.js +2 -2
  43. package/clis/_shared/video-publish.js +9 -9
  44. package/clis/amazon/offer.js +3 -3
  45. package/clis/amazon/product.js +5 -5
  46. package/clis/amazon/shared.js +6 -6
  47. package/clis/antigravity/_actions.js +13 -13
  48. package/clis/antigravity/audit-extras.js +10 -10
  49. package/clis/antigravity/delete.js +1 -1
  50. package/clis/antigravity/model.js +6 -6
  51. package/clis/antigravity/new.js +2 -2
  52. package/clis/antigravity/read.js +2 -2
  53. package/clis/antigravity/rename.js +1 -1
  54. package/clis/antigravity/send.js +3 -3
  55. package/clis/antigravity/serve.js +17 -17
  56. package/clis/antigravity/storage.js +6 -6
  57. package/clis/antigravity/watch.js +2 -2
  58. package/clis/apple-podcasts/episodes.js +1 -1
  59. package/clis/apple-podcasts/top.js +1 -1
  60. package/clis/apple-podcasts/utils.js +1 -1
  61. package/clis/archive/item.js +1 -1
  62. package/clis/archive/search.js +1 -1
  63. package/clis/archive/snapshots.js +1 -1
  64. package/clis/archive/wayback.js +1 -1
  65. package/clis/arxiv/author.js +1 -1
  66. package/clis/arxiv/utils.js +1 -1
  67. package/clis/autohome/brand.js +1 -1
  68. package/clis/autohome/score.js +1 -1
  69. package/clis/autohome/utils.js +1 -1
  70. package/clis/baijiahao/article.js +1 -1
  71. package/clis/baijiahao/lists.js +1 -1
  72. package/clis/baijiahao/login.js +1 -1
  73. package/clis/baijiahao/publish.js +9 -9
  74. package/clis/baijiahao/stats.js +1 -1
  75. package/clis/baijiahao/whoami.js +1 -1
  76. package/clis/band/bands.js +2 -2
  77. package/clis/band/mentions.js +2 -2
  78. package/clis/band/post.js +4 -4
  79. package/clis/band/posts.js +3 -3
  80. package/clis/barchart/flow.js +3 -3
  81. package/clis/barchart/greeks.js +2 -2
  82. package/clis/barchart/quote.js +3 -3
  83. package/clis/bbc/news.js +1 -1
  84. package/clis/bbc/topic.js +1 -1
  85. package/clis/bbc/utils.js +1 -1
  86. package/clis/bilibili/article.js +1 -1
  87. package/clis/bilibili/categories.js +1 -1
  88. package/clis/bilibili/coin.js +1 -1
  89. package/clis/bilibili/comment-del.js +1 -1
  90. package/clis/bilibili/comment-like.js +1 -1
  91. package/clis/bilibili/comment.js +1 -1
  92. package/clis/bilibili/comments.js +1 -1
  93. package/clis/bilibili/dm-list.js +1 -1
  94. package/clis/bilibili/dm-read.js +1 -1
  95. package/clis/bilibili/dm-send.js +1 -1
  96. package/clis/bilibili/download.js +2 -2
  97. package/clis/bilibili/drafts.js +1 -1
  98. package/clis/bilibili/dynamic-post.js +3 -3
  99. package/clis/bilibili/favorite-add.js +1 -1
  100. package/clis/bilibili/favorite.js +1 -1
  101. package/clis/bilibili/feed.js +2 -2
  102. package/clis/bilibili/follow.js +1 -1
  103. package/clis/bilibili/following.js +1 -1
  104. package/clis/bilibili/like.js +1 -1
  105. package/clis/bilibili/partitions.js +1 -1
  106. package/clis/bilibili/stats.js +1 -1
  107. package/clis/bilibili/subtitle.js +3 -3
  108. package/clis/bilibili/summary.js +1 -1
  109. package/clis/bilibili/topics.js +1 -1
  110. package/clis/bilibili/unfollow.js +1 -1
  111. package/clis/bilibili/upload.js +1 -1
  112. package/clis/bilibili/utils.js +10 -10
  113. package/clis/bilibili/video-drafts.js +1 -1
  114. package/clis/bilibili/video.js +1 -1
  115. package/clis/bloomberg/businessweek.js +4 -4
  116. package/clis/bloomberg/news.js +2 -2
  117. package/clis/bloomberg/utils.js +13 -13
  118. package/clis/bluesky/post.js +1 -1
  119. package/clis/bluesky/shared.js +11 -11
  120. package/clis/bluesky/whoami.js +1 -1
  121. package/clis/booking/search.js +2 -2
  122. package/clis/boss/accept.js +1 -1
  123. package/clis/boss/applied.js +1 -1
  124. package/clis/boss/auth.js +1 -1
  125. package/clis/boss/batchgreet.js +1 -1
  126. package/clis/boss/bossinfo.js +1 -1
  127. package/clis/boss/chatlist.js +1 -1
  128. package/clis/boss/chatmsg.js +1 -1
  129. package/clis/boss/cities.js +1 -1
  130. package/clis/boss/detail.js +1 -1
  131. package/clis/boss/exchange.js +1 -1
  132. package/clis/boss/greet.js +1 -1
  133. package/clis/boss/interviews.js +1 -1
  134. package/clis/boss/invite.js +1 -1
  135. package/clis/boss/joblist.js +1 -1
  136. package/clis/boss/mark.js +1 -1
  137. package/clis/boss/me.js +2 -2
  138. package/clis/boss/recommend.js +1 -1
  139. package/clis/boss/resumedelete.js +1 -1
  140. package/clis/boss/resumelist.js +1 -1
  141. package/clis/boss/resumeupload.js +11 -11
  142. package/clis/boss/search.js +1 -1
  143. package/clis/boss/send.js +1 -1
  144. package/clis/boss/sendresume.js +1 -1
  145. package/clis/boss/stats.js +1 -1
  146. package/clis/boss/unread.js +1 -1
  147. package/clis/boss/utils.js +13 -13
  148. package/clis/chaoxing/assignments.js +1 -1
  149. package/clis/chaoxing/exams.js +1 -1
  150. package/clis/chaoxing/utils.js +9 -9
  151. package/clis/chatgpt/ask.js +1 -1
  152. package/clis/chatgpt/auth.js +2 -2
  153. package/clis/chatgpt/detail.js +1 -1
  154. package/clis/chatgpt/image.js +1 -1
  155. package/clis/chatgpt/read.js +1 -1
  156. package/clis/chatgpt/send.js +1 -1
  157. package/clis/chatgpt/utils.js +59 -59
  158. package/clis/chatgpt-app/ask.js +1 -1
  159. package/clis/chatgpt-app/send.js +1 -1
  160. package/clis/chatwise/model.js +6 -6
  161. package/clis/chess/analyze.js +1 -1
  162. package/clis/chess/game.js +1 -1
  163. package/clis/chess/games.js +1 -1
  164. package/clis/chess/stats.js +1 -1
  165. package/clis/chess/utils.js +1 -1
  166. package/clis/claude/ask.js +2 -2
  167. package/clis/claude/detail.js +1 -1
  168. package/clis/claude/new.js +1 -1
  169. package/clis/claude/read.js +1 -1
  170. package/clis/claude/send.js +1 -1
  171. package/clis/claude/utils.js +23 -23
  172. package/clis/cnblogs/article.js +1 -1
  173. package/clis/cnblogs/login.js +1 -1
  174. package/clis/cnblogs/stats.js +7 -7
  175. package/clis/cnblogs/whoami.js +1 -1
  176. package/clis/codex/_actions.js +3 -3
  177. package/clis/codex/archive.js +1 -1
  178. package/clis/codex/ask.js +6 -6
  179. package/clis/codex/model.js +8 -8
  180. package/clis/codex/pin.js +1 -1
  181. package/clis/codex/rename.js +4 -4
  182. package/clis/codex/send.js +3 -3
  183. package/clis/codex/sidebar.js +1 -1
  184. package/clis/coingecko/categories.js +1 -1
  185. package/clis/coingecko/coin.js +1 -1
  186. package/clis/coingecko/derivatives.js +1 -1
  187. package/clis/coingecko/exchanges.js +1 -1
  188. package/clis/coingecko/global.js +1 -1
  189. package/clis/coingecko/trending.js +1 -1
  190. package/clis/confluence/search.js +1 -1
  191. package/clis/coupang/product.js +3 -3
  192. package/clis/coupang/utils.js +1 -1
  193. package/clis/crates/crate.js +1 -1
  194. package/clis/crates/search.js +1 -1
  195. package/clis/crates/utils.js +1 -1
  196. package/clis/csdn/article.js +13 -13
  197. package/clis/csdn/columns.js +1 -1
  198. package/clis/csdn/login.js +1 -1
  199. package/clis/csdn/stats.js +4 -4
  200. package/clis/csdn/whoami.js +1 -1
  201. package/clis/cto51/article.js +1 -1
  202. package/clis/cto51/whoami.js +1 -1
  203. package/clis/ctrip/flight.js +2 -2
  204. package/clis/ctrip/hotel-search.js +3 -3
  205. package/clis/ctrip/hotel-suggest.js +1 -1
  206. package/clis/ctrip/search.js +1 -1
  207. package/clis/ctrip/utils.js +6 -6
  208. package/clis/cursor/ask.js +5 -5
  209. package/clis/cursor/composer.js +2 -2
  210. package/clis/cursor/model.js +4 -4
  211. package/clis/cursor/send.js +2 -2
  212. package/clis/dblp/author.js +1 -1
  213. package/clis/dblp/paper.js +1 -1
  214. package/clis/dblp/search.js +1 -1
  215. package/clis/dblp/utils.js +1 -1
  216. package/clis/dblp/venue.js +1 -1
  217. package/clis/deepseek/ask.js +1 -1
  218. package/clis/deepseek/auth.js +2 -2
  219. package/clis/deepseek/detail.js +1 -1
  220. package/clis/deepseek/new.js +1 -1
  221. package/clis/deepseek/read.js +1 -1
  222. package/clis/deepseek/send.js +7 -7
  223. package/clis/deepseek/utils.js +25 -25
  224. package/clis/defillama/protocol.js +1 -1
  225. package/clis/defillama/protocols.js +1 -1
  226. package/clis/defillama/utils.js +1 -1
  227. package/clis/devto/auth.js +2 -2
  228. package/clis/devto/latest.js +1 -1
  229. package/clis/devto/publish.js +5 -5
  230. package/clis/devto/read.js +2 -2
  231. package/clis/devto/stats.js +3 -3
  232. package/clis/dianping/auth.js +2 -2
  233. package/clis/dianping/cityResolver.js +2 -2
  234. package/clis/dianping/search.js +1 -1
  235. package/clis/dianping/shop.js +1 -1
  236. package/clis/dianping/utils.js +1 -1
  237. package/clis/discord-app/delete.js +3 -3
  238. package/clis/discord-app/read.js +1 -1
  239. package/clis/discord-app/thread-read.js +1 -1
  240. package/clis/discord-web/auth.js +2 -2
  241. package/clis/discord-web/send.js +5 -5
  242. package/clis/dockerhub/image.js +1 -1
  243. package/clis/dockerhub/search.js +1 -1
  244. package/clis/dockerhub/utils.js +1 -1
  245. package/clis/dongchedi/koubei.js +1 -1
  246. package/clis/dongchedi/models.js +1 -1
  247. package/clis/dongchedi/score.js +1 -1
  248. package/clis/dongchedi/search.js +1 -1
  249. package/clis/dongchedi/series.js +1 -1
  250. package/clis/dongchedi/specs.js +1 -1
  251. package/clis/dongchedi/utils.js +1 -1
  252. package/clis/douban/article.js +3 -3
  253. package/clis/douban/auth.js +2 -2
  254. package/clis/douban/download.js +1 -1
  255. package/clis/douban/utils.js +23 -23
  256. package/clis/doubao/auth.js +3 -3
  257. package/clis/doubao/utils.js +39 -39
  258. package/clis/doubao-app/ask.js +1 -1
  259. package/clis/doubao-app/utils.js +4 -4
  260. package/clis/douyin/_shared/browser-fetch.js +7 -7
  261. package/clis/douyin/_shared/draft-cache.js +1 -1
  262. package/clis/douyin/_shared/imagex-upload.js +1 -1
  263. package/clis/douyin/_shared/sts2.js +1 -1
  264. package/clis/douyin/_shared/text-extra.js +1 -1
  265. package/clis/douyin/_shared/tos-upload.js +4 -4
  266. package/clis/douyin/_shared/transcode.js +1 -1
  267. package/clis/douyin/_shared/vod-upload.js +4 -4
  268. package/clis/douyin/draft.js +18 -18
  269. package/clis/douyin/drafts.js +1 -1
  270. package/clis/douyin/publish-image.js +12 -12
  271. package/clis/douyin/publish.js +9 -9
  272. package/clis/douyin/search.js +3 -3
  273. package/clis/douyin/videos.js +1 -1
  274. package/clis/eastmoney/_secid.js +1 -1
  275. package/clis/eastmoney/announcement.js +1 -1
  276. package/clis/eastmoney/article.js +1 -1
  277. package/clis/eastmoney/convertible.js +1 -1
  278. package/clis/eastmoney/etf.js +1 -1
  279. package/clis/eastmoney/holders.js +1 -1
  280. package/clis/eastmoney/index-board.js +1 -1
  281. package/clis/eastmoney/kline.js +1 -1
  282. package/clis/eastmoney/kuaixun.js +1 -1
  283. package/clis/eastmoney/longhu.js +1 -1
  284. package/clis/eastmoney/money-flow.js +1 -1
  285. package/clis/eastmoney/northbound.js +1 -1
  286. package/clis/eastmoney/quote.js +1 -1
  287. package/clis/eastmoney/rank.js +1 -1
  288. package/clis/eastmoney/sectors.js +1 -1
  289. package/clis/endoflife/product.js +1 -1
  290. package/clis/endoflife/utils.js +1 -1
  291. package/clis/facebook/comment.js +8 -8
  292. package/clis/facebook/feed.js +4 -4
  293. package/clis/facebook/like.js +5 -5
  294. package/clis/facebook/notifications.js +3 -3
  295. package/clis/facebook/post.js +11 -11
  296. package/clis/facebook/search.js +3 -3
  297. package/clis/flathub/app.js +1 -1
  298. package/clis/flathub/search.js +1 -1
  299. package/clis/flathub/utils.js +1 -1
  300. package/clis/flomo/memos.js +1 -1
  301. package/clis/gemini/deep-research-result.js +4 -4
  302. package/clis/gemini/deep-research.js +1 -1
  303. package/clis/gemini/detail.js +1 -1
  304. package/clis/gemini/history.js +1 -1
  305. package/clis/gemini/image.js +2 -2
  306. package/clis/gemini/status.js +1 -1
  307. package/clis/gemini/utils.js +43 -43
  308. package/clis/geogebra/hexagon.js +1 -1
  309. package/clis/geogebra/info.js +3 -3
  310. package/clis/geogebra/triangle.js +1 -1
  311. package/clis/geogebra/utils.js +11 -11
  312. package/clis/ghost/login.js +1 -1
  313. package/clis/ghost/shared.js +2 -2
  314. package/clis/gitee/auth.js +2 -2
  315. package/clis/github-trending/repos.js +1 -1
  316. package/clis/google/news.js +1 -1
  317. package/clis/google/search.js +2 -2
  318. package/clis/google/suggest.js +1 -1
  319. package/clis/google/trends.js +1 -1
  320. package/clis/google/utils.js +1 -1
  321. package/clis/goproxy/module.js +1 -1
  322. package/clis/goproxy/utils.js +1 -1
  323. package/clis/goproxy/versions.js +1 -1
  324. package/clis/gov-policy/recent.js +2 -2
  325. package/clis/gov-policy/search.js +2 -2
  326. package/clis/grok/ask.js +1 -1
  327. package/clis/grok/detail.js +1 -1
  328. package/clis/grok/image.js +8 -8
  329. package/clis/grok/pin.js +1 -1
  330. package/clis/grok/send.js +1 -1
  331. package/clis/grok/status.js +1 -1
  332. package/clis/grok/utils.js +21 -21
  333. package/clis/guazi/browse.js +1 -1
  334. package/clis/guazi/car.js +1 -1
  335. package/clis/guazi/utils.js +1 -1
  336. package/clis/hackernews/auth.js +2 -2
  337. package/clis/hackernews/comment.js +8 -8
  338. package/clis/hackernews/read.js +7 -7
  339. package/clis/hackernews/submit.js +7 -7
  340. package/clis/hashnode/auth.js +3 -3
  341. package/clis/hashnode/publish.js +14 -14
  342. package/clis/hf/auth.js +2 -2
  343. package/clis/hf/models.js +1 -1
  344. package/clis/hf/paper.js +1 -1
  345. package/clis/hf/spaces.js +1 -1
  346. package/clis/hf/top.js +1 -1
  347. package/clis/homebrew/cask.js +1 -1
  348. package/clis/homebrew/formula.js +1 -1
  349. package/clis/homebrew/popular.js +1 -1
  350. package/clis/homebrew/utils.js +1 -1
  351. package/clis/huodongxing/events.js +1 -1
  352. package/clis/hupu/detail.js +4 -4
  353. package/clis/hupu/hot.js +3 -3
  354. package/clis/hupu/reply.js +1 -1
  355. package/clis/hupu/search.js +1 -1
  356. package/clis/hupu/unlike.js +1 -1
  357. package/clis/hupu/utils.js +10 -10
  358. package/clis/imdb/person.js +2 -2
  359. package/clis/imdb/reviews.js +3 -3
  360. package/clis/imdb/search.js +2 -2
  361. package/clis/imdb/title.js +1 -1
  362. package/clis/imdb/top.js +1 -1
  363. package/clis/imdb/trending.js +1 -1
  364. package/clis/imdb/utils.js +13 -13
  365. package/clis/imooc/article.js +6 -6
  366. package/clis/imooc/login.js +1 -1
  367. package/clis/imooc/whoami.js +1 -1
  368. package/clis/indeed/job.js +2 -2
  369. package/clis/indeed/search.js +2 -2
  370. package/clis/indeed/utils.js +1 -1
  371. package/clis/infoq/article.js +2 -2
  372. package/clis/infoq/login.js +1 -1
  373. package/clis/infoq/whoami.js +1 -1
  374. package/clis/instagram/_shared/private-publish.js +4 -4
  375. package/clis/instagram/_shared/protocol-capture.js +9 -9
  376. package/clis/instagram/detail.js +3 -3
  377. package/clis/instagram/post.js +25 -25
  378. package/clis/instagram/reel.js +18 -18
  379. package/clis/instagram/story.js +4 -4
  380. package/clis/instagram/user.js +2 -2
  381. package/clis/jd/item.js +65 -65
  382. package/clis/jianshu/article.js +1 -1
  383. package/clis/jianshu/login.js +1 -1
  384. package/clis/jianshu/notebooks.js +1 -1
  385. package/clis/jianshu/whoami.js +1 -1
  386. package/clis/jianyu/search.js +6 -6
  387. package/clis/jianyu/shared/procurement-contract.js +1 -1
  388. package/clis/jike/api.js +6 -6
  389. package/clis/jike/auth.js +3 -3
  390. package/clis/jike/comment.js +1 -1
  391. package/clis/jike/create.js +6 -6
  392. package/clis/jike/feed.js +3 -3
  393. package/clis/jike/like.js +1 -1
  394. package/clis/jike/notifications.js +3 -3
  395. package/clis/jike/repost.js +13 -13
  396. package/clis/jike/search.js +3 -3
  397. package/clis/jimeng/auth.js +2 -2
  398. package/clis/jimeng/generate.js +10 -10
  399. package/clis/jira/shared.js +1 -1
  400. package/clis/juejin/article.js +4 -4
  401. package/clis/juejin/categories.js +1 -1
  402. package/clis/juejin/hot.js +1 -1
  403. package/clis/juejin/login.js +1 -1
  404. package/clis/juejin/recommend.js +1 -1
  405. package/clis/juejin/stats.js +3 -3
  406. package/clis/juejin/tags.js +1 -1
  407. package/clis/juejin/utils.js +1 -1
  408. package/clis/juejin/whoami.js +1 -1
  409. package/clis/ke/utils.js +4 -4
  410. package/clis/kimi/_utils.js +7 -7
  411. package/clis/kimi/audit-extras.js +14 -14
  412. package/clis/kimi/auth.js +3 -3
  413. package/clis/kimi/chat.js +15 -15
  414. package/clis/kimi/storage.js +5 -5
  415. package/clis/kimi/ui.js +13 -13
  416. package/clis/kimi/usage.js +3 -3
  417. package/clis/kuaishou/auth.js +1 -1
  418. package/clis/kuaishou/publish.js +6 -6
  419. package/clis/lesswrong/_helpers.js +5 -5
  420. package/clis/lesswrong/comments.js +5 -5
  421. package/clis/lichess/top.js +1 -1
  422. package/clis/lichess/user.js +1 -1
  423. package/clis/lichess/utils.js +1 -1
  424. package/clis/linkedin/comment.js +1 -1
  425. package/clis/linkedin/connect.js +11 -11
  426. package/clis/linkedin/create.js +5 -5
  427. package/clis/linkedin/follow.js +1 -1
  428. package/clis/linkedin/inbox.js +1 -1
  429. package/clis/linkedin/job-detail.js +3 -3
  430. package/clis/linkedin/like.js +1 -1
  431. package/clis/linkedin/notifications.js +1 -1
  432. package/clis/linkedin/people-search.js +1 -1
  433. package/clis/linkedin/post-comments.js +1 -1
  434. package/clis/linkedin/post-detail.js +1 -1
  435. package/clis/linkedin/profile-analytics.js +1 -1
  436. package/clis/linkedin/profile-api.js +13 -13
  437. package/clis/linkedin/profile-experience.js +1 -1
  438. package/clis/linkedin/profile-projects.js +1 -1
  439. package/clis/linkedin/profile-read.js +3 -3
  440. package/clis/linkedin/reply.js +1 -1
  441. package/clis/linkedin/repost.js +1 -1
  442. package/clis/linkedin/safe-send.js +8 -8
  443. package/clis/linkedin/salesnav-inbox.js +5 -5
  444. package/clis/linkedin/salesnav-message.js +3 -3
  445. package/clis/linkedin/salesnav-search.js +4 -4
  446. package/clis/linkedin/salesnav-thread.js +1 -1
  447. package/clis/linkedin/search-api.js +3 -3
  448. package/clis/linkedin/search.js +8 -8
  449. package/clis/linkedin/social-api.js +31 -31
  450. package/clis/linkedin/timeline.js +3 -3
  451. package/clis/linkedin-learning/search.js +2 -2
  452. package/clis/linkedin-learning/trending.js +2 -2
  453. package/clis/linux-do/feed.js +4 -4
  454. package/clis/linux-do/topic-content.js +8 -8
  455. package/clis/lobsters/domain.js +1 -1
  456. package/clis/lobsters/read.js +7 -7
  457. package/clis/maimai/auth.js +2 -2
  458. package/clis/maimai/search-talents.js +4 -4
  459. package/clis/manus/_utils.js +1 -1
  460. package/clis/mastodon/login.js +1 -1
  461. package/clis/mastodon/post.js +1 -1
  462. package/clis/mastodon/shared.js +12 -12
  463. package/clis/mastodon/whoami.js +1 -1
  464. package/clis/maven/artifact.js +1 -1
  465. package/clis/maven/search.js +1 -1
  466. package/clis/maven/utils.js +1 -1
  467. package/clis/mdn/search.js +1 -1
  468. package/clis/medium/article.js +5 -5
  469. package/clis/medium/login.js +1 -1
  470. package/clis/medium/stats.js +3 -3
  471. package/clis/medium/tag.js +1 -1
  472. package/clis/medium/whoami.js +1 -1
  473. package/clis/mubu/notes.js +1 -1
  474. package/clis/mubu/utils.js +15 -15
  475. package/clis/note/auth.js +2 -2
  476. package/clis/note/note-utils.js +2 -2
  477. package/clis/note/publish.js +8 -8
  478. package/clis/notebooklm/add-source.js +8 -8
  479. package/clis/notebooklm/create.js +1 -1
  480. package/clis/notebooklm/generate-slides.js +1 -1
  481. package/clis/notebooklm/notes-get.js +1 -1
  482. package/clis/notebooklm/rpc.js +8 -8
  483. package/clis/notebooklm/source-fulltext.js +1 -1
  484. package/clis/notebooklm/utils.js +10 -10
  485. package/clis/nowcoder/auth.js +2 -2
  486. package/clis/nowcoder/comment.js +1 -1
  487. package/clis/nowcoder/comments.js +1 -1
  488. package/clis/nowcoder/dm-list.js +1 -1
  489. package/clis/nowcoder/dm-read.js +1 -1
  490. package/clis/nowcoder/dm-send.js +1 -1
  491. package/clis/nowcoder/drafts.js +1 -1
  492. package/clis/nowcoder/inbox.js +1 -1
  493. package/clis/nowcoder/like.js +1 -1
  494. package/clis/nowcoder/my.js +1 -1
  495. package/clis/nowcoder/post.js +1 -1
  496. package/clis/nowcoder/utils.js +13 -13
  497. package/clis/npm/downloads.js +1 -1
  498. package/clis/npm/package.js +1 -1
  499. package/clis/npm/search.js +1 -1
  500. package/clis/npm/utils.js +1 -1
  501. package/clis/nuget/package.js +1 -1
  502. package/clis/nuget/search.js +1 -1
  503. package/clis/nuget/utils.js +1 -1
  504. package/clis/nvd/cve.js +1 -1
  505. package/clis/oeis/search.js +1 -1
  506. package/clis/oeis/sequence.js +1 -1
  507. package/clis/oeis/utils.js +1 -1
  508. package/clis/ones/common.js +6 -6
  509. package/clis/ones/enrich-tasks.js +1 -1
  510. package/clis/ones/my-tasks.js +1 -1
  511. package/clis/ones/resolve-labels.js +1 -1
  512. package/clis/ones/task-helpers.js +1 -1
  513. package/clis/ones/task.js +1 -1
  514. package/clis/ones/worklog.js +7 -7
  515. package/clis/openalex/search.js +1 -1
  516. package/clis/openalex/utils.js +1 -1
  517. package/clis/openalex/work.js +1 -1
  518. package/clis/openfda/drug-label.js +1 -1
  519. package/clis/openfda/food-recall.js +1 -1
  520. package/clis/openfda/utils.js +1 -1
  521. package/clis/openreview/author.js +1 -1
  522. package/clis/openreview/paper.js +1 -1
  523. package/clis/openreview/reviews.js +3 -3
  524. package/clis/openreview/search.js +1 -1
  525. package/clis/openreview/utils.js +1 -1
  526. package/clis/openreview/venue.js +1 -1
  527. package/clis/oschina/article.js +1 -1
  528. package/clis/oschina/catalogs.js +1 -1
  529. package/clis/oschina/login.js +1 -1
  530. package/clis/oschina/stats.js +6 -6
  531. package/clis/oschina/whoami.js +1 -1
  532. package/clis/osv/query.js +1 -1
  533. package/clis/osv/utils.js +1 -1
  534. package/clis/osv/vulnerability.js +1 -1
  535. package/clis/packagist/package.js +1 -1
  536. package/clis/packagist/search.js +1 -1
  537. package/clis/packagist/utils.js +1 -1
  538. package/clis/pinterest/api.js +1 -1
  539. package/clis/pinterest/auth.js +1 -1
  540. package/clis/pinterest/boards.js +1 -1
  541. package/clis/pinterest/client.js +6 -6
  542. package/clis/pinterest/publish.js +5 -5
  543. package/clis/pixiv/auth.js +2 -2
  544. package/clis/pixiv/download.js +1 -1
  545. package/clis/pixiv/illusts.js +1 -1
  546. package/clis/pixiv/search.js +1 -1
  547. package/clis/pixiv/utils.js +3 -3
  548. package/clis/powerchina/auth.js +2 -2
  549. package/clis/powerchina/search.js +1 -1
  550. package/clis/producthunt/browse.js +2 -2
  551. package/clis/producthunt/hot.js +2 -2
  552. package/clis/producthunt/posts.js +1 -1
  553. package/clis/producthunt/today.js +1 -1
  554. package/clis/producthunt/utils.js +1 -1
  555. package/clis/pypi/downloads.js +1 -1
  556. package/clis/pypi/package.js +1 -1
  557. package/clis/pypi/utils.js +1 -1
  558. package/clis/qiita/auth.js +1 -1
  559. package/clis/qiita/gql.js +6 -6
  560. package/clis/qiita/publish.js +4 -4
  561. package/clis/qiita/stats.js +4 -4
  562. package/clis/qoder/_utils.js +16 -16
  563. package/clis/qoder/composer.js +1 -1
  564. package/clis/qoder/quest.js +1 -1
  565. package/clis/qoder/ui.js +14 -14
  566. package/clis/quark/auth.js +2 -2
  567. package/clis/quark/utils.js +2 -2
  568. package/clis/quora/answer-comments.js +3 -3
  569. package/clis/quora/create-answer.js +4 -4
  570. package/clis/quora/create-question.js +3 -3
  571. package/clis/quora/shared.js +17 -17
  572. package/clis/quora/whoami.js +1 -1
  573. package/clis/qwen/ask.js +1 -1
  574. package/clis/qwen/auth.js +3 -3
  575. package/clis/qwen/detail.js +1 -1
  576. package/clis/qwen/image.js +5 -5
  577. package/clis/qwen/status.js +1 -1
  578. package/clis/qwen/utils.js +16 -16
  579. package/clis/reddit/home.js +3 -3
  580. package/clis/reddit/read.js +10 -10
  581. package/clis/reddit/reply.js +4 -4
  582. package/clis/reddit/submit.js +11 -11
  583. package/clis/reddit/subreddit-info.js +3 -3
  584. package/clis/reddit/subscribed.js +4 -4
  585. package/clis/reddit/whoami.js +2 -2
  586. package/clis/rednote/comments.js +1 -1
  587. package/clis/rednote/download.js +1 -1
  588. package/clis/rednote/feed.js +1 -1
  589. package/clis/rednote/note.js +1 -1
  590. package/clis/rednote/notifications.js +2 -2
  591. package/clis/rednote/search.js +2 -2
  592. package/clis/rest-countries/country.js +1 -1
  593. package/clis/rest-countries/region.js +1 -1
  594. package/clis/rest-countries/utils.js +1 -1
  595. package/clis/reuters/article-detail.js +1 -1
  596. package/clis/reuters/auth.js +3 -3
  597. package/clis/reuters/search.js +1 -1
  598. package/clis/reuters/utils.js +4 -4
  599. package/clis/rfc/rfc.js +1 -1
  600. package/clis/rfc/utils.js +1 -1
  601. package/clis/rubygems/gem.js +1 -1
  602. package/clis/rubygems/search.js +1 -1
  603. package/clis/rubygems/utils.js +1 -1
  604. package/clis/segmentfault/article.js +3 -3
  605. package/clis/segmentfault/channels.js +1 -1
  606. package/clis/segmentfault/login.js +1 -1
  607. package/clis/segmentfault/stats.js +4 -4
  608. package/clis/segmentfault/tags.js +1 -1
  609. package/clis/segmentfault/whoami.js +1 -1
  610. package/clis/semanticscholar/citations.js +1 -1
  611. package/clis/semanticscholar/paper.js +1 -1
  612. package/clis/semanticscholar/recommendations.js +1 -1
  613. package/clis/semanticscholar/search.js +1 -1
  614. package/clis/semanticscholar/utils.js +1 -1
  615. package/clis/sinafinance/news.js +1 -1
  616. package/clis/sinafinance/stock-rank.js +1 -1
  617. package/clis/sinafinance/stock.js +1 -1
  618. package/clis/slock/attachment-download.js +1 -1
  619. package/clis/slock/attachment-upload.js +7 -7
  620. package/clis/slock/attachment-url.js +1 -1
  621. package/clis/slock/auth-verify.js +1 -1
  622. package/clis/slock/bookmark-add.js +1 -1
  623. package/clis/slock/bookmark-remove.js +1 -1
  624. package/clis/slock/channel-action.js +1 -1
  625. package/clis/slock/channel-create.js +1 -1
  626. package/clis/slock/channel-files.js +1 -1
  627. package/clis/slock/channel-list.js +1 -1
  628. package/clis/slock/channel-mark.js +1 -1
  629. package/clis/slock/channel-members.js +1 -1
  630. package/clis/slock/channel-unarchive.js +1 -1
  631. package/clis/slock/dm-list.js +1 -1
  632. package/clis/slock/errors.js +1 -1
  633. package/clis/slock/in-page.js +28 -28
  634. package/clis/slock/inbox-done.js +5 -5
  635. package/clis/slock/inbox.js +1 -1
  636. package/clis/slock/message-read.js +22 -22
  637. package/clis/slock/message-search.js +10 -10
  638. package/clis/slock/message-send.js +25 -25
  639. package/clis/slock/reaction-add.js +1 -1
  640. package/clis/slock/reaction-remove.js +1 -1
  641. package/clis/slock/resolve.js +1 -1
  642. package/clis/slock/server-list.js +2 -2
  643. package/clis/slock/task-claim.js +4 -4
  644. package/clis/slock/task-convert.js +13 -13
  645. package/clis/slock/task-create.js +1 -1
  646. package/clis/slock/task-delete.js +5 -5
  647. package/clis/slock/task-get.js +5 -5
  648. package/clis/slock/task-list-server.js +4 -4
  649. package/clis/slock/task-list.js +5 -5
  650. package/clis/slock/task-status.js +3 -3
  651. package/clis/slock/task-unclaim.js +3 -3
  652. package/clis/slock/thread-follow.js +1 -1
  653. package/clis/slock/thread-state.js +1 -1
  654. package/clis/slock/unread-summary.js +5 -5
  655. package/clis/slock/whoami.js +1 -1
  656. package/clis/smzdm/search.js +3 -3
  657. package/clis/sohu/article.js +1 -1
  658. package/clis/sohu/attributes.js +1 -1
  659. package/clis/sohu/categories.js +1 -1
  660. package/clis/sohu/channels.js +1 -1
  661. package/clis/sohu/columns.js +1 -1
  662. package/clis/sohu/login.js +1 -1
  663. package/clis/sohu/stats.js +3 -3
  664. package/clis/sohu/topics.js +1 -1
  665. package/clis/sohu/whoami.js +1 -1
  666. package/clis/spotify/spotify.js +1 -1
  667. package/clis/stackoverflow/read.js +6 -6
  668. package/clis/stackoverflow/related.js +1 -1
  669. package/clis/stackoverflow/tag.js +1 -1
  670. package/clis/stackoverflow/user.js +1 -1
  671. package/clis/stackoverflow/utils.js +1 -1
  672. package/clis/steam/app.js +1 -1
  673. package/clis/steam/search.js +1 -1
  674. package/clis/steam/utils.js +1 -1
  675. package/clis/substack/auth.js +2 -2
  676. package/clis/substack/post-utils.js +2 -2
  677. package/clis/substack/publish.js +5 -5
  678. package/clis/suno/auth.js +2 -2
  679. package/clis/suno/download.js +5 -5
  680. package/clis/suno/generate.js +3 -3
  681. package/clis/suno/list.js +1 -1
  682. package/clis/suno/status.js +1 -1
  683. package/clis/suno/utils.js +29 -29
  684. package/clis/telegram/send.js +7 -7
  685. package/clis/telegram/shared.js +2 -2
  686. package/clis/telegram/whoami.js +1 -1
  687. package/clis/test-utils.js +1 -1
  688. package/clis/threads/post.js +23 -23
  689. package/clis/threads/shared.js +3 -3
  690. package/clis/threads/whoami.js +1 -1
  691. package/clis/tieba/hot.js +3 -3
  692. package/clis/tieba/posts.js +1 -1
  693. package/clis/tieba/read.js +2 -2
  694. package/clis/tieba/search.js +3 -3
  695. package/clis/tieba/utils.js +1 -1
  696. package/clis/tiktok/comment.js +2 -2
  697. package/clis/tiktok/creator-videos.js +3 -3
  698. package/clis/tiktok/explore.js +3 -3
  699. package/clis/tiktok/follow.js +8 -8
  700. package/clis/tiktok/following.js +4 -4
  701. package/clis/tiktok/friends.js +7 -7
  702. package/clis/tiktok/live.js +3 -3
  703. package/clis/tiktok/notifications.js +6 -6
  704. package/clis/tiktok/publish.js +17 -17
  705. package/clis/tiktok/unfollow.js +4 -4
  706. package/clis/tiktok/user.js +2 -2
  707. package/clis/tiktok/utils.js +1 -1
  708. package/clis/toutiao/article.js +1 -1
  709. package/clis/toutiao/articles.js +2 -2
  710. package/clis/toutiao/auth.js +2 -2
  711. package/clis/toutiao/hot.js +1 -1
  712. package/clis/toutiao/recommend.js +1 -1
  713. package/clis/toutiao/utils.js +2 -2
  714. package/clis/trae-solo/_actions.js +4 -4
  715. package/clis/trae-solo/_fs.js +5 -5
  716. package/clis/trae-solo/_state.js +2 -2
  717. package/clis/trae-solo/automation.js +4 -4
  718. package/clis/trae-solo/mode.js +4 -4
  719. package/clis/trae-solo/model.js +4 -4
  720. package/clis/trae-solo/renderer-storage.js +4 -4
  721. package/clis/trae-solo/settings.js +1 -1
  722. package/clis/trae-solo/skill-fs.js +1 -1
  723. package/clis/trae-solo/skill.js +12 -12
  724. package/clis/trae-solo/state-fs.js +2 -2
  725. package/clis/trae-solo/task-fs.js +5 -5
  726. package/clis/trae-solo/workspaces-fs.js +1 -1
  727. package/clis/tumblr/auth.js +2 -2
  728. package/clis/tumblr/publish.js +3 -3
  729. package/clis/tvmaze/search.js +1 -1
  730. package/clis/tvmaze/show.js +1 -1
  731. package/clis/tvmaze/utils.js +1 -1
  732. package/clis/twitter/accept.js +7 -7
  733. package/clis/twitter/article.js +7 -7
  734. package/clis/twitter/bookmark-folder.js +3 -3
  735. package/clis/twitter/bookmark-folders.js +3 -3
  736. package/clis/twitter/bookmarks.js +4 -4
  737. package/clis/twitter/delete.js +5 -5
  738. package/clis/twitter/device-follow.js +3 -3
  739. package/clis/twitter/dm-list.js +1 -1
  740. package/clis/twitter/dm-read.js +1 -1
  741. package/clis/twitter/dm-send.js +5 -5
  742. package/clis/twitter/dm-shared.js +3 -3
  743. package/clis/twitter/download.js +6 -6
  744. package/clis/twitter/followers.js +5 -5
  745. package/clis/twitter/following.js +2 -2
  746. package/clis/twitter/like.js +3 -3
  747. package/clis/twitter/likes.js +8 -8
  748. package/clis/twitter/list-add-core.js +9 -9
  749. package/clis/twitter/list-create.js +5 -5
  750. package/clis/twitter/list-remove-core.js +9 -9
  751. package/clis/twitter/list-tweets.js +7 -7
  752. package/clis/twitter/lists.js +6 -6
  753. package/clis/twitter/notifications.js +2 -2
  754. package/clis/twitter/post.js +24 -24
  755. package/clis/twitter/profile.js +7 -7
  756. package/clis/twitter/quote.js +7 -7
  757. package/clis/twitter/reply-dm.js +7 -7
  758. package/clis/twitter/reply.js +12 -12
  759. package/clis/twitter/retweet.js +3 -3
  760. package/clis/twitter/scheduled-delete.js +3 -3
  761. package/clis/twitter/scheduled-list.js +2 -2
  762. package/clis/twitter/scheduled-utils.js +3 -3
  763. package/clis/twitter/search.js +5 -5
  764. package/clis/twitter/shared.js +6 -6
  765. package/clis/twitter/thread.js +4 -4
  766. package/clis/twitter/timeline.js +3 -3
  767. package/clis/twitter/trending.js +2 -2
  768. package/clis/twitter/tweets.js +11 -11
  769. package/clis/twitter/unlike.js +3 -3
  770. package/clis/twitter/unretweet.js +3 -3
  771. package/clis/twitter/utils.js +6 -6
  772. package/clis/upwork/detail.js +2 -2
  773. package/clis/upwork/feed.js +2 -2
  774. package/clis/upwork/search.js +2 -2
  775. package/clis/upwork/utils.js +1 -1
  776. package/clis/v2ex/auth.js +2 -2
  777. package/clis/v2ex/daily.js +3 -3
  778. package/clis/v2ex/me.js +2 -2
  779. package/clis/v2ex/notifications.js +2 -2
  780. package/clis/vk/post.js +1 -1
  781. package/clis/vk/shared.js +2 -2
  782. package/clis/vk/whoami.js +1 -1
  783. package/clis/web/read.js +8 -8
  784. package/clis/wechat-channels/auth.js +2 -2
  785. package/clis/wechat-channels/publish.js +30 -30
  786. package/clis/weibo/article.js +1 -1
  787. package/clis/weibo/auth.js +3 -3
  788. package/clis/weibo/comments.js +1 -1
  789. package/clis/weibo/delete.js +2 -2
  790. package/clis/weibo/feed.js +3 -3
  791. package/clis/weibo/hot.js +1 -1
  792. package/clis/weibo/publish.js +10 -10
  793. package/clis/weibo/search.js +2 -2
  794. package/clis/weibo/user-posts.js +3 -3
  795. package/clis/weibo/user.js +2 -2
  796. package/clis/weibo/utils.js +3 -3
  797. package/clis/weixin/article.js +1 -1
  798. package/clis/weixin/create-draft.js +26 -26
  799. package/clis/weixin/download.js +2 -2
  800. package/clis/weixin/login.js +1 -1
  801. package/clis/weixin/search.js +2 -2
  802. package/clis/weixin/stats.js +3 -3
  803. package/clis/weixin/whoami.js +1 -1
  804. package/clis/weread/ai-outline.js +2 -2
  805. package/clis/weread/book-search.js +2 -2
  806. package/clis/weread/book.js +2 -2
  807. package/clis/weread/notebooks.js +1 -1
  808. package/clis/weread/search.js +1 -1
  809. package/clis/weread/shelf.js +1 -1
  810. package/clis/weread/utils.js +6 -6
  811. package/clis/weread-official/book.js +1 -1
  812. package/clis/weread-official/discover.js +1 -1
  813. package/clis/weread-official/list-apis.js +1 -1
  814. package/clis/weread-official/notes.js +1 -1
  815. package/clis/weread-official/readdata.js +1 -1
  816. package/clis/weread-official/review.js +1 -1
  817. package/clis/weread-official/search.js +1 -1
  818. package/clis/weread-official/shelf.js +1 -1
  819. package/clis/weread-official/utils.js +1 -1
  820. package/clis/wikidata/entity.js +1 -1
  821. package/clis/wikidata/search.js +1 -1
  822. package/clis/wikidata/utils.js +1 -1
  823. package/clis/wikipedia/page.js +1 -1
  824. package/clis/wikipedia/trending.js +1 -1
  825. package/clis/wikipedia/utils.js +1 -1
  826. package/clis/wordpress/login.js +1 -1
  827. package/clis/wordpress/publish.js +1 -1
  828. package/clis/wordpress/shared.js +3 -3
  829. package/clis/wordpress/whoami.js +1 -1
  830. package/clis/woshipm/article.js +1 -1
  831. package/clis/woshipm/login.js +1 -1
  832. package/clis/woshipm/stats.js +4 -4
  833. package/clis/woshipm/whoami.js +1 -1
  834. package/clis/wttr/current.js +1 -1
  835. package/clis/wttr/forecast.js +1 -1
  836. package/clis/wttr/utils.js +1 -1
  837. package/clis/xianyu/collect.js +1 -1
  838. package/clis/xianyu/inbox.js +1 -1
  839. package/clis/xianyu/item-stats.js +2 -2
  840. package/clis/xianyu/location.js +1 -1
  841. package/clis/xianyu/manage.js +1 -1
  842. package/clis/xianyu/messages.js +1 -1
  843. package/clis/xianyu/mtop.js +5 -5
  844. package/clis/xianyu/order.js +1 -1
  845. package/clis/xianyu/promote-stats.js +2 -2
  846. package/clis/xianyu/publish.js +17 -17
  847. package/clis/xianyu/rate.js +1 -1
  848. package/clis/xianyu/reply.js +1 -1
  849. package/clis/xianyu/search.js +8 -8
  850. package/clis/xianyu/seller-data.js +1 -1
  851. package/clis/xianyu/seller-list.js +1 -1
  852. package/clis/xianyu/user.js +1 -1
  853. package/clis/xiaoe/catalog.js +2 -2
  854. package/clis/xiaoe/content.js +2 -2
  855. package/clis/xiaoe/courses.js +2 -2
  856. package/clis/xiaohongshu/ask.js +6 -6
  857. package/clis/xiaohongshu/comments.js +6 -6
  858. package/clis/xiaohongshu/creator-note-detail.js +7 -7
  859. package/clis/xiaohongshu/creator-notes-summary.js +1 -1
  860. package/clis/xiaohongshu/creator-notes.js +13 -13
  861. package/clis/xiaohongshu/creator-profile.js +2 -2
  862. package/clis/xiaohongshu/creator-stats.js +2 -2
  863. package/clis/xiaohongshu/delete-note.js +7 -7
  864. package/clis/xiaohongshu/download.js +4 -4
  865. package/clis/xiaohongshu/feed.js +2 -2
  866. package/clis/xiaohongshu/follow.js +3 -3
  867. package/clis/xiaohongshu/human.js +3 -3
  868. package/clis/xiaohongshu/note-helpers.js +1 -1
  869. package/clis/xiaohongshu/note.js +2 -2
  870. package/clis/xiaohongshu/notifications.js +1 -1
  871. package/clis/xiaohongshu/publish-video.js +8 -8
  872. package/clis/xiaohongshu/publish.js +59 -59
  873. package/clis/xiaohongshu/search.js +8 -8
  874. package/clis/xiaohongshu/unfollow.js +4 -4
  875. package/clis/xiaohongshu/user-helpers.js +1 -1
  876. package/clis/xiaohongshu/user.js +2 -2
  877. package/clis/xiaoyuzhou/auth.js +3 -3
  878. package/clis/xiaoyuzhou/download.js +1 -1
  879. package/clis/xiaoyuzhou/utils.js +1 -1
  880. package/clis/xueqiu/article.js +4 -4
  881. package/clis/xueqiu/comments.js +4 -4
  882. package/clis/xueqiu/danjuan-utils.js +4 -4
  883. package/clis/xueqiu/earnings-date.js +1 -1
  884. package/clis/xueqiu/events.js +3 -3
  885. package/clis/xueqiu/hashtags.js +3 -3
  886. package/clis/xueqiu/stocks.js +3 -3
  887. package/clis/xueqiu/users.js +3 -3
  888. package/clis/xueqiu/utils.js +3 -3
  889. package/clis/yahoo-finance/quote.js +1 -1
  890. package/clis/yollomi/background.js +1 -1
  891. package/clis/yollomi/edit.js +1 -1
  892. package/clis/yollomi/face-swap.js +1 -1
  893. package/clis/yollomi/generate.js +1 -1
  894. package/clis/yollomi/object-remover.js +1 -1
  895. package/clis/yollomi/remove-bg.js +1 -1
  896. package/clis/yollomi/restore.js +1 -1
  897. package/clis/yollomi/try-on.js +1 -1
  898. package/clis/yollomi/upload.js +4 -4
  899. package/clis/yollomi/upscale.js +1 -1
  900. package/clis/yollomi/utils.js +4 -4
  901. package/clis/yollomi/video.js +1 -1
  902. package/clis/youtube/channel.js +4 -4
  903. package/clis/youtube/feed.js +2 -2
  904. package/clis/youtube/like.js +5 -5
  905. package/clis/youtube/playlist.js +7 -7
  906. package/clis/youtube/publish.js +11 -11
  907. package/clis/youtube/search.js +3 -3
  908. package/clis/youtube/subscribe.js +7 -7
  909. package/clis/youtube/subscriptions.js +1 -1
  910. package/clis/youtube/transcript-group.js +2 -2
  911. package/clis/youtube/transcript.js +13 -13
  912. package/clis/youtube/unlike.js +5 -5
  913. package/clis/youtube/unsubscribe.js +7 -7
  914. package/clis/youtube/utils.js +3 -3
  915. package/clis/youtube/video.js +4 -4
  916. package/clis/youtube/watch-later.js +2 -2
  917. package/clis/yuanbao/ask.js +18 -18
  918. package/clis/yuanbao/detail.js +1 -1
  919. package/clis/yuanbao/read.js +1 -1
  920. package/clis/yuanbao/shared.js +9 -9
  921. package/clis/yuanbao/status.js +1 -1
  922. package/clis/yuque/article.js +1 -1
  923. package/clis/yuque/whoami.js +1 -1
  924. package/clis/zhihu/answer-comments.js +2 -2
  925. package/clis/zhihu/answer-detail.js +3 -3
  926. package/clis/zhihu/answer.js +1 -1
  927. package/clis/zhihu/article-transform.js +1 -1
  928. package/clis/zhihu/article.js +1 -1
  929. package/clis/zhihu/auth.js +2 -2
  930. package/clis/zhihu/collection.js +3 -3
  931. package/clis/zhihu/collections.js +3 -3
  932. package/clis/zhihu/download.js +2 -2
  933. package/clis/zhihu/image-profile.js +6 -6
  934. package/clis/zhihu/paginate.js +3 -3
  935. package/clis/zhihu/pin.js +4 -4
  936. package/clis/zhihu/question.js +3 -3
  937. package/clis/zhihu/recommend.js +3 -3
  938. package/clis/zhihu/search.js +3 -3
  939. package/clis/zhihu/stats.js +3 -3
  940. package/clis/zhihu/user-arg.js +1 -1
  941. package/clis/zhihu/write-shared.js +7 -7
  942. package/clis/zlibrary/utils.js +6 -6
  943. package/clis/zsxq/auth.js +3 -3
  944. package/clis/zsxq/search.js +1 -1
  945. package/clis/zsxq/topic.js +1 -1
  946. package/clis/zsxq/utils.js +5 -5
  947. package/dist/src/adapter-source.js +1 -1
  948. package/dist/src/browser/analyze.js +1 -1
  949. package/dist/src/browser/article-extract.js +2 -2
  950. package/dist/src/browser/ax-snapshot.js +2 -2
  951. package/dist/src/browser/base-page.js +25 -25
  952. package/dist/src/browser/bridge.js +1 -1
  953. package/dist/src/browser/cdp.js +1 -1
  954. package/dist/src/browser/daemon-client.js +1 -1
  955. package/dist/src/browser/daemon-lifecycle.js +7 -7
  956. package/dist/src/browser/dom-helpers.js +35 -35
  957. package/dist/src/browser/dom-snapshot.js +19 -19
  958. package/dist/src/browser/errors.js +3 -3
  959. package/dist/src/browser/extract.js +5 -5
  960. package/dist/src/browser/find.js +13 -13
  961. package/dist/src/browser/fingerprint.js +2 -2
  962. package/dist/src/browser/html-tree.js +6 -6
  963. package/dist/src/browser/managed-chrome.js +1 -1
  964. package/dist/src/browser/network-cache.js +1 -1
  965. package/dist/src/browser/network-key.js +1 -1
  966. package/dist/src/browser/page.js +7 -7
  967. package/dist/src/browser/profile.js +2 -2
  968. package/dist/src/browser/proxy-test.js +8 -8
  969. package/dist/src/browser/shape-filter.js +1 -1
  970. package/dist/src/browser/shape.js +1 -1
  971. package/dist/src/browser/stealth.js +3 -3
  972. package/dist/src/browser/tabs.js +2 -2
  973. package/dist/src/browser/target-errors.js +1 -1
  974. package/dist/src/browser/target-resolver.js +23 -23
  975. package/dist/src/browser/trace.js +2 -2
  976. package/dist/src/browser/utils.js +1 -1
  977. package/dist/src/browser/verify-fixture.js +2 -2
  978. package/dist/src/browser-session-lock.js +1 -1
  979. package/dist/src/build-manifest.js +11 -11
  980. package/dist/src/capabilityRouting.js +1 -1
  981. package/dist/src/cli-argv-preprocess.js +1 -1
  982. package/dist/src/cli.js +32 -32
  983. package/dist/src/commanderAdapter.js +3 -3
  984. package/dist/src/commands/auth.js +3 -3
  985. package/dist/src/commands/daemon.js +1 -1
  986. package/dist/src/completion-fast.js +1 -1
  987. package/dist/src/completion.js +1 -1
  988. package/dist/src/constants.js +1 -1
  989. package/dist/src/convention-audit.js +2 -2
  990. package/dist/src/daemon-utils.js +1 -1
  991. package/dist/src/daemon.js +1 -1
  992. package/dist/src/discovery.js +2 -2
  993. package/dist/src/doctor.js +9 -9
  994. package/dist/src/download/article-download.js +15 -15
  995. package/dist/src/download/index.js +4 -4
  996. package/dist/src/download/media-download.js +1 -1
  997. package/dist/src/download/progress.js +3 -3
  998. package/dist/src/electron-apps.js +1 -1
  999. package/dist/src/errors.js +2 -2
  1000. package/dist/src/execution.js +2 -2
  1001. package/dist/src/external.js +1 -1
  1002. package/dist/src/help.js +8 -8
  1003. package/dist/src/hooks.js +1 -1
  1004. package/dist/src/interceptor.js +21 -21
  1005. package/dist/src/launcher.js +7 -7
  1006. package/dist/src/logger.js +8 -8
  1007. package/dist/src/main.js +7 -7
  1008. package/dist/src/observation/artifact.js +5 -5
  1009. package/dist/src/observation/retention.js +1 -1
  1010. package/dist/src/output.js +2 -2
  1011. package/dist/src/package-paths.js +1 -1
  1012. package/dist/src/pipeline/executor.js +1 -1
  1013. package/dist/src/pipeline/registry.js +1 -1
  1014. package/dist/src/pipeline/steps/browser.js +1 -1
  1015. package/dist/src/pipeline/steps/download.js +1 -1
  1016. package/dist/src/pipeline/steps/fetch.js +6 -6
  1017. package/dist/src/pipeline/steps/intercept.js +1 -1
  1018. package/dist/src/pipeline/steps/tap.js +17 -17
  1019. package/dist/src/pipeline/steps/transform.js +1 -1
  1020. package/dist/src/pipeline/template.js +1 -1
  1021. package/dist/src/plugin-manifest.js +1 -1
  1022. package/dist/src/plugin-scaffold.js +19 -19
  1023. package/dist/src/plugin.js +12 -12
  1024. package/dist/src/rate-limit.js +1 -1
  1025. package/dist/src/registry.js +1 -1
  1026. package/dist/src/runtime-detect.js +1 -1
  1027. package/dist/src/runtime.js +1 -1
  1028. package/dist/src/scripts/framework.js +1 -1
  1029. package/dist/src/scripts/interact.js +1 -1
  1030. package/dist/src/scripts/store.js +1 -1
  1031. package/dist/src/serialization.js +2 -2
  1032. package/dist/src/session-lease.js +1 -1
  1033. package/dist/src/snapshotFormatter.js +2 -2
  1034. package/dist/src/tui.js +12 -12
  1035. package/dist/src/user-runtime.js +1 -1
  1036. package/dist/src/utils.d.ts +12 -0
  1037. package/dist/src/utils.js +4 -4
  1038. package/dist/src/validate.js +2 -2
  1039. package/dist/src/verify.js +2 -2
  1040. package/dist/src/version.js +1 -1
  1041. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import{AuthRequiredError as J,CommandExecutionError as F}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as L}from"../_shared/site-auth.js";const K=`(async () => {
1
+ import{AuthRequiredError as r,CommandExecutionError as i}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as a}from"../_shared/site-auth.js";const n=`(async () => {
2
2
  try {
3
3
  const r = await fetch('/api/v5/user', { credentials: 'include', headers: { Accept: 'application/json' } });
4
4
  if (r.status === 401 || r.status === 403) return { kind: 'auth', detail: 'Gitee /api/v5/user HTTP ' + r.status };
@@ -9,4 +9,4 @@ import{AuthRequiredError as J,CommandExecutionError as F}from"@jackwener/opencli
9
9
  } catch (e) {
10
10
  return { kind: 'exception', detail: String(e && e.message || e) };
11
11
  }
12
- })()`;async function N(D){await D.goto("https://gitee.com/");await D.wait(1);const z=await D.evaluate(K);if(z?.kind==="auth")throw new J("gitee.com",z.detail);if(z?.kind==="http")throw new F(`HTTP ${z.httpStatus} from Gitee /api/v5/user`);if(z?.kind==="exception")throw new F(`Gitee whoami failed: ${z.detail}`);if(!z?.ok)throw new F(`Unexpected Gitee probe: ${JSON.stringify(z)}`);return{user_id:z.user_id,username:z.username,name:z.name}}L({site:"gitee",domain:"gitee.com",loginUrl:"https://gitee.com/login",columns:["user_id","username","name"],verify:N,poll:async(D)=>{const z=await D.evaluate(K);if(!z?.ok)throw new J("gitee.com","Waiting for Gitee login");return{user_id:z.user_id,username:z.username,name:z.name}}});
12
+ })()`;async function o(t){await t.goto("https://gitee.com/");await t.wait(1);const e=await t.evaluate(n);if(e?.kind==="auth")throw new r("gitee.com",e.detail);if(e?.kind==="http")throw new i(`HTTP ${e.httpStatus} from Gitee /api/v5/user`);if(e?.kind==="exception")throw new i(`Gitee whoami failed: ${e.detail}`);if(!e?.ok)throw new i(`Unexpected Gitee probe: ${JSON.stringify(e)}`);return{user_id:e.user_id,username:e.username,name:e.name}}a({site:"gitee",domain:"gitee.com",loginUrl:"https://gitee.com/login",columns:["user_id","username","name"],verify:o,poll:async(t)=>{const e=await t.evaluate(n);if(!e?.ok)throw new r("gitee.com","Waiting for Gitee login");return{user_id:e.user_id,username:e.username,name:e.name}}});
@@ -1 +1 @@
1
- import{cli as $,Strategy as E}from"@jackwener/opencli/registry";import{ArgumentError as d,CommandExecutionError as c,EmptyResultError as x}from"@jackwener/opencli/errors";const k={daily:"daily",weekly:"weekly",monthly:"monthly"};function f(t){return String(t??"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#0?39;/g,"'").replace(/&#x27;/gi,"'").replace(/&nbsp;/g," ")}function g(t){return String(t??"").replace(/<[^>]*>/g,"")}function T(t){if(t==null)return null;const s=String(t).replace(/[,\s]/g,"");if(!/^\d+$/.test(s))return null;return Number(s)}function M(t){return String(t).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(t,s,o){const e=T(t);if(e==null)throw new c(`github-trending parser drift: missing ${s} for ${o}`);return e}function A(t){return/don.t have any trending repositories/i.test(g(t))||/no trending repositories/i.test(g(t))}function C(t,s){const o=Array.from(String(t??"").matchAll(/<article\b[^>]*class="[^"]*\bBox-row\b[^"]*"[^>]*>([\s\S]*?)<\/article>/g)).map((l)=>l[1]),e=[];if(o.length===0){if(A(t))return e;throw new c("github-trending parser drift: no repository rows found")}for(const l of o){const n=l,p=n.match(/<h2\b[\s\S]*?href="\/([^"/?#]+\/[^"/?#]+)"/);if(!p)throw new c("github-trending parser drift: missing repository link");const i=f(p[1]).trim();if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(i))throw new c(`github-trending parser drift: invalid repository identity "${i}"`);const a=n.match(/<p class="col-9 color-fg-muted[^"]*">([\s\S]*?)<\/p>/),h=a?f(g(a[1]).replace(/\s+/g," ")).trim():"",u=n.match(/<span itemprop="programmingLanguage">([\s\S]*?)<\/span>/),r=u?f(g(u[1])).trim():null,m=M(i),y=n.match(new RegExp(`<a\\b[^>]*href="/${m}/stargazers"[^>]*>([\\s\\S]*?)</a>`)),w=n.match(new RegExp(`<a\\b[^>]*href="/${m}/forks"[^>]*>([\\s\\S]*?)</a>`)),S=n.match(/([\d,]+)\s+stars\s+(?:today|this week|this month)/i);e.push({repo:i,description:h,language:r,stars:b(y?g(y[1]):null,"stars",i),forks:b(w?g(w[1]):null,"forks",i),starsSince:b(S?.[1],"period stars",i),url:`https://github.com/${i}`});if(e.length>=s)break}return e}$({site:"github-trending",name:"repos",access:"read",description:"GitHub Trending repositories (public, no login). Filter by --language and --since.",domain:"github.com",strategy:E.PUBLIC,browser:!1,args:[{name:"since",type:"string",default:"daily",help:"Time range: daily / weekly / monthly"},{name:"language",type:"string",default:"",help:'Filter by programming language slug, e.g. python, rust, "c++"'},{name:"limit",type:"int",default:25,help:"Number of repositories to return (max 25)"}],columns:["rank","repo","description","language","stars","forks","starsSince","url"],func:async(t)=>{const s=String(t.since??"daily").toLowerCase(),o=k[s];if(!o)throw new d(`Unknown --since "${s}". Valid: ${Object.keys(k).join(", ")}`);const e=Number(t.limit??25);if(!Number.isInteger(e)||e<=0)throw new d("--limit must be a positive integer");if(e>25)throw new d("--limit must be <= 25 (GitHub Trending lists at most 25 repositories)");const l=e,n=String(t.language??"").trim(),p=n?`/trending/${encodeURIComponent(n)}`:"/trending",i=new URL(`https://github.com${p}`);i.searchParams.set("since",o);let a;try{a=await fetch(i,{headers:{"User-Agent":"Mozilla/5.0 (compatible; ppcli/github-trending)",Accept:"text/html"}})}catch(r){throw new c(`github-trending request failed: ${r?.message||r}`)}if(!a.ok)throw new c(`github-trending request failed: HTTP ${a.status}`);const h=await a.text(),u=C(h,l);if(u.length===0)throw new x("github-trending",n?`no trending repositories for language "${n}" (${o})`:`no trending repositories (${o})`);return u.map((r,m)=>({rank:m+1,repo:r.repo,description:r.description,language:r.language,stars:r.stars,forks:r.forks,starsSince:r.starsSince,url:r.url}))}});
1
+ import{cli as E,Strategy as x}from"@jackwener/opencli/registry";import{ArgumentError as d,CommandExecutionError as c,EmptyResultError as T}from"@jackwener/opencli/errors";const k={daily:"daily",weekly:"weekly",monthly:"monthly"};function f(t){return String(t??"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#0?39;/g,"'").replace(/&#x27;/gi,"'").replace(/&nbsp;/g," ")}function g(t){return String(t??"").replace(/<[^>]*>/g,"")}function A(t){if(t==null)return null;const s=String(t).replace(/[,\s]/g,"");if(!/^\d+$/.test(s))return null;return Number(s)}function C(t){return String(t).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(t,s,o){const e=A(t);if(e==null)throw new c(`github-trending parser drift: missing ${s} for ${o}`);return e}function M(t){return/don.t have any trending repositories/i.test(g(t))||/no trending repositories/i.test(g(t))}function R(t,s){const o=Array.from(String(t??"").matchAll(/<article\b[^>]*class="[^"]*\bBox-row\b[^"]*"[^>]*>([\s\S]*?)<\/article>/g)).map((l)=>l[1]),e=[];if(o.length===0){if(M(t))return e;throw new c("github-trending parser drift: no repository rows found")}for(const l of o){const n=l,p=n.match(/<h2\b[\s\S]*?href="\/([^"/?#]+\/[^"/?#]+)"/);if(!p)throw new c("github-trending parser drift: missing repository link");const i=f(p[1]).trim();if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(i))throw new c(`github-trending parser drift: invalid repository identity "${i}"`);const a=n.match(/<p class="col-9 color-fg-muted[^"]*">([\s\S]*?)<\/p>/),h=a?f(g(a[1]).replace(/\s+/g," ")).trim():"",u=n.match(/<span itemprop="programmingLanguage">([\s\S]*?)<\/span>/),r=u?f(g(u[1])).trim():null,m=C(i),y=n.match(new RegExp(`<a\\b[^>]*href="/${m}/stargazers"[^>]*>([\\s\\S]*?)</a>`)),w=n.match(new RegExp(`<a\\b[^>]*href="/${m}/forks"[^>]*>([\\s\\S]*?)</a>`)),S=n.match(/([\d,]+)\s+stars\s+(?:today|this week|this month)/i);e.push({repo:i,description:h,language:r,stars:b(y?g(y[1]):null,"stars",i),forks:b(w?g(w[1]):null,"forks",i),starsSince:b(S?.[1],"period stars",i),url:`https://github.com/${i}`});if(e.length>=s)break}return e}E({site:"github-trending",name:"repos",access:"read",description:"GitHub Trending repositories (public, no login). Filter by --language and --since.",domain:"github.com",strategy:x.PUBLIC,browser:!1,args:[{name:"since",type:"string",default:"daily",help:"Time range: daily / weekly / monthly"},{name:"language",type:"string",default:"",help:'Filter by programming language slug, e.g. python, rust, "c++"'},{name:"limit",type:"int",default:25,help:"Number of repositories to return (max 25)"}],columns:["rank","repo","description","language","stars","forks","starsSince","url"],func:async(t)=>{const s=String(t.since??"daily").toLowerCase(),o=k[s];if(!o)throw new d(`Unknown --since "${s}". Valid: ${Object.keys(k).join(", ")}`);const e=Number(t.limit??25);if(!Number.isInteger(e)||e<=0)throw new d("--limit must be a positive integer");if(e>25)throw new d("--limit must be <= 25 (GitHub Trending lists at most 25 repositories)");const l=e,n=String(t.language??"").trim(),p=n?`/trending/${encodeURIComponent(n)}`:"/trending",i=new URL(`https://github.com${p}`);i.searchParams.set("since",o);let a;try{a=await fetch(i,{headers:{"User-Agent":"Mozilla/5.0 (compatible; ppcli/github-trending)",Accept:"text/html"}})}catch(r){throw new c(`github-trending request failed: ${r?.message||r}`)}if(!a.ok)throw new c(`github-trending request failed: HTTP ${a.status}`);const h=await a.text(),u=R(h,l);if(u.length===0)throw new T("github-trending",n?`no trending repositories for language "${n}" (${o})`:`no trending repositories (${o})`);return u.map((r,m)=>({rank:m+1,repo:r.repo,description:r.description,language:r.language,stars:r.stars,forks:r.forks,starsSince:r.starsSince,url:r.url}))}});
@@ -1 +1 @@
1
- import{cli as N,Strategy as O}from"@jackwener/opencli/registry";import{CliError as J}from"@jackwener/opencli/errors";import{parseRssItems as P}from"./utils.js";N({site:"google",name:"news",access:"read",description:"Get Google News headlines",strategy:O.PUBLIC,browser:!1,args:[{name:"keyword",positional:!0,help:"Search query (omit for top stories)"},{name:"limit",type:"int",default:10,help:"Number of results"},{name:"lang",default:"en",help:"Language short code (e.g. en, zh)"},{name:"region",default:"US",help:"Region code (e.g. US, CN)"}],columns:["title","source","date","url"],func:async(h)=>{const K=Math.max(1,Math.min(Number(h.limit),100)),D=encodeURIComponent(h.lang),F=encodeURIComponent(h.region),G=`${h.region}:${h.lang}`,L=h.keyword?`https://news.google.com/rss/search?q=${encodeURIComponent(h.keyword)}&hl=${D}&gl=${F}&ceid=${G}`:`https://news.google.com/rss?hl=${D}&gl=${F}&ceid=${G}`,z=await fetch(L);if(!z.ok)throw new J("FETCH_ERROR",`HTTP ${z.status}`,"Check your network connection");const M=await z.text(),H=P(M,["title","link","pubDate","source"]);if(!H.length)throw new J("NOT_FOUND","No news articles found","Try a different keyword or region");return H.slice(0,K).map((v)=>{let q=v.title||"",A=v.source||"";if(!A){const B=q.lastIndexOf(" - ");if(B!==-1){A=q.slice(B+3);q=q.slice(0,B)}}return{title:q,source:A,date:v.pubDate||"",url:v.link||""}})}});
1
+ import{cli as p,Strategy as h}from"@jackwener/opencli/registry";import{CliError as m}from"@jackwener/opencli/errors";import{parseRssItems as f}from"./utils.js";p({site:"google",name:"news",access:"read",description:"Get Google News headlines",strategy:h.PUBLIC,browser:!1,args:[{name:"keyword",positional:!0,help:"Search query (omit for top stories)"},{name:"limit",type:"int",default:10,help:"Number of results"},{name:"lang",default:"en",help:"Language short code (e.g. en, zh)"},{name:"region",default:"US",help:"Region code (e.g. US, CN)"}],columns:["title","source","date","url"],func:async(e)=>{const d=Math.max(1,Math.min(Number(e.limit),100)),i=encodeURIComponent(e.lang),l=encodeURIComponent(e.region),c=`${e.region}:${e.lang}`,u=e.keyword?`https://news.google.com/rss/search?q=${encodeURIComponent(e.keyword)}&hl=${i}&gl=${l}&ceid=${c}`:`https://news.google.com/rss?hl=${i}&gl=${l}&ceid=${c}`,n=await fetch(u);if(!n.ok)throw new m("FETCH_ERROR",`HTTP ${n.status}`,"Check your network connection");const g=await n.text(),a=f(g,["title","link","pubDate","source"]);if(!a.length)throw new m("NOT_FOUND","No news articles found","Try a different keyword or region");return a.slice(0,d).map((o)=>{let t=o.title||"",r=o.source||"";if(!r){const s=t.lastIndexOf(" - ");if(s!==-1){r=t.slice(s+3);t=t.slice(0,s)}}return{title:t,source:r,date:o.pubDate||"",url:o.link||""}})}});
@@ -1,4 +1,4 @@
1
- import{cli as D,Strategy as F}from"@jackwener/opencli/registry";import{CliError as G}from"@jackwener/opencli/errors";D({site:"google",name:"search",access:"read",description:"Search Google",domain:"google.com",strategy:F.PUBLIC,browser:!0,args:[{name:"keyword",positional:!0,required:!0,help:"Search query"},{name:"limit",type:"int",default:10,help:"Number of results (1-100)"},{name:"lang",default:"en",help:"Language short code (e.g. en, zh)"}],columns:["type","title","url","snippet"],func:async(b,f)=>{const v=Math.max(1,Math.min(Number(f.limit),100)),z=encodeURIComponent(f.keyword),A=encodeURIComponent(f.lang),B=`https://www.google.com/search?q=${z}&hl=${A}&num=${v}`;await b.goto(B);try{await b.wait({selector:"#rso a h3",timeout:5})}catch{await b.wait(2)}const h=await b.evaluate(`
1
+ import{cli as s,Strategy as c}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";s({site:"google",name:"search",access:"read",description:"Search Google",domain:"google.com",strategy:c.PUBLIC,browser:!0,args:[{name:"keyword",positional:!0,required:!0,help:"Search query"},{name:"limit",type:"int",default:10,help:"Number of results (1-100)"},{name:"lang",default:"en",help:"Language short code (e.g. en, zh)"}],columns:["type","title","url","snippet"],func:async(e,t)=>{const i=Math.max(1,Math.min(Number(t.limit),100)),a=encodeURIComponent(t.keyword),o=encodeURIComponent(t.lang),l=`https://www.google.com/search?q=${a}&hl=${o}&num=${i}`;await e.goto(l);try{await e.wait({selector:"#rso a h3",timeout:5})}catch{await e.wait(2)}const r=await e.evaluate(`
2
2
  (function() {
3
3
  var results = [];
4
4
  var seenUrls = {};
@@ -87,4 +87,4 @@ import{cli as D,Strategy as F}from"@jackwener/opencli/registry";import{CliError
87
87
 
88
88
  return {items: results};
89
89
  })()
90
- `),q=h&&h.items||[];if(q.length===0)throw new G("NOT_FOUND","No search results found","Try a different keyword or check for CAPTCHA");return q}});
90
+ `),n=r&&r.items||[];if(n.length===0)throw new u("NOT_FOUND","No search results found","Try a different keyword or check for CAPTCHA");return n}});
@@ -1 +1 @@
1
- import{cli as G,Strategy as H}from"@jackwener/opencli/registry";import{CliError as z}from"@jackwener/opencli/errors";G({site:"google",name:"suggest",access:"read",description:"Get Google search suggestions",strategy:H.PUBLIC,browser:!1,args:[{name:"keyword",positional:!0,required:!0,help:"Search query"},{name:"lang",default:"zh-CN",help:"Language code"}],columns:["suggestion"],func:async(v)=>{const A=encodeURIComponent(v.keyword),B=encodeURIComponent(v.lang),D=`https://suggestqueries.google.com/complete/search?client=firefox&q=${A}&hl=${B}`,b=await fetch(D);if(!b.ok)throw new z("FETCH_ERROR",`HTTP ${b.status}`,"Check your network connection");const h=await b.json(),x=Array.isArray(h)&&Array.isArray(h[1])?h[1]:[];if(!x.length)throw new z("NOT_FOUND","No suggestions found","Try a different keyword");return x.map((F)=>({suggestion:F}))}});
1
+ import{cli as i,Strategy as u}from"@jackwener/opencli/registry";import{CliError as s}from"@jackwener/opencli/errors";i({site:"google",name:"suggest",access:"read",description:"Get Google search suggestions",strategy:u.PUBLIC,browser:!1,args:[{name:"keyword",positional:!0,required:!0,help:"Search query"},{name:"lang",default:"zh-CN",help:"Language code"}],columns:["suggestion"],func:async(r)=>{const n=encodeURIComponent(r.keyword),a=encodeURIComponent(r.lang),g=`https://suggestqueries.google.com/complete/search?client=firefox&q=${n}&hl=${a}`,e=await fetch(g);if(!e.ok)throw new s("FETCH_ERROR",`HTTP ${e.status}`,"Check your network connection");const o=await e.json(),t=Array.isArray(o)&&Array.isArray(o[1])?o[1]:[];if(!t.length)throw new s("NOT_FOUND","No suggestions found","Try a different keyword");return t.map((c)=>({suggestion:c}))}});
@@ -1 +1 @@
1
- import{cli as D,Strategy as F}from"@jackwener/opencli/registry";import{CliError as q}from"@jackwener/opencli/errors";import{parseRssItems as G}from"./utils.js";D({site:"google",name:"trends",access:"read",description:"Get Google Trends daily trending searches",strategy:F.PUBLIC,browser:!1,args:[{name:"region",default:"US",help:"Region code (e.g. US, CN, JP)"},{name:"limit",type:"int",default:20,help:"Number of results"}],columns:["title","traffic","date"],func:async(f)=>{const z=Math.max(1,Math.min(Number(f.limit),100)),A=`https://trends.google.com/trending/rss?geo=${encodeURIComponent(f.region)}`,b=await fetch(A);if(!b.ok)throw new q("FETCH_ERROR",`HTTP ${b.status}`,"Check your network connection or region code");const B=await b.text(),h=G(B,["title","pubDate","ht:approx_traffic"]);if(!h.length)throw new q("NOT_FOUND","No trending data found","Try a different region code");return h.slice(0,z).map((d)=>({title:d.title,traffic:d["ht:approx_traffic"],date:d.pubDate}))}});
1
+ import{cli as c,Strategy as l}from"@jackwener/opencli/registry";import{CliError as n}from"@jackwener/opencli/errors";import{parseRssItems as f}from"./utils.js";c({site:"google",name:"trends",access:"read",description:"Get Google Trends daily trending searches",strategy:l.PUBLIC,browser:!1,args:[{name:"region",default:"US",help:"Region code (e.g. US, CN, JP)"},{name:"limit",type:"int",default:20,help:"Number of results"}],columns:["title","traffic","date"],func:async(o)=>{const i=Math.max(1,Math.min(Number(o.limit),100)),a=`https://trends.google.com/trending/rss?geo=${encodeURIComponent(o.region)}`,e=await fetch(a);if(!e.ok)throw new n("FETCH_ERROR",`HTTP ${e.status}`,"Check your network connection or region code");const s=await e.text(),r=f(s,["title","pubDate","ht:approx_traffic"]);if(!r.length)throw new n("NOT_FOUND","No trending data found","Try a different region code");return r.slice(0,i).map((t)=>({title:t.title,traffic:t["ht:approx_traffic"],date:t.pubDate}))}});
@@ -1 +1 @@
1
- export function parseRssItems(z,A){return(z.match(/<item>([\s\S]*?)<\/item>/g)||[]).map((B)=>{const j={};for(const q of A){const v=q.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),y=B.match(new RegExp(`<${v}(?:\\s[^>]*)?>(?:<!\\[CDATA\\[)?([\\s\\S]*?)(?:\\]\\]>)?</${v}>`));j[q]=y?y[1].trim():""}return j})}
1
+ export function parseRssItems(r,m){return(r.match(/<item>([\s\S]*?)<\/item>/g)||[]).map((n)=>{const t={};for(const e of m){const s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=n.match(new RegExp(`<${s}(?:\\s[^>]*)?>(?:<!\\[CDATA\\[)?([\\s\\S]*?)(?:\\]\\]>)?</${s}>`));t[e]=c?c[1].trim():""}return t})}
@@ -1 +1 @@
1
- import{cli as K,Strategy as L}from"@jackwener/opencli/registry";import{EmptyResultError as N}from"@jackwener/opencli/errors";import{GOPROXY_BASE as H,goproxyJson as Q,requireModulePath as T,trimDate as U}from"./utils.js";K({site:"goproxy",name:"module",access:"read",description:"Latest version + VCS origin metadata for a Go module on proxy.golang.org",domain:"proxy.golang.org",strategy:L.PUBLIC,browser:!1,args:[{name:"module",positional:!0,type:"string",required:!0,help:'Go module path (e.g. "github.com/gin-gonic/gin", "golang.org/x/net")'}],columns:["module","version","publishedAt","vcs","repository","commit","ref","pkgGoDevUrl","url"],func:async(I)=>{const z=T(I.module),F=z.split("/").map(encodeURIComponent).join("/"),f=await Q(`${H}/${F}/@latest`,`goproxy module ${z}`);if(!f||!f.Version)throw new N("goproxy module",`proxy.golang.org returned no @latest entry for "${z}".`);const C=f.Origin&&typeof f.Origin==="object"?f.Origin:{};return[{module:z,version:String(f.Version),publishedAt:U(f.Time),vcs:String(C.VCS??"").trim(),repository:String(C.URL??"").trim(),commit:String(C.Hash??"").trim(),ref:String(C.Ref??"").trim(),pkgGoDevUrl:`https://pkg.go.dev/${z}`,url:`${H}/${F}/@latest`}]}});
1
+ import{cli as g,Strategy as s}from"@jackwener/opencli/registry";import{EmptyResultError as m}from"@jackwener/opencli/errors";import{GOPROXY_BASE as i,goproxyJson as a,requireModulePath as l,trimDate as p}from"./utils.js";g({site:"goproxy",name:"module",access:"read",description:"Latest version + VCS origin metadata for a Go module on proxy.golang.org",domain:"proxy.golang.org",strategy:s.PUBLIC,browser:!1,args:[{name:"module",positional:!0,type:"string",required:!0,help:'Go module path (e.g. "github.com/gin-gonic/gin", "golang.org/x/net")'}],columns:["module","version","publishedAt","vcs","repository","commit","ref","pkgGoDevUrl","url"],func:async(n)=>{const r=l(n.module),t=r.split("/").map(encodeURIComponent).join("/"),o=await a(`${i}/${t}/@latest`,`goproxy module ${r}`);if(!o||!o.Version)throw new m("goproxy module",`proxy.golang.org returned no @latest entry for "${r}".`);const e=o.Origin&&typeof o.Origin==="object"?o.Origin:{};return[{module:r,version:String(o.Version),publishedAt:p(o.Time),vcs:String(e.VCS??"").trim(),repository:String(e.URL??"").trim(),commit:String(e.Hash??"").trim(),ref:String(e.Ref??"").trim(),pkgGoDevUrl:`https://pkg.go.dev/${r}`,url:`${i}/${t}/@latest`}]}});
@@ -1 +1 @@
1
- import{ArgumentError as D,CommandExecutionError as H,EmptyResultError as Z}from"@jackwener/opencli/errors";export const GOPROXY_BASE="https://proxy.golang.org";const U="opencli-goproxy-adapter (+https://github.com/jackwener/OpenCLI)",G=/^[A-Za-z0-9][A-Za-z0-9._\/-]{0,199}$/,X=/^v[0-9]+(\.[0-9]+)*([-+][A-Za-z0-9._-]+)?$/;export function requireModulePath(z){const q=String(z??"").trim();if(!q)throw new D('goproxy module path is required (e.g. "github.com/gin-gonic/gin", "golang.org/x/net")',"Use the canonical module path that appears in `go.mod`.");if(!G.test(q)||!q.includes("/"))throw new D(`goproxy module path "${z}" is not a recognised Go module path`,'Module paths look like "github.com/<org>/<repo>" or "golang.org/x/<name>".');return q}export function requireVersionTag(z){const q=String(z??"").trim();if(!q)throw new D("goproxy --version cannot be empty");if(!X.test(q))throw new D(`goproxy --version "${z}" is not a valid Go semver tag`,'Use the GOPROXY canonical form like "v1.2.3" or "v0.0.0-20240101010101-abcdef012345".');return q}export function requireBoundedInt(z,q,J,K="limit"){const Q=z??q,W=typeof Q==="number"?Q:Number(Q);if(!Number.isInteger(W)||W<=0)throw new D(`goproxy ${K} must be a positive integer`);if(W>J)throw new D(`goproxy ${K} must be <= ${J}`);return W}async function Y(z,q){let J;try{J=await fetch(z,{headers:{"user-agent":U}})}catch(K){throw new H(`${q} request failed: ${K?.message??K}`,"Check that proxy.golang.org is reachable from this network.")}if(J.status===404||J.status===410)throw new Z(q,`proxy.golang.org returned ${J.status} for ${z}.`);if(J.status===429)throw new H(`${q} returned HTTP 429 (rate limited)`);if(!J.ok)throw new H(`${q} returned HTTP ${J.status}`);return J}export async function goproxyJson(z,q){const J=await Y(z,q);let K;try{K=await J.json()}catch(Q){throw new H(`${q} returned malformed JSON: ${Q?.message??Q}`)}return K}export async function goproxyText(z,q){return(await Y(z,q)).text()}export function sortVersionsDescending(z){return z.filter((q)=>typeof q==="string"&&X.test(q)).map((q)=>({v:q,parts:T(q)})).sort((q,J)=>_(J.parts,q.parts)).map((q)=>q.v)}function T(z){const q=z.replace(/^v/,""),J=q.indexOf("+"),K=J>=0?q.slice(0,J):q,Q=K.indexOf("-"),W=Q>=0?K.slice(0,Q):K,j=Q>=0?K.slice(Q+1):"";return{numbers:W.split(".").map(($)=>Number.parseInt($,10)).map(($)=>Number.isFinite($)?$:0),pre:j}}function _(z,q){const J=Math.max(z.numbers.length,q.numbers.length);for(let K=0;K<J;K+=1){const Q=z.numbers[K]??0,W=q.numbers[K]??0;if(Q!==W)return Q-W}if(z.pre===""&&q.pre!=="")return 1;if(z.pre!==""&&q.pre==="")return-1;if(z.pre===q.pre)return 0;return B(z.pre,q.pre)}function B(z,q){const J=z.split("."),K=q.split("."),Q=Math.max(J.length,K.length);for(let W=0;W<Q;W+=1){const j=J[W],k=K[W];if(j==null)return-1;if(k==null)return 1;const $=/^\d+$/.test(j),L=/^\d+$/.test(k);if($&&L){const M=Number(j)-Number(k);if(M!==0)return M;continue}if($!==L)return $?-1:1;if(j!==k)return j<k?-1:1}return 0}export function trimDate(z){const q=String(z??"").trim();if(!q)return null;const J=q.replace(/\.\d+/,"");return J.endsWith("Z")?J:q.length>=10?q.slice(0,10):null}
1
+ import{ArgumentError as c,CommandExecutionError as p,EmptyResultError as l}from"@jackwener/opencli/errors";export const GOPROXY_BASE="https://proxy.golang.org";const d="opencli-goproxy-adapter (+https://github.com/jackwener/OpenCLI)",w=/^[A-Za-z0-9][A-Za-z0-9._\/-]{0,199}$/,f=/^v[0-9]+(\.[0-9]+)*([-+][A-Za-z0-9._-]+)?$/;export function requireModulePath(r){const t=String(r??"").trim();if(!t)throw new c('goproxy module path is required (e.g. "github.com/gin-gonic/gin", "golang.org/x/net")',"Use the canonical module path that appears in `go.mod`.");if(!w.test(t)||!t.includes("/"))throw new c(`goproxy module path "${r}" is not a recognised Go module path`,'Module paths look like "github.com/<org>/<repo>" or "golang.org/x/<name>".');return t}export function requireVersionTag(r){const t=String(r??"").trim();if(!t)throw new c("goproxy --version cannot be empty");if(!f.test(t))throw new c(`goproxy --version "${r}" is not a valid Go semver tag`,'Use the GOPROXY canonical form like "v1.2.3" or "v0.0.0-20240101010101-abcdef012345".');return t}export function requireBoundedInt(r,t,e,n="limit"){const o=r??t,s=typeof o==="number"?o:Number(o);if(!Number.isInteger(s)||s<=0)throw new c(`goproxy ${n} must be a positive integer`);if(s>e)throw new c(`goproxy ${n} must be <= ${e}`);return s}async function h(r,t){let e;try{e=await fetch(r,{headers:{"user-agent":d}})}catch(n){throw new p(`${t} request failed: ${n?.message??n}`,"Check that proxy.golang.org is reachable from this network.")}if(e.status===404||e.status===410)throw new l(t,`proxy.golang.org returned ${e.status} for ${r}.`);if(e.status===429)throw new p(`${t} returned HTTP 429 (rate limited)`);if(!e.ok)throw new p(`${t} returned HTTP ${e.status}`);return e}export async function goproxyJson(r,t){const e=await h(r,t);let n;try{n=await e.json()}catch(o){throw new p(`${t} returned malformed JSON: ${o?.message??o}`)}return n}export async function goproxyText(r,t){return(await h(r,t)).text()}export function sortVersionsDescending(r){return r.filter((t)=>typeof t==="string"&&f.test(t)).map((t)=>({v:t,parts:x(t)})).sort((t,e)=>y(e.parts,t.parts)).map((t)=>t.v)}function x(r){const t=r.replace(/^v/,""),e=t.indexOf("+"),n=e>=0?t.slice(0,e):t,o=n.indexOf("-"),s=o>=0?n.slice(0,o):n,u=o>=0?n.slice(o+1):"";return{numbers:s.split(".").map((i)=>Number.parseInt(i,10)).map((i)=>Number.isFinite(i)?i:0),pre:u}}function y(r,t){const e=Math.max(r.numbers.length,t.numbers.length);for(let n=0;n<e;n+=1){const o=r.numbers[n]??0,s=t.numbers[n]??0;if(o!==s)return o-s}if(r.pre===""&&t.pre!=="")return 1;if(r.pre!==""&&t.pre==="")return-1;if(r.pre===t.pre)return 0;return b(r.pre,t.pre)}function b(r,t){const e=r.split("."),n=t.split("."),o=Math.max(e.length,n.length);for(let s=0;s<o;s+=1){const u=e[s],a=n[s];if(u==null)return-1;if(a==null)return 1;const i=/^\d+$/.test(u),m=/^\d+$/.test(a);if(i&&m){const g=Number(u)-Number(a);if(g!==0)return g;continue}if(i!==m)return i?-1:1;if(u!==a)return u<a?-1:1}return 0}export function trimDate(r){const t=String(r??"").trim();if(!t)return null;const e=t.replace(/\.\d+/,"");return e.endsWith("Z")?e:t.length>=10?t.slice(0,10):null}
@@ -1 +1 @@
1
- import{cli as $,Strategy as f}from"@jackwener/opencli/registry";import{EmptyResultError as U}from"@jackwener/opencli/errors";import{GOPROXY_BASE as K,goproxyJson as I,goproxyText as J,requireBoundedInt as M,requireModulePath as V,sortVersionsDescending as D,trimDate as T}from"./utils.js";$({site:"goproxy",name:"versions",access:"read",description:"Published version tags for a Go module (newest first), optionally with publish times",domain:"proxy.golang.org",strategy:f.PUBLIC,browser:!1,args:[{name:"module",positional:!0,type:"string",required:!0,help:'Go module path (e.g. "github.com/gin-gonic/gin")'},{name:"limit",type:"int",default:30,help:"Max rows to return (1-200)"},{name:"with-time",type:"boolean",default:!1,help:"Fetch each version's publish time (one extra request per row)"}],columns:["rank","module","version","publishedAt","url"],func:async(C)=>{const z=V(C.module),W=M(C.limit,30,200,"limit"),Z=C["with-time"]===!0,F=z.split("/").map(encodeURIComponent).join("/"),L=(await J(`${K}/${F}/@v/list`,`goproxy versions ${z}`)).split(/\r?\n/).map((b)=>b.trim()).filter(Boolean);if(L.length===0)throw new U("goproxy versions",`proxy.golang.org returned no published versions for "${z}".`);const N=D(L).slice(0,W);if(N.length===0)throw new U("goproxy versions",`"${z}" has no semver-shaped tags on proxy.golang.org.`);const Q=N.map((b,H)=>({rank:H+1,module:z,version:b,publishedAt:null,url:`${K}/${F}/@v/${encodeURIComponent(b)}.info`}));if(Z)for(const b of Q){const H=await I(`${K}/${F}/@v/${encodeURIComponent(b.version)}.info`,`goproxy versions ${z} ${b.version}`);b.publishedAt=T(H?.Time)}return Q}});
1
+ import{cli as d,Strategy as g}from"@jackwener/opencli/registry";import{EmptyResultError as m}from"@jackwener/opencli/errors";import{GOPROXY_BASE as i,goproxyJson as c,goproxyText as h,requireBoundedInt as f,requireModulePath as y,sortVersionsDescending as w,trimDate as v}from"./utils.js";d({site:"goproxy",name:"versions",access:"read",description:"Published version tags for a Go module (newest first), optionally with publish times",domain:"proxy.golang.org",strategy:g.PUBLIC,browser:!1,args:[{name:"module",positional:!0,type:"string",required:!0,help:'Go module path (e.g. "github.com/gin-gonic/gin")'},{name:"limit",type:"int",default:30,help:"Max rows to return (1-200)"},{name:"with-time",type:"boolean",default:!1,help:"Fetch each version's publish time (one extra request per row)"}],columns:["rank","module","version","publishedAt","url"],func:async(t)=>{const e=y(t.module),p=f(t.limit,30,200,"limit"),u=t["with-time"]===!0,r=e.split("/").map(encodeURIComponent).join("/"),s=(await h(`${i}/${r}/@v/list`,`goproxy versions ${e}`)).split(/\r?\n/).map((o)=>o.trim()).filter(Boolean);if(s.length===0)throw new m("goproxy versions",`proxy.golang.org returned no published versions for "${e}".`);const l=w(s).slice(0,p);if(l.length===0)throw new m("goproxy versions",`"${e}" has no semver-shaped tags on proxy.golang.org.`);const a=l.map((o,n)=>({rank:n+1,module:e,version:o,publishedAt:null,url:`${i}/${r}/@v/${encodeURIComponent(o)}.info`}));if(u)for(const o of a){const n=await c(`${i}/${r}/@v/${encodeURIComponent(o.version)}.info`,`goproxy versions ${e} ${o.version}`);o.publishedAt=v(n?.Time)}return a}});
@@ -1,8 +1,8 @@
1
- import{cli as O,Strategy as Q}from"@jackwener/opencli/registry";import{classifyExtractorFailure as T,parseGovPolicyLimit as U,requireRows as V,wrapBrowserError as W}from"./utils.js";export function extractRecentRows(){const C=(A)=>(A||"").replace(/\s+/g," ").trim(),I=document.querySelectorAll(".news_box li, .list li, .list_item, .news-list li");if(I.length===0){const A=document.body;return{ok:!1,sample:(A&&(A.innerText||A.textContent)||"").slice(0,800),url:location.href}}const D=[];for(const A of I){const J=A.querySelector("a"),K=C(J?.textContent);if(!K||K.length<4)continue;let H=J?.getAttribute("href")||"";if(H&&!H.startsWith("http"))H="https://www.gov.cn"+H;const M=(A.textContent||"").match(/(\d{4}[-./]\d{1,2}[-./]\d{1,2})/)?.[1]||"",N=C(A.querySelector(".source, .from")?.textContent);D.push({rank:D.length+1,title:K,date:M,source:N,url:H})}return{ok:!0,rows:D}}O({site:"gov-policy",name:"recent",access:"read",description:"国务院最新政策文件",domain:"www.gov.cn",strategy:Q.PUBLIC,browser:!0,args:[{name:"limit",type:"int",default:10,help:"返回结果数量 (max 20)"}],columns:["rank","title","date","source","url"],func:async(C,I)=>{const D=U(I.limit,"recent");try{await C.goto("https://www.gov.cn/zhengce/zuixin/index.htm");await C.wait(4);await C.evaluate(`
1
+ import{cli as a,Strategy as u}from"@jackwener/opencli/registry";import{classifyExtractorFailure as m,parseGovPolicyLimit as w,requireRows as f,wrapBrowserError as d}from"./utils.js";export function extractRecentRows(){const e=(t)=>(t||"").replace(/\s+/g," ").trim(),i=document.querySelectorAll(".news_box li, .list li, .list_item, .news-list li");if(i.length===0){const t=document.body;return{ok:!1,sample:(t&&(t.innerText||t.textContent)||"").slice(0,800),url:location.href}}const r=[];for(const t of i){const n=t.querySelector("a"),s=e(n?.textContent);if(!s||s.length<4)continue;let o=n?.getAttribute("href")||"";if(o&&!o.startsWith("http"))o="https://www.gov.cn"+o;const c=(t.textContent||"").match(/(\d{4}[-./]\d{1,2}[-./]\d{1,2})/)?.[1]||"",l=e(t.querySelector(".source, .from")?.textContent);r.push({rank:r.length+1,title:s,date:c,source:l,url:o})}return{ok:!0,rows:r}}a({site:"gov-policy",name:"recent",access:"read",description:"国务院最新政策文件",domain:"www.gov.cn",strategy:u.PUBLIC,browser:!0,args:[{name:"limit",type:"int",default:10,help:"返回结果数量 (max 20)"}],columns:["rank","title","date","source","url"],func:async(e,i)=>{const r=w(i.limit,"recent");try{await e.goto("https://www.gov.cn/zhengce/zuixin/index.htm");await e.wait(4);await e.evaluate(`
2
2
  (async () => {
3
3
  for (let i = 0; i < 20; i++) {
4
4
  if (document.querySelector('.news_box li, .list li, .list_item, .news-list li')) break;
5
5
  await new Promise(r => setTimeout(r, 500));
6
6
  }
7
7
  })()
8
- `);const A=await C.evaluate(`(${extractRecentRows.toString()})()`);if(!A||!A.ok)T("recent",A);return V("recent",A.rows).slice(0,D)}catch(A){W("recent",A)}}});
8
+ `);const t=await e.evaluate(`(${extractRecentRows.toString()})()`);if(!t||!t.ok)m("recent",t);return f("recent",t.rows).slice(0,r)}catch(t){d("recent",t)}}});
@@ -1,8 +1,8 @@
1
- import{cli as T,Strategy as U}from"@jackwener/opencli/registry";import{requireNonEmptyQuery as V}from"../_shared/common.js";import{classifyExtractorFailure as W,parseGovPolicyLimit as X,requireRows as Y,wrapBrowserError as Z}from"./utils.js";export function extractSearchRows(){const D=(A)=>(A||"").replace(/\s+/g," ").trim(),H=document.querySelectorAll(".basic_result_content .item, .js_basic_result_content .item");if(H.length===0){const A=document.body;return{ok:!1,sample:(A&&(A.innerText||A.textContent)||"").slice(0,800),url:location.href}}const I=[];for(const A of H){const C=A.querySelector("a.title, .title a, a.log-anchor"),K=D(C?.textContent).replace(/<[^>]+>/g,"");if(!K||K.length<4)continue;let J=C?.getAttribute("href")||"";if(J&&!J.startsWith("http"))J="https://www.gov.cn"+J;const M=D(A.querySelector(".description")?.textContent).slice(0,120),O=(A.textContent||"").match(/(\d{4}[-./]\d{1,2}[-./]\d{1,2})/)?.[1]||"";I.push({rank:I.length+1,title:K,description:M,date:O,url:J})}return{ok:!0,rows:I}}T({site:"gov-policy",name:"search",access:"read",description:"中国政府网政策文件搜索",domain:"sousuo.www.gov.cn",strategy:U.PUBLIC,browser:!0,args:[{name:"query",positional:!0,required:!0,help:"搜索关键词"},{name:"limit",type:"int",default:10,help:"返回结果数量 (max 20)"}],columns:["rank","title","description","date","url"],func:async(D,H)=>{const I=X(H.limit,"search"),A=V(H.query);try{await D.goto(`https://sousuo.www.gov.cn/sousuo/search.shtml?code=17da70961a7&dataTypeId=107&searchWord=${encodeURIComponent(A)}`);await D.wait(5);await D.evaluate(`
1
+ import{cli as l,Strategy as u}from"@jackwener/opencli/registry";import{requireNonEmptyQuery as m}from"../_shared/common.js";import{classifyExtractorFailure as h,parseGovPolicyLimit as d,requireRows as p,wrapBrowserError as w}from"./utils.js";export function extractSearchRows(){const r=(t)=>(t||"").replace(/\s+/g," ").trim(),o=document.querySelectorAll(".basic_result_content .item, .js_basic_result_content .item");if(o.length===0){const t=document.body;return{ok:!1,sample:(t&&(t.innerText||t.textContent)||"").slice(0,800),url:location.href}}const s=[];for(const t of o){const e=t.querySelector("a.title, .title a, a.log-anchor"),n=r(e?.textContent).replace(/<[^>]+>/g,"");if(!n||n.length<4)continue;let i=e?.getAttribute("href")||"";if(i&&!i.startsWith("http"))i="https://www.gov.cn"+i;const c=r(t.querySelector(".description")?.textContent).slice(0,120),a=(t.textContent||"").match(/(\d{4}[-./]\d{1,2}[-./]\d{1,2})/)?.[1]||"";s.push({rank:s.length+1,title:n,description:c,date:a,url:i})}return{ok:!0,rows:s}}l({site:"gov-policy",name:"search",access:"read",description:"中国政府网政策文件搜索",domain:"sousuo.www.gov.cn",strategy:u.PUBLIC,browser:!0,args:[{name:"query",positional:!0,required:!0,help:"搜索关键词"},{name:"limit",type:"int",default:10,help:"返回结果数量 (max 20)"}],columns:["rank","title","description","date","url"],func:async(r,o)=>{const s=d(o.limit,"search"),t=m(o.query);try{await r.goto(`https://sousuo.www.gov.cn/sousuo/search.shtml?code=17da70961a7&dataTypeId=107&searchWord=${encodeURIComponent(t)}`);await r.wait(5);await r.evaluate(`
2
2
  (async () => {
3
3
  for (let i = 0; i < 30; i++) {
4
4
  if (document.querySelectorAll('.basic_result_content .item, .js_basic_result_content .item').length > 0) break;
5
5
  await new Promise(r => setTimeout(r, 500));
6
6
  }
7
7
  })()
8
- `);const C=await D.evaluate(`(${extractSearchRows.toString()})()`);if(!C||!C.ok)W("search",C);return Y("search",C.rows).slice(0,I)}catch(C){Z("search",C)}}});
8
+ `);const e=await r.evaluate(`(${extractSearchRows.toString()})()`);if(!e||!e.ok)h("search",e);return p("search",e.rows).slice(0,s)}catch(e){w("search",e)}}});
package/clis/grok/ask.js CHANGED
@@ -1 +1 @@
1
- import{cli as X,Strategy as Y}from"@jackwener/opencli/registry";import{CommandExecutionError as Z,TimeoutError as $}from"@jackwener/opencli/errors";import{authRequired as q,ensureOnGrok as z,getMessageBubbles as G,isLoggedIn as H,normalizeBooleanFlag as _,sendMessage as x,startNewChat as y,waitForAnswer as C}from"./utils.js";const F="Likely login/auth/challenge/session issue in the existing grok.com browser session.";async function Q(f){const v=await G(f);for(let D=v.length-1;D>=0;D-=1)if(v[D].role==="Assistant")return v[D].id;return""}export const askCommand=X({site:"grok",name:"ask",access:"write",description:"Send a message to Grok and get response",domain:"grok.com",strategy:Y.COOKIE,browser:!0,siteSession:"persistent",args:[{name:"prompt",fromFile:!0,positional:!0,type:"string",required:!0,help:"Prompt to send to Grok"},{name:"timeout",type:"int",default:120,help:"Max seconds to wait for response (default: 120)"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending (default: false)"}],columns:["response"],func:async(f,v)=>{const D=v.prompt,P=v.timeout||120;if(_(v.new))await y(f);else await z(f);if(!await H(f))throw q();const U=await Q(f),J=await x(f,D);if(!J||!J.ok){const V=J?.reason||"Unable to send the prompt to Grok.",W=J?.detail?` ${J.detail}`:"";throw new Z(`${V}${W}`,F)}const K=await C(f,D,P,U);if(K.status==="ok")return[{response:K.assistant.text}];if(K.status==="partial"&&K.assistant)return[{response:K.assistant.text}];throw new $("grok ask response",P)}}),__test__={getBaselineLastAssistantId:Q};
1
+ import{cli as m,Strategy as c}from"@jackwener/opencli/registry";import{CommandExecutionError as d,TimeoutError as p}from"@jackwener/opencli/errors";import{authRequired as w,ensureOnGrok as f,getMessageBubbles as h,isLoggedIn as g,normalizeBooleanFlag as k,sendMessage as b,startNewChat as y,waitForAnswer as S}from"./utils.js";const x="Likely login/auth/challenge/session issue in the existing grok.com browser session.";async function r(t){const e=await h(t);for(let s=e.length-1;s>=0;s-=1)if(e[s].role==="Assistant")return e[s].id;return""}export const askCommand=m({site:"grok",name:"ask",access:"write",description:"Send a message to Grok and get response",domain:"grok.com",strategy:c.COOKIE,browser:!0,siteSession:"persistent",args:[{name:"prompt",fromFile:!0,positional:!0,type:"string",required:!0,help:"Prompt to send to Grok"},{name:"timeout",type:"int",default:120,help:"Max seconds to wait for response (default: 120)"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending (default: false)"}],columns:["response"],func:async(t,e)=>{const s=e.prompt,a=e.timeout||120;if(k(e.new))await y(t);else await f(t);if(!await g(t))throw w();const i=await r(t),o=await b(t,s);if(!o||!o.ok){const l=o?.reason||"Unable to send the prompt to Grok.",u=o?.detail?` ${o.detail}`:"";throw new d(`${l}${u}`,x)}const n=await S(t,s,a,i);if(n.status==="ok")return[{response:n.assistant.text}];if(n.status==="partial"&&n.assistant)return[{response:n.assistant.text}];throw new p("grok ask response",a)}}),__test__={getBaselineLastAssistantId:r};
@@ -1 +1 @@
1
- import{cli as X,Strategy as Y}from"@jackwener/opencli/registry";import{EmptyResultError as Z}from"@jackwener/opencli/errors";import{GROK_DOMAIN as $,bubbleHtmlToMarkdown as z,getMessageBubbles as F,normalizeBooleanFlag as H,parseGrokSessionId as K}from"./utils.js";X({site:"grok",name:"detail",access:"read",description:"Open a Grok conversation by ID and read its messages",domain:$,strategy:Y.COOKIE,browser:!0,navigateBefore:!1,siteSession:"persistent",args:[{name:"id",positional:!0,required:!0,help:"Session ID (UUID) or full https://grok.com/c/<id> URL"},{name:"markdown",type:"boolean",default:!1,help:"Emit assistant replies as markdown"}],columns:["Role","Text"],func:async(q,x)=>{const C=K(x.id),J=H(x.markdown,!1);await q.goto(`https://grok.com/c/${C}`);await q.wait(2);let v=[];const Q=20000,U=1,W=Date.now();while(Date.now()-W<Q){v=await F(q);if(v.length>0)break;await q.wait(U)}if(!v.length)throw new Z("grok detail",`No visible messages found for conversation ${C}. Verify the ID is correct and that the conversation belongs to the signed-in account.`);return v.map((f)=>({Role:f.role,Text:J&&f.role==="Assistant"&&f.html?z(f.html)||f.text:f.text}))}});
1
+ import{cli as m,Strategy as c}from"@jackwener/opencli/registry";import{EmptyResultError as d}from"@jackwener/opencli/errors";import{GROK_DOMAIN as w,bubbleHtmlToMarkdown as f,getMessageBubbles as u,normalizeBooleanFlag as g,parseGrokSessionId as h}from"./utils.js";m({site:"grok",name:"detail",access:"read",description:"Open a Grok conversation by ID and read its messages",domain:w,strategy:c.COOKIE,browser:!0,navigateBefore:!1,siteSession:"persistent",args:[{name:"id",positional:!0,required:!0,help:"Session ID (UUID) or full https://grok.com/c/<id> URL"},{name:"markdown",type:"boolean",default:!1,help:"Emit assistant replies as markdown"}],columns:["Role","Text"],func:async(t,s)=>{const a=h(s.id),r=g(s.markdown,!1);await t.goto(`https://grok.com/c/${a}`);await t.wait(2);let o=[];const n=20000,i=1,l=Date.now();while(Date.now()-l<n){o=await u(t);if(o.length>0)break;await t.wait(i)}if(!o.length)throw new d("grok detail",`No visible messages found for conversation ${a}. Verify the ID is correct and that the conversation belongs to the signed-in account.`);return o.map((e)=>({Role:e.role,Text:r&&e.role==="Assistant"&&e.html?f(e.html)||e.text:e.text}))}});
@@ -1,4 +1,4 @@
1
- import*as L from"node:fs";import*as k from"node:path";import*as I from"node:crypto";import{cli as f,Strategy as w}from"@jackwener/opencli/registry";import{ArgumentError as S,CommandExecutionError as x,TimeoutError as b}from"@jackwener/opencli/errors";const O="https://grok.com/",h="Likely login/auth/challenge/session issue in the existing grok.com browser session.";function P(q){if(typeof q==="boolean")return q;const Q=String(q??"").trim().toLowerCase();return Q==="true"||Q==="1"||Q==="yes"||Q==="on"}function T(q,Q,W){const Y=Number(q??Q);if(!Number.isInteger(Y)||Y<=0)throw new S(`${W} must be a positive integer`);return Y}function E(q){const Q=new Set,W=[];for(const X of q){if(!X.src||Q.has(X.src))continue;Q.add(X.src);W.push(X)}return W}function F(q){return q.map((Q)=>Q.src).sort().join("|")}function z(q){if(!q)return"jpg";if(q.includes("png"))return"png";if(q.includes("webp"))return"webp";if(q.includes("gif"))return"gif";return"jpg"}function B(q,Q){const W=z(Q),X=I.createHash("sha1").update(q).digest("hex").slice(0,12);return`grok-${Date.now()}-${X}.${W}`}async function D(q){const Q=await q.evaluate("window.location.href").catch(()=>"");if(typeof Q!=="string"||!Q)return!1;try{const W=new URL(Q).hostname;return W==="grok.com"||W.endsWith(".grok.com")}catch{return!1}}async function c(q){await q.evaluate(`(() => {
1
+ import*as w from"node:fs";import*as q from"node:path";import*as B from"node:crypto";import{cli as H,Strategy as O}from"@jackwener/opencli/registry";import{ArgumentError as P,CommandExecutionError as y,TimeoutError as R}from"@jackwener/opencli/errors";const S="https://grok.com/",N="Likely login/auth/challenge/session issue in the existing grok.com browser session.";function k(e){if(typeof e==="boolean")return e;const t=String(e??"").trim().toLowerCase();return t==="true"||t==="1"||t==="yes"||t==="on"}function x(e,t,r){const o=Number(e??t);if(!Number.isInteger(o)||o<=0)throw new P(`${r} must be a positive integer`);return o}function v(e){const t=new Set,r=[];for(const n of e){if(!n.src||t.has(n.src))continue;t.add(n.src);r.push(n)}return r}function C(e){return e.map((t)=>t.src).sort().join("|")}function A(e){if(!e)return"jpg";if(e.includes("png"))return"png";if(e.includes("webp"))return"webp";if(e.includes("gif"))return"gif";return"jpg"}function E(e,t){const r=A(t),n=B.createHash("sha1").update(e).digest("hex").slice(0,12);return`grok-${Date.now()}-${n}.${r}`}async function T(e){const t=await e.evaluate("window.location.href").catch(()=>"");if(typeof t!=="string"||!t)return!1;try{const r=new URL(t).hostname;return r==="grok.com"||r.endsWith(".grok.com")}catch{return!1}}async function j(e){await e.evaluate(`(() => {
2
2
  const isVisible = (node) => {
3
3
  if (!(node instanceof HTMLElement)) return false;
4
4
  const rect = node.getBoundingClientRect();
@@ -18,7 +18,7 @@ import*as L from"node:fs";import*as k from"node:path";import*as I from"node:cryp
18
18
  });
19
19
  const target = candidates[0];
20
20
  if (target instanceof HTMLElement) target.click();
21
- })()`)}async function d(q,Q){const W=JSON.stringify(Q);return q.evaluate(`(async () => {
21
+ })()`)}async function U(e,t){const r=JSON.stringify(t);return e.evaluate(`(async () => {
22
22
  try {
23
23
  const waitFor = (ms) => new Promise(resolve => setTimeout(resolve, ms));
24
24
  const composerSelector = '.ProseMirror[contenteditable="true"]';
@@ -56,7 +56,7 @@ import*as L from"node:fs";import*as k from"node:path";import*as I from"node:cryp
56
56
  try {
57
57
  if (pm.editor.commands.clearContent) pm.editor.commands.clearContent();
58
58
  pm.editor.commands.focus();
59
- pm.editor.commands.insertContent(${W});
59
+ pm.editor.commands.insertContent(${r});
60
60
  for (let attempt = 0; attempt < 6; attempt += 1) {
61
61
  const sbtn = Array.from(document.querySelectorAll('button[aria-label="Submit"], button[aria-label="\\u63d0\\u4ea4"]'))
62
62
  .find(isVisibleEnabledSubmit);
@@ -73,7 +73,7 @@ import*as L from"node:fs";import*as k from"node:path";import*as I from"node:cryp
73
73
  if (!box) return { ok: false, msg: 'no composer (neither ProseMirror nor textarea)' };
74
74
  box.focus(); box.value = '';
75
75
  document.execCommand('selectAll');
76
- document.execCommand('insertText', false, ${W});
76
+ document.execCommand('insertText', false, ${r});
77
77
  for (let attempt = 0; attempt < 6; attempt += 1) {
78
78
  const btn = Array.from(document.querySelectorAll('button[aria-label="\\u63d0\\u4ea4"], button[aria-label="Submit"]'))
79
79
  .find(isVisibleEnabledSubmit);
@@ -94,7 +94,7 @@ import*as L from"node:fs";import*as k from"node:path";import*as I from"node:cryp
94
94
  box.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
95
95
  return { ok: true, msg: 'enter' };
96
96
  } catch (e) { return { ok: false, msg: e && e.toString ? e.toString() : String(e) }; }
97
- })()`)}async function y(q){const Q=await q.evaluate(`(() => {
97
+ })()`)}async function I(e){const t=await e.evaluate(`(() => {
98
98
  const bubbles = document.querySelectorAll('div.message-bubble, [data-testid="message-bubble"]');
99
99
  return Array.from(bubbles).map(bubble => Array.from(bubble.querySelectorAll('img'))
100
100
  .map(img => ({
@@ -105,9 +105,9 @@ import*as L from"node:fs";import*as k from"node:path";import*as I from"node:cryp
105
105
  .filter(i => i.src && /^https?:/.test(i.src))
106
106
  // Ignore tiny UI/avatar images that may live in the bubble chrome.
107
107
  .filter(i => (i.w === 0 || i.w >= 128) && (i.h === 0 || i.h >= 128)));
108
- })()`);return(Array.isArray(Q)?Q:[]).map(E)}function R(q,Q){const W=q.slice(Math.max(0,Q));for(let X=W.length-1;X>=0;X-=1)if(W[X].length)return W[X];return[]}async function p(q,Q){const W=JSON.stringify(Q);return q.evaluate(`(async () => {
108
+ })()`);return(Array.isArray(t)?t:[]).map(v)}function L(e,t){const r=e.slice(Math.max(0,t));for(let n=r.length-1;n>=0;n-=1)if(r[n].length)return r[n];return[]}async function V(e,t){const r=JSON.stringify(t);return e.evaluate(`(async () => {
109
109
  try {
110
- const res = await fetch(${W}, { credentials: 'include', referrer: 'https://grok.com/' });
110
+ const res = await fetch(${r}, { credentials: 'include', referrer: 'https://grok.com/' });
111
111
  if (!res.ok) return { ok: false, error: 'HTTP ' + res.status };
112
112
  const blob = await res.blob();
113
113
  const buf = await blob.arrayBuffer();
@@ -116,4 +116,4 @@ import*as L from"node:fs";import*as k from"node:path";import*as I from"node:cryp
116
116
  for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
117
117
  return { ok: true, base64: btoa(binary), contentType: blob.type || 'image/jpeg' };
118
118
  } catch (e) { return { ok: false, error: e && e.message || String(e) }; }
119
- })()`)}async function v(q,Q,W){L.mkdirSync(W,{recursive:!0});const X=[];for(const Y of Q){const Z=await p(q,Y.src);if(!Z||!Z.ok){const M=Z?.error?`: ${Z.error}`:"";throw new x(`Failed to download grok image ${Y.src}${M}`,"assets.grok.com download requires the live grok.com browser session — verify the tab is logged in and try again.")}const H=k.join(W,B(Y.src,Z.contentType));L.writeFileSync(H,Buffer.from(Z.base64||"","base64"));X.push({...Y,path:H})}return X}function K(q,Q=""){return{url:q.src,width:q.w,height:q.h,path:Q}}export const imageCommand=f({site:"grok",name:"image",description:"Generate images on grok.com and return image URLs",access:"write",domain:"grok.com",strategy:w.COOKIE,browser:!0,siteSession:"persistent",args:[{name:"prompt",fromFile:!0,positional:!0,type:"string",required:!0,help:"Image generation prompt"},{name:"timeout",type:"int",default:240,help:"Max seconds to wait for the image (default: 240)"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending (default: false)"},{name:"count",type:"int",default:1,help:"Minimum images to wait for before returning (default: 1)"},{name:"out",type:"string",default:"",help:"Directory to save downloaded images (uses browser session to bypass auth)"}],columns:["url","width","height","path"],func:async(q,Q)=>{const W=Q.prompt,X=(Q.timeout||240)*1000,Y=P(Q.new),Z=T(Q.count,1,"count"),H=(Q.out||"").toString().trim();if(Y){await q.goto(O);await q.wait(2);await c(q);await q.wait(2)}else if(!await D(q)){await q.goto(O);await q.wait(3)}const M=(await y(q)).length,N=await d(q,W);if(!N||!N.ok)throw new x(`Grok composer rejected the prompt: ${JSON.stringify(N)}`,h);const C=Date.now();let V="",U=0,j=[];while(Date.now()-C<X){await q.wait(3);const A=await y(q),$=R(A,M);if($.length>=Z){const J=F($);if(J===V){U+=1;if(U>=2){if(H)return(await v(q,$,H)).map((G)=>K(G,G.path));return $.map((_)=>K(_))}}else{U=0;V=J;j=$}}}if(j.length){if(H)return(await v(q,j,H)).map(($)=>K($,$.path));return j.map((A)=>K(A))}throw new b("grok image generation",Math.round(X/1000))}}),__test__={normalizeBooleanFlag:P,normalizePositiveInteger:T,isOnGrok:D,dedupeBySrc:E,imagesSignature:F,extFromContentType:z,buildFilename:B,pickLatestImageCandidate:R};
119
+ })()`)}async function M(e,t,r){w.mkdirSync(r,{recursive:!0});const n=[];for(const o of t){const i=await V(e,o.src);if(!i||!i.ok){const m=i?.error?`: ${i.error}`:"";throw new y(`Failed to download grok image ${o.src}${m}`,"assets.grok.com download requires the live grok.com browser session — verify the tab is logged in and try again.")}const s=q.join(r,E(o.src,i.contentType));w.writeFileSync(s,Buffer.from(i.base64||"","base64"));n.push({...o,path:s})}return n}function l(e,t=""){return{url:e.src,width:e.w,height:e.h,path:t}}export const imageCommand=H({site:"grok",name:"image",description:"Generate images on grok.com and return image URLs",access:"write",domain:"grok.com",strategy:O.COOKIE,browser:!0,siteSession:"persistent",args:[{name:"prompt",fromFile:!0,positional:!0,type:"string",required:!0,help:"Image generation prompt"},{name:"timeout",type:"int",default:240,help:"Max seconds to wait for the image (default: 240)"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending (default: false)"},{name:"count",type:"int",default:1,help:"Minimum images to wait for before returning (default: 1)"},{name:"out",type:"string",default:"",help:"Directory to save downloaded images (uses browser session to bypass auth)"}],columns:["url","width","height","path"],func:async(e,t)=>{const r=t.prompt,n=(t.timeout||240)*1000,o=k(t.new),i=x(t.count,1,"count"),s=(t.out||"").toString().trim();if(o){await e.goto(S);await e.wait(2);await j(e);await e.wait(2)}else if(!await T(e)){await e.goto(S);await e.wait(3)}const m=(await I(e)).length,d=await U(e,r);if(!d||!d.ok)throw new y(`Grok composer rejected the prompt: ${JSON.stringify(d)}`,N);const F=Date.now();let b="",f=0,c=[];while(Date.now()-F<n){await e.wait(3);const u=await I(e),a=L(u,m);if(a.length>=i){const g=C(a);if(g===b){f+=1;if(f>=2){if(s)return(await M(e,a,s)).map((p)=>l(p,p.path));return a.map((h)=>l(h))}}else{f=0;b=g;c=a}}}if(c.length){if(s)return(await M(e,c,s)).map((a)=>l(a,a.path));return c.map((u)=>l(u))}throw new R("grok image generation",Math.round(n/1000))}}),__test__={normalizeBooleanFlag:k,normalizePositiveInteger:x,isOnGrok:T,dedupeBySrc:v,imagesSignature:C,extFromContentType:A,buildFilename:E,pickLatestImageCandidate:L};
package/clis/grok/pin.js CHANGED
@@ -1 +1 @@
1
- import{cli as D,Strategy as K}from"@jackwener/opencli/registry";import{CommandExecutionError as Y}from"@jackwener/opencli/errors";import{GROK_DOMAIN as F,ensureOnGrok as P,authRequired as R,isLoggedIn as j,parseGrokSessionId as y,clickConversationMenuItem as G,getPinStateFromMenuLabels as H,readConversationMenuLabels as M,waitForConversationPinState as _}from"./utils.js";const Z="Likely login/auth/challenge/session issue in the existing grok.com browser session.";function $(z,q){D({site:"grok",name:z,access:"write",description:`${z==="pin"?"Pin":"Unpin"} a Grok conversation by ID`,domain:F,strategy:K.COOKIE,browser:!0,siteSession:"persistent",args:[{name:"id",positional:!0,type:"string",required:!0,help:"Conversation UUID or grok.com/c/<uuid> URL"}],columns:["status","id"],func:async(B,A)=>{const J=y(A.id);await P(B);if(!await j(B))throw R();const W=z==="pin"?"pinned":"unpinned",Q=await M(B,J);if(!Q.ok){const V=Q.detail?` ${Q.detail}`:"";throw new Y(`${Q.reason||`Failed to inspect ${z} state.`}${V}`,Z)}if(H(Q.labels)===W)return[{status:`already-${W}`,id:J}];const U=await G(B,J,q);if(!U||!U.ok){const V=U?.detail?` ${U.detail}`:"";throw new Y(`${U?.reason||`Failed to ${z} conversation.`}${V}`,Z)}const X=await _(B,J,W);if(!X.ok){const V=X.labels?.length?` labels=${JSON.stringify(X.labels)}`:"";throw new Y(`${z} menu item was clicked, but the conversation did not verify as ${W}.${V}`,Z)}return[{status:z==="pin"?"pinned":"unpinned",id:J}]}})}$("pin",["置顶","pin"]);$("unpin",["取消置顶","unpin"]);
1
+ import{cli as w,Strategy as f}from"@jackwener/opencli/registry";import{CommandExecutionError as l}from"@jackwener/opencli/errors";import{GROK_DOMAIN as g,ensureOnGrok as b,authRequired as k,isLoggedIn as h,parseGrokSessionId as m,clickConversationMenuItem as S,getPinStateFromMenuLabels as v,readConversationMenuLabels as y,waitForConversationPinState as I}from"./utils.js";const d="Likely login/auth/challenge/session issue in the existing grok.com browser session.";function c(e,u){w({site:"grok",name:e,access:"write",description:`${e==="pin"?"Pin":"Unpin"} a Grok conversation by ID`,domain:g,strategy:f.COOKIE,browser:!0,siteSession:"persistent",args:[{name:"id",positional:!0,type:"string",required:!0,help:"Conversation UUID or grok.com/c/<uuid> URL"}],columns:["status","id"],func:async(i,p)=>{const t=m(p.id);await b(i);if(!await h(i))throw k();const r=e==="pin"?"pinned":"unpinned",n=await y(i,t);if(!n.ok){const s=n.detail?` ${n.detail}`:"";throw new l(`${n.reason||`Failed to inspect ${e} state.`}${s}`,d)}if(v(n.labels)===r)return[{status:`already-${r}`,id:t}];const o=await S(i,t,u);if(!o||!o.ok){const s=o?.detail?` ${o.detail}`:"";throw new l(`${o?.reason||`Failed to ${e} conversation.`}${s}`,d)}const a=await I(i,t,r);if(!a.ok){const s=a.labels?.length?` labels=${JSON.stringify(a.labels)}`:"";throw new l(`${e} menu item was clicked, but the conversation did not verify as ${r}.${s}`,d)}return[{status:e==="pin"?"pinned":"unpinned",id:t}]}})}c("pin",["置顶","pin"]);c("unpin",["取消置顶","unpin"]);
package/clis/grok/send.js CHANGED
@@ -1 +1 @@
1
- import{cli as Q,Strategy as T}from"@jackwener/opencli/registry";import{ArgumentError as U,CommandExecutionError as V}from"@jackwener/opencli/errors";import{GROK_DOMAIN as W,authRequired as X,ensureOnGrok as Y,isLoggedIn as Z,normalizeBooleanFlag as $,sendMessage as q,startNewChat as z}from"./utils.js";Q({site:"grok",name:"send",access:"write",description:"Fire-and-forget: send a prompt to Grok without waiting for the reply",domain:W,strategy:T.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"prompt",fromFile:!0,required:!0,positional:!0,help:"Prompt to send to Grok"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending"}],columns:["Status","Prompt"],func:async(b,H)=>{const v=String(H.prompt||"").trim();if(!v)throw new U("prompt","is required");const P=$(H.new,!1);await Y(b);if(P)await z(b);const J=await q(b,v);if(!J?.ok){if(!await Z(b))throw X();throw new V(J?.reason||"Failed to send Grok prompt")}return[{Status:"sent",Prompt:v}]}});
1
+ import{cli as a,Strategy as i}from"@jackwener/opencli/registry";import{ArgumentError as s,CommandExecutionError as m}from"@jackwener/opencli/errors";import{GROK_DOMAIN as p,authRequired as u,ensureOnGrok as d,isLoggedIn as f,normalizeBooleanFlag as l,sendMessage as w,startNewChat as c}from"./utils.js";a({site:"grok",name:"send",access:"write",description:"Fire-and-forget: send a prompt to Grok without waiting for the reply",domain:p,strategy:i.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"prompt",fromFile:!0,required:!0,positional:!0,help:"Prompt to send to Grok"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending"}],columns:["Status","Prompt"],func:async(t,r)=>{const e=String(r.prompt||"").trim();if(!e)throw new s("prompt","is required");const n=l(r.new,!1);await d(t);if(n)await c(t);const o=await w(t,e);if(!o?.ok){if(!await f(t))throw u();throw new m(o?.reason||"Failed to send Grok prompt")}return[{Status:"sent",Prompt:e}]}});
@@ -1 +1 @@
1
- import{cli as E,Strategy as F}from"@jackwener/opencli/registry";import{GROK_DOMAIN as H,ensureOnGrok as J,getCurrentSessionId as P,getModelLabel as Q,isLoggedIn as T}from"./utils.js";E({site:"grok",name:"status",access:"read",description:"Check Grok page availability, login state, current session and model",domain:H,strategy:F.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:["Status","Login","Model","SessionId","Url"],func:async(q)=>{await J(q);await q.wait(2);const[B,v,x,z]=await Promise.all([T(q),P(q),Q(q),q.evaluate("window.location.href").catch(()=>"")]);return[{Status:"Connected",Login:B?"Yes":"No",Model:x?x:null,SessionId:v?v:null,Url:typeof z==="string"?z:""}]}});
1
+ import{cli as i,Strategy as r}from"@jackwener/opencli/registry";import{GROK_DOMAIN as a,ensureOnGrok as l,getCurrentSessionId as d,getModelLabel as c,isLoggedIn as u}from"./utils.js";i({site:"grok",name:"status",access:"read",description:"Check Grok page availability, login state, current session and model",domain:a,strategy:r.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:["Status","Login","Model","SessionId","Url"],func:async(e)=>{await l(e);await e.wait(2);const[n,s,t,o]=await Promise.all([u(e),d(e),c(e),e.evaluate("window.location.href").catch(()=>"")]);return[{Status:"Connected",Login:n?"Yes":"No",Model:t?t:null,SessionId:s?s:null,Url:typeof o==="string"?o:""}]}});
@@ -1,4 +1,4 @@
1
- import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError as j,AuthRequiredError as z}from"@jackwener/opencli/errors";export const GROK_DOMAIN="grok.com",GROK_URL="https://grok.com/",IS_VISIBLE_JS=`
1
+ import{htmlToMarkdown as b}from"@jackwener/opencli/utils";import{ArgumentError as c,AuthRequiredError as h}from"@jackwener/opencli/errors";export const GROK_DOMAIN="grok.com",GROK_URL="https://grok.com/",IS_VISIBLE_JS=`
2
2
  const isVisible = (node) => {
3
3
  if (!(node instanceof Element)) return false;
4
4
  const style = window.getComputedStyle(node);
@@ -6,7 +6,7 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
6
6
  const rect = node.getBoundingClientRect();
7
7
  return rect.width > 0 && rect.height > 0;
8
8
  };
9
- `;export function authRequired(H){return new z(GROK_DOMAIN,H||"Sign in to grok.com in your browser, then retry.")}export function normalizeBooleanFlag(H,Y=!1){if(typeof H==="boolean")return H;if(H==null||H==="")return Y;const X=String(H).trim().toLowerCase();return X==="true"||X==="1"||X==="yes"||X==="on"}const F=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;export function parseGrokSessionId(H){const Y=String(H??"").trim();if(!Y)throw new j("id","must be a non-empty session ID or grok.com chat URL");let X=Y;if(/^[a-z][a-z0-9+.-]*:\/\//i.test(Y)){let q;try{q=new URL(Y)}catch{throw new j("id",`not a valid Grok URL (got "${H}")`)}const Z=q.hostname.toLowerCase(),$=q.pathname.match(/^\/c\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/?$/i);if(q.protocol!=="https:"||Z!=="grok.com"&&!Z.endsWith(".grok.com")||!$)throw new j("id",`not a valid Grok conversation URL (got "${H}"); expected https://grok.com/c/<id>`);X=$[1]}if(!F.test(X))throw new j("id",`not a valid Grok session ID (got "${H}"); expected a UUID like "7c4197f2-10a1-4ebb-a84a-fea89f4f1d06" or a full https://grok.com/c/<id> URL`);return X.toLowerCase()}export async function isOnGrok(H){const Y=await H.evaluate("window.location.href").catch(()=>"");if(typeof Y!=="string"||!Y)return!1;try{const X=new URL(Y).hostname;return X==="grok.com"||X.endsWith(".grok.com")}catch{return!1}}export async function ensureOnGrok(H){if(await isOnGrok(H))return;await H.goto(GROK_URL);await H.wait(2)}export async function isLoggedIn(H){const Y=await H.evaluate(`(() => {
9
+ `;export function authRequired(t){return new h(GROK_DOMAIN,t||"Sign in to grok.com in your browser, then retry.")}export function normalizeBooleanFlag(t,n=!1){if(typeof t==="boolean")return t;if(t==null||t==="")return n;const e=String(t).trim().toLowerCase();return e==="true"||e==="1"||e==="yes"||e==="on"}const d=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;export function parseGrokSessionId(t){const n=String(t??"").trim();if(!n)throw new c("id","must be a non-empty session ID or grok.com chat URL");let e=n;if(/^[a-z][a-z0-9+.-]*:\/\//i.test(n)){let i;try{i=new URL(n)}catch{throw new c("id",`not a valid Grok URL (got "${t}")`)}const o=i.hostname.toLowerCase(),r=i.pathname.match(/^\/c\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/?$/i);if(i.protocol!=="https:"||o!=="grok.com"&&!o.endsWith(".grok.com")||!r)throw new c("id",`not a valid Grok conversation URL (got "${t}"); expected https://grok.com/c/<id>`);e=r[1]}if(!d.test(e))throw new c("id",`not a valid Grok session ID (got "${t}"); expected a UUID like "7c4197f2-10a1-4ebb-a84a-fea89f4f1d06" or a full https://grok.com/c/<id> URL`);return e.toLowerCase()}export async function isOnGrok(t){const n=await t.evaluate("window.location.href").catch(()=>"");if(typeof n!=="string"||!n)return!1;try{const e=new URL(n).hostname;return e==="grok.com"||e.endsWith(".grok.com")}catch{return!1}}export async function ensureOnGrok(t){if(await isOnGrok(t))return;await t.goto(GROK_URL);await t.wait(2)}export async function isLoggedIn(t){const n=await t.evaluate(`(() => {
10
10
  ${IS_VISIBLE_JS}
11
11
  const composer = document.querySelector('.ProseMirror[contenteditable="true"]');
12
12
  if (composer && isVisible(composer)) {
@@ -15,9 +15,9 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
15
15
  return !signInCta;
16
16
  }
17
17
  return false;
18
- })()`);return Boolean(Y)}export async function getCurrentSessionId(H){const Y=await H.evaluate("window.location.href").catch(()=>"");if(typeof Y!=="string")return"";const X=Y.match(/\/c\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);return X?X[1].toLowerCase():""}const B=["#model-select-trigger",'button[aria-label="Model select"]','button[aria-label="模型选择"]','button[aria-label="モデル選択"]'];export async function getModelLabel(H){const Y=JSON.stringify(B),X=await H.evaluate(`(() => {
18
+ })()`);return Boolean(n)}export async function getCurrentSessionId(t){const n=await t.evaluate("window.location.href").catch(()=>"");if(typeof n!=="string")return"";const e=n.match(/\/c\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);return e?e[1].toLowerCase():""}const w=["#model-select-trigger",'button[aria-label="Model select"]','button[aria-label="模型选择"]','button[aria-label="モデル選択"]'];export async function getModelLabel(t){const n=JSON.stringify(w),e=await t.evaluate(`(() => {
19
19
  ${IS_VISIBLE_JS}
20
- const selectors = ${Y};
20
+ const selectors = ${n};
21
21
  let trigger = null;
22
22
  for (const sel of selectors) {
23
23
  trigger = Array.from(document.querySelectorAll(sel)).find((node) => isVisible(node));
@@ -25,7 +25,7 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
25
25
  }
26
26
  if (!trigger) return '';
27
27
  return (trigger.innerText || trigger.textContent || '').trim().split('\\n')[0].trim();
28
- })()`);return typeof X==="string"?X:""}export async function getMessageBubbles(H){const Y=await H.evaluate(`(() => {
28
+ })()`);return typeof e==="string"?e:""}export async function getMessageBubbles(t){const n=await t.evaluate(`(() => {
29
29
  ${IS_VISIBLE_JS}
30
30
  const findResponseId = (node) => {
31
31
  let parent = node.parentElement;
@@ -51,7 +51,7 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
51
51
  out.push({ id, role: isAssistant ? 'Assistant' : 'User', text, html });
52
52
  }
53
53
  return out;
54
- })()`);if(!Array.isArray(Y))return[];return Y.map((X)=>({id:String(X?.id||""),role:X?.role==="Assistant"?"Assistant":"User",text:String(X?.text||"").trim(),html:String(X?.html||"")})).filter((X)=>X.id&&(X.text||X.html))}export function bubbleHtmlToMarkdown(H){try{return k(H).trim()}catch{return(H||"").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}}export async function getHistoryFromSidebar(H,Y){const X=await H.evaluate(`(() => {
54
+ })()`);if(!Array.isArray(n))return[];return n.map((e)=>({id:String(e?.id||""),role:e?.role==="Assistant"?"Assistant":"User",text:String(e?.text||"").trim(),html:String(e?.html||"")})).filter((e)=>e.id&&(e.text||e.html))}export function bubbleHtmlToMarkdown(t){try{return b(t).trim()}catch{return(t||"").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}}export async function getHistoryFromSidebar(t,n){const e=await t.evaluate(`(() => {
55
55
  ${IS_VISIBLE_JS}
56
56
  const re = /^\\/c\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
57
57
  const seen = new Set();
@@ -86,10 +86,10 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
86
86
  }
87
87
  }
88
88
  return out.map((entry) => ({ id: entry.id, title: titleById.get(entry.id) || entry.title }));
89
- })()`);if(!Array.isArray(X))return[];return X.slice(0,Y).map((Z)=>({id:String(Z?.id||""),title:String(Z?.title||"")}))}export async function startNewChat(H){await H.goto(GROK_URL);await H.wait(2)}export async function clickConversationMenuItem(H,Y,X){const q=String(Y).toLowerCase(),Z=JSON.stringify(q),$=JSON.stringify(X.map((Q)=>Q.toLowerCase()));return await H.evaluate(`(async () => {
89
+ })()`);if(!Array.isArray(e))return[];return e.slice(0,n).map((o)=>({id:String(o?.id||""),title:String(o?.title||"")}))}export async function startNewChat(t){await t.goto(GROK_URL);await t.wait(2)}export async function clickConversationMenuItem(t,n,e){const i=String(n).toLowerCase(),o=JSON.stringify(i),r=JSON.stringify(e.map((s)=>s.toLowerCase()));return await t.evaluate(`(async () => {
90
90
  const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
91
- const id = ${Z};
92
- const labels = ${$};
91
+ const id = ${o};
92
+ const labels = ${r};
93
93
  // Find the sidebar anchor for this conversation.
94
94
  let link = null;
95
95
  for (let attempt = 0; attempt < 10; attempt += 1) {
@@ -142,13 +142,13 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
142
142
  }
143
143
  target.click();
144
144
  return { ok: true, clicked: (target.textContent || '').trim() };
145
- })()`)}export function getPinStateFromMenuLabels(H){const Y=(Array.isArray(H)?H:[]).map((X)=>String(X||"").trim().toLowerCase()).filter(Boolean);if(Y.some((X)=>X==="取消置顶"||X==="unpin"))return"pinned";if(Y.some((X)=>X==="置顶"||X==="pin"))return"unpinned";return""}export async function isConversationVisibleInSidebar(H,Y){const X=String(Y).toLowerCase(),q=JSON.stringify(X),Z=await H.evaluate(`(() => {
146
- const id = ${q};
145
+ })()`)}export function getPinStateFromMenuLabels(t){const n=(Array.isArray(t)?t:[]).map((e)=>String(e||"").trim().toLowerCase()).filter(Boolean);if(n.some((e)=>e==="取消置顶"||e==="unpin"))return"pinned";if(n.some((e)=>e==="置顶"||e==="pin"))return"unpinned";return""}export async function isConversationVisibleInSidebar(t,n){const e=String(n).toLowerCase(),i=JSON.stringify(e),o=await t.evaluate(`(() => {
146
+ const id = ${i};
147
147
  return Array.from(document.querySelectorAll('a[href^="/c/"]'))
148
148
  .some((a) => a instanceof HTMLElement && a.offsetParent && (a.getAttribute('href') || '').toLowerCase().includes(id));
149
- })()`);return Boolean(Z)}export async function waitForConversationToDisappear(H,Y,X=5000){const q=Date.now();while(Date.now()-q<X){if(!await isConversationVisibleInSidebar(H,Y))return!0;await H.wait(0.25)}return!await isConversationVisibleInSidebar(H,Y)}export async function readConversationMenuLabels(H,Y){const X=String(Y).toLowerCase(),q=JSON.stringify(X),Z=await H.evaluate(`(async () => {
149
+ })()`);return Boolean(o)}export async function waitForConversationToDisappear(t,n,e=5000){const i=Date.now();while(Date.now()-i<e){if(!await isConversationVisibleInSidebar(t,n))return!0;await t.wait(0.25)}return!await isConversationVisibleInSidebar(t,n)}export async function readConversationMenuLabels(t,n){const e=String(n).toLowerCase(),i=JSON.stringify(e),o=await t.evaluate(`(async () => {
150
150
  const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
151
- const id = ${q};
151
+ const id = ${i};
152
152
  let link = null;
153
153
  for (let attempt = 0; attempt < 10; attempt += 1) {
154
154
  link = Array.from(document.querySelectorAll('a[href^="/c/"]'))
@@ -183,7 +183,7 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
183
183
  return items.length
184
184
  ? { ok: true, labels }
185
185
  : { ok: false, reason: 'Context menu did not open for the conversation.', labels: [] };
186
- })()`);try{await H.keys("Escape")}catch{}if(!Z||typeof Z!=="object")return{ok:!1,reason:"Malformed context-menu result.",labels:[]};return{ok:Boolean(Z.ok),reason:String(Z.reason||""),detail:String(Z.detail||""),labels:Array.isArray(Z.labels)?Z.labels.map(($)=>String($||"")):[]}}export async function waitForConversationPinState(H,Y,X,q=5000){const Z=Date.now();let $=null;while(Date.now()-Z<q){$=await readConversationMenuLabels(H,Y);if($.ok&&getPinStateFromMenuLabels($.labels)===X)return{ok:!0,state:X,labels:$.labels};await H.wait(0.25)}$=await readConversationMenuLabels(H,Y);const Q=$.ok?getPinStateFromMenuLabels($.labels):"";return{ok:$.ok&&Q===X,state:Q,labels:$.labels||[],reason:$.reason||`Conversation did not reach ${X} state.`,detail:$.detail||""}}export async function fillRenameInputAndSubmit(H,Y){const X=JSON.stringify(Y);return await H.evaluate(`(async () => {
186
+ })()`);try{await t.keys("Escape")}catch{}if(!o||typeof o!=="object")return{ok:!1,reason:"Malformed context-menu result.",labels:[]};return{ok:Boolean(o.ok),reason:String(o.reason||""),detail:String(o.detail||""),labels:Array.isArray(o.labels)?o.labels.map((r)=>String(r||"")):[]}}export async function waitForConversationPinState(t,n,e,i=5000){const o=Date.now();let r=null;while(Date.now()-o<i){r=await readConversationMenuLabels(t,n);if(r.ok&&getPinStateFromMenuLabels(r.labels)===e)return{ok:!0,state:e,labels:r.labels};await t.wait(0.25)}r=await readConversationMenuLabels(t,n);const s=r.ok?getPinStateFromMenuLabels(r.labels):"";return{ok:r.ok&&s===e,state:s,labels:r.labels||[],reason:r.reason||`Conversation did not reach ${e} state.`,detail:r.detail||""}}export async function fillRenameInputAndSubmit(t,n){const e=JSON.stringify(n);return await t.evaluate(`(async () => {
187
187
  const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
188
188
  let input = null;
189
189
  for (let attempt = 0; attempt < 15; attempt += 1) {
@@ -200,17 +200,17 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
200
200
  input.focus();
201
201
  if (input instanceof HTMLInputElement) {
202
202
  const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
203
- setter.call(input, ${X});
203
+ setter.call(input, ${e});
204
204
  input.dispatchEvent(new Event('input', { bubbles: true }));
205
205
  } else {
206
206
  // contenteditable path
207
207
  input.innerText = '';
208
- document.execCommand('insertText', false, ${X});
208
+ document.execCommand('insertText', false, ${e});
209
209
  }
210
210
  // Commit by Enter (Grok accepts Enter to confirm, Escape to cancel).
211
211
  input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
212
- return { ok: true, value: ${X} };
213
- })()`)}export async function sendMessage(H,Y){const X=JSON.stringify(Y);return await H.evaluate(`(async () => {
212
+ return { ok: true, value: ${e} };
213
+ })()`)}export async function sendMessage(t,n){const e=JSON.stringify(n);return await t.evaluate(`(async () => {
214
214
  const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
215
215
  const normalize = (value) => String(value || '').replace(/\\s+/g, ' ').trim();
216
216
  const composerSelector = '.ProseMirror[contenteditable="true"]';
@@ -237,7 +237,7 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
237
237
  text: normalize(node.innerText || node.textContent || ''),
238
238
  }))
239
239
  .filter((turn) => turn.text);
240
- const promptText = normalize(${X});
240
+ const promptText = normalize(${e});
241
241
  const beforeTurns = userTurns();
242
242
  const beforeKeys = new Set(beforeTurns.map((turn) => turn.id + '\\n' + turn.text));
243
243
  const waitForSubmittedUserTurn = async () => {
@@ -267,7 +267,7 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
267
267
  try {
268
268
  if (typeof editor.commands.clearContent === 'function') editor.commands.clearContent();
269
269
  editor.commands.focus();
270
- editor.commands.insertContent(${X});
270
+ editor.commands.insertContent(${e});
271
271
  } catch (error) {
272
272
  return {
273
273
  ok: false,
@@ -334,4 +334,4 @@ import{htmlToMarkdown as k}from"@jackwener/opencli/utils";import{ArgumentError a
334
334
  detail: error instanceof Error ? error.message : String(error),
335
335
  };
336
336
  }
337
- })()`)}const D=2,N=6000,V=2;function G(H){return(H||"").replace(/\u00a0/g," ").trim()}export async function waitForAnswer(H,Y,X,q){const Z=Date.now();let $="",Q=0,y="";while(Date.now()-Z<X*1000){await H.wait(D);const f=[...await getMessageBubbles(H)].reverse().find((P)=>P.role==="Assistant");if(!f)continue;if(q&&f.id===q)continue;const W=G(f.text);if(!W||W===Y.trim())continue;y=W;const K=Date.now()-Z>=N;if(W===$){Q+=1;if(K&&Q>=V)return{status:"ok",assistant:f}}else{$=W;Q=0}}if(y)return{status:"partial",assistant:[...await getMessageBubbles(H)].reverse().find((W)=>W.role==="Assistant")};return{status:"timeout"}}export const __test__={GROK_SESSION_ID_RE:F,getPinStateFromMenuLabels};
337
+ })()`)}const y=2,g=6000,k=2;function E(t){return(t||"").replace(/\u00a0/g," ").trim()}export async function waitForAnswer(t,n,e,i){const o=Date.now();let r="",s=0,u="";while(Date.now()-o<e*1000){await t.wait(y);const l=[...await getMessageBubbles(t)].reverse().find((p)=>p.role==="Assistant");if(!l)continue;if(i&&l.id===i)continue;const a=E(l.text);if(!a||a===n.trim())continue;u=a;const f=Date.now()-o>=g;if(a===r){s+=1;if(f&&s>=k)return{status:"ok",assistant:l}}else{r=a;s=0}}if(u)return{status:"partial",assistant:[...await getMessageBubbles(t)].reverse().find((a)=>a.role==="Assistant")};return{status:"timeout"}}export const __test__={GROK_SESSION_ID_RE:d,getPinStateFromMenuLabels};
@@ -1 +1 @@
1
- import{cli as j,Strategy as A}from"@jackwener/opencli/registry";import{BROWSE_COLUMNS as B,CommandExecutionError as G,GUAZI_M_BASE as N,clean as W,guaziFetch as O,requireStableId as R,requireText as U,requireLimit as q,resolveCityCode as L}from"./utils.js";const _=["插电混动","纯电动","油电混动","增程式","汽油","柴油"];export function parseListings(P,H){const Q=String(P||"").match(/<a[^>]+href="\/car-detail\/c\d+\.html"[\s\S]*?<\/a>/g)||[],f=[],J=new Set;for(const V of Q){const X=V.match(/car-detail\/c(\d+)\.html/);if(!X)continue;const K=R(X[1],`guazi listing row ${f.length+1}`);if(J.has(K))continue;J.add(K);const $=V.match(/<img[^>]+alt="([^"]+)"/),Y=U($&&$[1],`guazi listing ${K} title`),D=W(V.replace(/<[^>]+>/g," ")),k=D.match(/(\d+(?:\.\d+)?)\s*万\s*首付/),v=D.match(/首付\s*(\d+(?:\.\d+)?)\s*万/),z=D.match(/(\d+(?:\.\d+)?万公里|\d+公里)/),F=D.match(/(\d{4})年/),T=D.match(/[||]\s*([^||]{1,8}?)\s+\d+(?:\.\d+)?\s*万\s*首付/),Z=_.find((b)=>D.includes(b))||"";f.push({rank:f.length+1,clue_id:K,title:Y,price:k?`${k[1]}万`:"",down_payment:v?`${v[1]}万`:"",mileage:z?z[1]:"",year:F?F[1]:"",city:T?W(T[1]):Z,url:`${N}/car-detail/c${K}.html`});if(f.length>=H)break}return f}j({site:"guazi",name:"browse",access:"read",aliases:["list"],description:"瓜子二手车在售车源列表(按城市,含售价/首付/里程/年份)",strategy:A.PUBLIC,browser:!1,args:[{name:"city",positional:!0,help:"城市名(北京/上海/...)或瓜子城市码(bj/sh/...)。默认 bj 北京"},{name:"limit",type:"int",default:20,help:"返回的车源数量(最多 40,单页 SSR 上限)"}],columns:B,func:async(P)=>{const H=L(P.city),Q=q(P.limit,20,40),f=await O(`/${H}/buy/`,`browse ${H}`),J=parseListings(f,Q);if(J.length===0)throw new G(`guazi browse ${H}`,"No SSR listing anchors found on a successful Guazi mobile page; the mobile layout may have changed.");return J}});
1
+ import{cli as S,Strategy as b}from"@jackwener/opencli/registry";import{BROWSE_COLUMNS as M,CommandExecutionError as z,GUAZI_M_BASE as E,clean as f,guaziFetch as C,requireStableId as _,requireText as x,requireLimit as I,resolveCityCode as L}from"./utils.js";const R=["插电混动","纯电动","油电混动","增程式","汽油","柴油"];export function parseListings(c,i){const a=String(c||"").match(/<a[^>]+href="\/car-detail\/c\d+\.html"[\s\S]*?<\/a>/g)||[],t=[],n=new Set;for(const o of a){const r=o.match(/car-detail\/c(\d+)\.html/);if(!r)continue;const s=_(r[1],`guazi listing row ${t.length+1}`);if(n.has(s))continue;n.add(s);const l=o.match(/<img[^>]+alt="([^"]+)"/),y=x(l&&l[1],`guazi listing ${s} title`),e=f(o.replace(/<[^>]+>/g," ")),d=e.match(/(\d+(?:\.\d+)?)\s*万\s*首付/),m=e.match(/首付\s*(\d+(?:\.\d+)?)\s*万/),h=e.match(/(\d+(?:\.\d+)?万公里|\d+公里)/),u=e.match(/(\d{4})年/),g=e.match(/[||]\s*([^||]{1,8}?)\s+\d+(?:\.\d+)?\s*万\s*首付/),p=R.find((w)=>e.includes(w))||"";t.push({rank:t.length+1,clue_id:s,title:y,price:d?`${d[1]}万`:"",down_payment:m?`${m[1]}万`:"",mileage:h?h[1]:"",year:u?u[1]:"",city:g?f(g[1]):p,url:`${E}/car-detail/c${s}.html`});if(t.length>=i)break}return t}S({site:"guazi",name:"browse",access:"read",aliases:["list"],description:"瓜子二手车在售车源列表(按城市,含售价/首付/里程/年份)",strategy:b.PUBLIC,browser:!1,args:[{name:"city",positional:!0,help:"城市名(北京/上海/...)或瓜子城市码(bj/sh/...)。默认 bj 北京"},{name:"limit",type:"int",default:20,help:"返回的车源数量(最多 40,单页 SSR 上限)"}],columns:M,func:async(c)=>{const i=L(c.city),a=I(c.limit,20,40),t=await C(`/${i}/buy/`,`browse ${i}`),n=parseListings(t,a);if(n.length===0)throw new z(`guazi browse ${i}`,"No SSR listing anchors found on a successful Guazi mobile page; the mobile layout may have changed.");return n}});
package/clis/guazi/car.js CHANGED
@@ -1 +1 @@
1
- import{cli as O,Strategy as W}from"@jackwener/opencli/registry";import{CAR_COLUMNS as Z,EmptyResultError as j,GUAZI_M_BASE as q,clean as Y,guaziFetch as x,normalizeClueId as z,requireText as L}from"./utils.js";const A=["首次上牌","表显里程","过户次数","车源地","车身颜色","发动机","变速箱","驱动方式","排放标准","车源编号"];function D(P){let H=Y(P);H=H.replace(/^【[^】]*】/,"");H=H.replace(/^二手/,"");H=H.replace(/报价[,,].*$/,"");H=H.replace(/\s*-\s*瓜子二手车.*$/,"");return Y(H)}export function parseCarDetail(P,H){const K=String(P||"").replace(/\\"/g,'"'),Q=K.match(/<meta[^>]+property="og:title"[^>]+content="([^"]+)"/)||K.match(/"title":"([^"]{6,80})"/),V=Q?Q[1]:"",X=Y(V).match(/^【([^】]+)】/),F=K.match(/"price":(\d{4,8})/),N=F?`${(Number(F[1])/1e4).toFixed(2)}万`:"",J={};for(const[,$,B]of K.matchAll(/"label":"([^"]{1,12})","value":"([^"]{1,40})"/g))if(!($ in J))J[$]=Y(B);const G=K.match(/基础车况[^,,"<]{0,16}/);return[["clue_id",String(H)],["title",V?D(V):""],["tag",X?X[1]:""],["price",N],["reg_date",J["首次上牌"]||""],["mileage",J["表显里程"]||""],["transfers",J["过户次数"]||""],["source_city",J["车源地"]||""],["color",J["车身颜色"]||""],["engine",J["发动机"]||""],["gearbox",J["变速箱"]||""],["drivetrain",J["驱动方式"]||""],["emission",J["排放标准"]||""],["condition",G?Y(G[0]):""],["listing_no",J["车源编号"]||""],["url",`${q}/car-detail/c${H}.html`]].map(([$,B])=>({field:$,value:B}))}function R(P){const H=Object.fromEntries(P.map((K)=>[K.field,K.value]));return Boolean(H.title||H.price||H.reg_date)}O({site:"guazi",name:"car",access:"read",aliases:["detail"],description:"瓜子二手车车源详情(售价 / 上牌 / 里程 / 过户 / 配置 / 车况)",strategy:W.PUBLIC,browser:!1,args:[{name:"clue_id",required:!0,positional:!0,help:"车源 ID(来自 browse 的 clue_id,或 /car-detail/c<id>.html URL)"}],columns:Z,func:async(P)=>{const H=z(P.clue_id),K=await x(`/car-detail/c${H}.html`,`car ${H}`),Q=parseCarDetail(K,H);if(!R(Q))throw new j(`guazi car ${H}`,"No listing detail found — the car may have been sold/removed, or the id is wrong.");const V=Object.fromEntries(Q.map((X)=>[X.field,X.value]));L(V.title,`guazi car ${H} title`);L(V.price,`guazi car ${H} price`);return Q}});
1
+ import{cli as g,Strategy as f}from"@jackwener/opencli/registry";import{CAR_COLUMNS as h,EmptyResultError as _,GUAZI_M_BASE as b,clean as n,guaziFetch as w,normalizeClueId as v,requireText as d}from"./utils.js";const M=["首次上牌","表显里程","过户次数","车源地","车身颜色","发动机","变速箱","驱动方式","排放标准","车源编号"];function y(a){let e=n(a);e=e.replace(/^【[^】]*】/,"");e=e.replace(/^二手/,"");e=e.replace(/报价[,,].*$/,"");e=e.replace(/\s*-\s*瓜子二手车.*$/,"");return n(e)}export function parseCarDetail(a,e){const r=String(a||"").replace(/\\"/g,'"'),i=r.match(/<meta[^>]+property="og:title"[^>]+content="([^"]+)"/)||r.match(/"title":"([^"]{6,80})"/),c=i?i[1]:"",l=n(c).match(/^【([^】]+)】/),m=r.match(/"price":(\d{4,8})/),p=m?`${(Number(m[1])/1e4).toFixed(2)}万`:"",t={};for(const[,o,s]of r.matchAll(/"label":"([^"]{1,12})","value":"([^"]{1,40})"/g))if(!(o in t))t[o]=n(s);const u=r.match(/基础车况[^,,"<]{0,16}/);return[["clue_id",String(e)],["title",c?y(c):""],["tag",l?l[1]:""],["price",p],["reg_date",t["首次上牌"]||""],["mileage",t["表显里程"]||""],["transfers",t["过户次数"]||""],["source_city",t["车源地"]||""],["color",t["车身颜色"]||""],["engine",t["发动机"]||""],["gearbox",t["变速箱"]||""],["drivetrain",t["驱动方式"]||""],["emission",t["排放标准"]||""],["condition",u?n(u[0]):""],["listing_no",t["车源编号"]||""],["url",`${b}/car-detail/c${e}.html`]].map(([o,s])=>({field:o,value:s}))}function E(a){const e=Object.fromEntries(a.map((r)=>[r.field,r.value]));return Boolean(e.title||e.price||e.reg_date)}g({site:"guazi",name:"car",access:"read",aliases:["detail"],description:"瓜子二手车车源详情(售价 / 上牌 / 里程 / 过户 / 配置 / 车况)",strategy:f.PUBLIC,browser:!1,args:[{name:"clue_id",required:!0,positional:!0,help:"车源 ID(来自 browse 的 clue_id,或 /car-detail/c<id>.html URL)"}],columns:h,func:async(a)=>{const e=v(a.clue_id),r=await w(`/car-detail/c${e}.html`,`car ${e}`),i=parseCarDetail(r,e);if(!E(i))throw new _(`guazi car ${e}`,"No listing detail found — the car may have been sold/removed, or the id is wrong.");const c=Object.fromEntries(i.map((l)=>[l.field,l.value]));d(c.title,`guazi car ${e} title`);d(c.price,`guazi car ${e} price`);return i}});