@jackwener/opencli 1.4.1 → 1.5.1

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 (369) hide show
  1. package/.github/workflows/build-extension.yml +2 -6
  2. package/.github/workflows/ci.yml +21 -1
  3. package/README.md +35 -6
  4. package/README.zh-CN.md +12 -5
  5. package/SKILL.md +2 -0
  6. package/dist/browser/cdp.d.ts +2 -1
  7. package/dist/browser/cdp.js +5 -0
  8. package/dist/browser/discover.d.ts +4 -1
  9. package/dist/browser/discover.js +6 -2
  10. package/dist/browser/errors.d.ts +2 -2
  11. package/dist/browser/errors.js +4 -12
  12. package/dist/browser/mcp.d.ts +2 -1
  13. package/dist/browser/page.d.ts +3 -0
  14. package/dist/browser/page.js +24 -1
  15. package/dist/build-manifest.d.ts +2 -0
  16. package/dist/build-manifest.js +39 -14
  17. package/dist/build-manifest.test.js +21 -0
  18. package/dist/capabilityRouting.d.ts +2 -0
  19. package/dist/capabilityRouting.js +2 -1
  20. package/dist/cli-manifest.json +1567 -108
  21. package/dist/cli.js +68 -6
  22. package/dist/clis/36kr/article.d.ts +1 -0
  23. package/dist/clis/36kr/article.js +62 -0
  24. package/dist/clis/36kr/hot.d.ts +3 -0
  25. package/dist/clis/36kr/hot.js +80 -0
  26. package/dist/clis/36kr/hot.test.d.ts +1 -0
  27. package/dist/clis/36kr/hot.test.js +15 -0
  28. package/dist/clis/36kr/news.d.ts +1 -0
  29. package/dist/clis/36kr/news.js +51 -0
  30. package/dist/clis/36kr/news.test.d.ts +1 -0
  31. package/dist/clis/36kr/news.test.js +85 -0
  32. package/dist/clis/36kr/search.d.ts +1 -0
  33. package/dist/clis/36kr/search.js +72 -0
  34. package/dist/clis/bilibili/comments.d.ts +5 -0
  35. package/dist/clis/bilibili/comments.js +40 -0
  36. package/dist/clis/bilibili/comments.test.d.ts +1 -0
  37. package/dist/clis/bilibili/comments.test.js +82 -0
  38. package/dist/clis/bluesky/feeds.yaml +29 -0
  39. package/dist/clis/bluesky/followers.yaml +33 -0
  40. package/dist/clis/bluesky/following.yaml +33 -0
  41. package/dist/clis/bluesky/profile.yaml +27 -0
  42. package/dist/clis/bluesky/search.yaml +34 -0
  43. package/dist/clis/bluesky/starter-packs.yaml +34 -0
  44. package/dist/clis/bluesky/thread.yaml +32 -0
  45. package/dist/clis/bluesky/trending.yaml +27 -0
  46. package/dist/clis/bluesky/user.yaml +34 -0
  47. package/dist/clis/chatgpt/ask.js +29 -14
  48. package/dist/clis/chatgpt/ax.d.ts +6 -0
  49. package/dist/clis/chatgpt/ax.js +172 -1
  50. package/dist/clis/chatgpt/model.d.ts +1 -0
  51. package/dist/clis/chatgpt/model.js +24 -0
  52. package/dist/clis/chatgpt/send.js +12 -3
  53. package/dist/clis/douban/download.d.ts +1 -0
  54. package/dist/clis/douban/download.js +67 -0
  55. package/dist/clis/douban/download.test.d.ts +1 -0
  56. package/dist/clis/douban/download.test.js +170 -0
  57. package/dist/clis/douban/photos.d.ts +1 -0
  58. package/dist/clis/douban/photos.js +34 -0
  59. package/dist/clis/douban/utils.d.ts +25 -0
  60. package/dist/clis/douban/utils.js +190 -1
  61. package/dist/clis/douban/utils.test.d.ts +1 -0
  62. package/dist/clis/douban/utils.test.js +64 -0
  63. package/dist/clis/imdb/person.d.ts +1 -0
  64. package/dist/clis/imdb/person.js +203 -0
  65. package/dist/clis/imdb/reviews.d.ts +1 -0
  66. package/dist/clis/imdb/reviews.js +88 -0
  67. package/dist/clis/imdb/search.d.ts +1 -0
  68. package/dist/clis/imdb/search.js +161 -0
  69. package/dist/clis/imdb/title.d.ts +1 -0
  70. package/dist/clis/imdb/title.js +93 -0
  71. package/dist/clis/imdb/top.d.ts +1 -0
  72. package/dist/clis/imdb/top.js +53 -0
  73. package/dist/clis/imdb/trending.d.ts +1 -0
  74. package/dist/clis/imdb/trending.js +52 -0
  75. package/dist/clis/imdb/utils.d.ts +46 -0
  76. package/dist/clis/imdb/utils.js +285 -0
  77. package/dist/clis/imdb/utils.test.d.ts +1 -0
  78. package/dist/clis/imdb/utils.test.js +88 -0
  79. package/dist/clis/jd/item.d.ts +4 -0
  80. package/dist/clis/jd/item.js +16 -15
  81. package/dist/clis/jd/item.test.js +16 -1
  82. package/dist/clis/linux-do/categories.yaml +38 -9
  83. package/dist/clis/linux-do/category.d.ts +1 -0
  84. package/dist/clis/linux-do/category.js +36 -0
  85. package/dist/clis/linux-do/feed.d.ts +45 -0
  86. package/dist/clis/linux-do/feed.js +397 -0
  87. package/dist/clis/linux-do/feed.test.d.ts +1 -0
  88. package/dist/clis/linux-do/feed.test.js +118 -0
  89. package/dist/clis/linux-do/hot.d.ts +1 -0
  90. package/dist/clis/linux-do/hot.js +25 -0
  91. package/dist/clis/linux-do/latest.d.ts +1 -0
  92. package/dist/clis/linux-do/latest.js +18 -0
  93. package/dist/clis/linux-do/tags.yaml +41 -0
  94. package/dist/clis/linux-do/topic.yaml +41 -3
  95. package/dist/clis/linux-do/user-posts.yaml +67 -0
  96. package/dist/clis/linux-do/user-topics.yaml +54 -0
  97. package/dist/clis/paperreview/commands.test.d.ts +3 -0
  98. package/dist/clis/paperreview/commands.test.js +243 -0
  99. package/dist/clis/paperreview/feedback.d.ts +1 -0
  100. package/dist/clis/paperreview/feedback.js +52 -0
  101. package/dist/clis/paperreview/review.d.ts +1 -0
  102. package/dist/clis/paperreview/review.js +37 -0
  103. package/dist/clis/paperreview/submit.d.ts +1 -0
  104. package/dist/clis/paperreview/submit.js +85 -0
  105. package/dist/clis/paperreview/utils.d.ts +46 -0
  106. package/dist/clis/paperreview/utils.js +197 -0
  107. package/dist/clis/paperreview/utils.test.d.ts +1 -0
  108. package/dist/clis/paperreview/utils.test.js +49 -0
  109. package/dist/clis/producthunt/browse.d.ts +1 -0
  110. package/dist/clis/producthunt/browse.js +99 -0
  111. package/dist/clis/producthunt/hot.d.ts +1 -0
  112. package/dist/clis/producthunt/hot.js +110 -0
  113. package/dist/clis/producthunt/posts.d.ts +1 -0
  114. package/dist/clis/producthunt/posts.js +28 -0
  115. package/dist/clis/producthunt/today.d.ts +1 -0
  116. package/dist/clis/producthunt/today.js +35 -0
  117. package/dist/clis/producthunt/utils.d.ts +29 -0
  118. package/dist/clis/producthunt/utils.js +99 -0
  119. package/dist/clis/producthunt/utils.test.d.ts +1 -0
  120. package/dist/clis/producthunt/utils.test.js +64 -0
  121. package/dist/clis/twitter/article.js +4 -28
  122. package/dist/clis/twitter/likes.d.ts +24 -0
  123. package/dist/clis/twitter/likes.js +217 -0
  124. package/dist/clis/twitter/likes.test.d.ts +1 -0
  125. package/dist/clis/twitter/likes.test.js +85 -0
  126. package/dist/clis/twitter/profile.js +4 -28
  127. package/dist/clis/twitter/search.js +2 -1
  128. package/dist/clis/twitter/search.test.js +2 -0
  129. package/dist/clis/twitter/shared.d.ts +6 -0
  130. package/dist/clis/twitter/shared.js +35 -0
  131. package/dist/clis/twitter/timeline.js +2 -13
  132. package/dist/clis/twitter/trending.js +29 -61
  133. package/dist/clis/v2ex/hot.yaml +17 -3
  134. package/dist/clis/weixin/download.d.ts +17 -0
  135. package/dist/clis/weixin/download.js +88 -20
  136. package/dist/clis/weread/book.js +2 -2
  137. package/dist/clis/weread/commands.test.d.ts +3 -0
  138. package/dist/clis/weread/commands.test.js +43 -0
  139. package/dist/clis/weread/highlights.js +2 -2
  140. package/dist/clis/weread/notebooks.js +2 -2
  141. package/dist/clis/weread/notes.js +3 -3
  142. package/dist/clis/weread/shelf.js +2 -2
  143. package/dist/clis/weread/utils.d.ts +4 -4
  144. package/dist/clis/weread/utils.js +32 -14
  145. package/dist/clis/weread/utils.test.js +1 -28
  146. package/dist/clis/xiaohongshu/comments.d.ts +5 -0
  147. package/dist/clis/xiaohongshu/comments.js +74 -0
  148. package/dist/clis/xiaohongshu/comments.test.d.ts +1 -0
  149. package/dist/clis/xiaohongshu/comments.test.js +79 -0
  150. package/dist/clis/xiaohongshu/publish.js +179 -47
  151. package/dist/clis/xiaohongshu/publish.test.d.ts +1 -0
  152. package/dist/clis/xiaohongshu/publish.test.js +131 -0
  153. package/dist/clis/xiaohongshu/search.d.ts +8 -1
  154. package/dist/clis/xiaohongshu/search.js +20 -1
  155. package/dist/clis/xiaohongshu/search.test.d.ts +1 -1
  156. package/dist/clis/xiaohongshu/search.test.js +32 -1
  157. package/dist/commanderAdapter.d.ts +1 -0
  158. package/dist/commanderAdapter.js +176 -29
  159. package/dist/commanderAdapter.test.d.ts +1 -0
  160. package/dist/commanderAdapter.test.js +62 -0
  161. package/dist/daemon.js +17 -1
  162. package/dist/discovery.js +48 -42
  163. package/dist/doctor.d.ts +2 -2
  164. package/dist/doctor.js +11 -4
  165. package/dist/download/index.js +63 -51
  166. package/dist/download/index.test.js +17 -4
  167. package/dist/engine.test.js +42 -0
  168. package/dist/errors.d.ts +4 -2
  169. package/dist/errors.js +17 -34
  170. package/dist/execution.d.ts +1 -3
  171. package/dist/execution.js +66 -8
  172. package/dist/execution.test.d.ts +1 -0
  173. package/dist/execution.test.js +40 -0
  174. package/dist/external.js +6 -1
  175. package/dist/hooks.js +2 -0
  176. package/dist/main.js +6 -0
  177. package/dist/output.js +5 -1
  178. package/dist/pipeline/executor.js +3 -4
  179. package/dist/plugin-manifest.d.ts +70 -0
  180. package/dist/plugin-manifest.js +160 -0
  181. package/dist/plugin-manifest.test.d.ts +4 -0
  182. package/dist/plugin-manifest.test.js +179 -0
  183. package/dist/plugin-scaffold.d.ts +28 -0
  184. package/dist/plugin-scaffold.js +142 -0
  185. package/dist/plugin-scaffold.test.d.ts +4 -0
  186. package/dist/plugin-scaffold.test.js +83 -0
  187. package/dist/plugin.d.ts +82 -11
  188. package/dist/plugin.js +870 -84
  189. package/dist/plugin.test.js +1032 -17
  190. package/dist/registry.d.ts +4 -0
  191. package/dist/registry.js +2 -0
  192. package/dist/runtime-detect.d.ts +21 -0
  193. package/dist/runtime-detect.js +32 -0
  194. package/dist/runtime-detect.test.d.ts +1 -0
  195. package/dist/runtime-detect.test.js +27 -0
  196. package/dist/runtime.d.ts +1 -0
  197. package/dist/runtime.js +2 -2
  198. package/dist/serialization.d.ts +2 -0
  199. package/dist/serialization.js +6 -0
  200. package/dist/types.d.ts +3 -0
  201. package/dist/update-check.d.ts +22 -0
  202. package/dist/update-check.js +112 -0
  203. package/dist/weixin-download.test.d.ts +1 -0
  204. package/dist/weixin-download.test.js +30 -0
  205. package/dist/weread-private-api-regression.test.d.ts +1 -0
  206. package/dist/weread-private-api-regression.test.js +122 -0
  207. package/dist/yaml-schema.d.ts +3 -0
  208. package/dist/yaml-schema.js +18 -1
  209. package/docs/.vitepress/config.mts +4 -0
  210. package/docs/adapters/browser/36kr.md +47 -0
  211. package/docs/adapters/browser/bluesky.md +53 -0
  212. package/docs/adapters/browser/douban.md +14 -0
  213. package/docs/adapters/browser/imdb.md +47 -0
  214. package/docs/adapters/browser/jd.md +2 -2
  215. package/docs/adapters/browser/linux-do.md +181 -20
  216. package/docs/adapters/browser/paperreview.md +43 -0
  217. package/docs/adapters/browser/producthunt.md +49 -0
  218. package/docs/adapters/desktop/chatgpt.md +5 -0
  219. package/docs/adapters/index.md +6 -2
  220. package/docs/advanced/download.md +4 -0
  221. package/docs/advanced/rate-limiter-plugin.md +99 -0
  222. package/docs/guide/electron-app-cli.md +200 -0
  223. package/docs/guide/getting-started.md +1 -0
  224. package/docs/guide/plugins.md +97 -0
  225. package/docs/zh/guide/electron-app-cli.md +188 -0
  226. package/docs/zh/guide/getting-started.md +1 -0
  227. package/docs/zh/guide/plugins.md +65 -0
  228. package/extension/package.json +1 -0
  229. package/extension/scripts/package-release.mjs +179 -0
  230. package/extension/src/background.ts +2 -0
  231. package/package.json +4 -1
  232. package/scripts/postinstall.js +10 -0
  233. package/src/browser/cdp.ts +8 -1
  234. package/src/browser/discover.ts +8 -3
  235. package/src/browser/errors.ts +13 -14
  236. package/src/browser/mcp.ts +2 -1
  237. package/src/browser/page.ts +24 -1
  238. package/src/build-manifest.test.ts +23 -0
  239. package/src/build-manifest.ts +40 -15
  240. package/src/capabilityRouting.ts +2 -1
  241. package/src/cli.ts +69 -6
  242. package/src/clis/36kr/article.ts +69 -0
  243. package/src/clis/36kr/hot.test.ts +19 -0
  244. package/src/clis/36kr/hot.ts +100 -0
  245. package/src/clis/36kr/news.test.ts +90 -0
  246. package/src/clis/36kr/news.ts +54 -0
  247. package/src/clis/36kr/search.ts +78 -0
  248. package/src/clis/bilibili/comments.test.ts +102 -0
  249. package/src/clis/bilibili/comments.ts +44 -0
  250. package/src/clis/bluesky/feeds.yaml +29 -0
  251. package/src/clis/bluesky/followers.yaml +33 -0
  252. package/src/clis/bluesky/following.yaml +33 -0
  253. package/src/clis/bluesky/profile.yaml +27 -0
  254. package/src/clis/bluesky/search.yaml +34 -0
  255. package/src/clis/bluesky/starter-packs.yaml +34 -0
  256. package/src/clis/bluesky/thread.yaml +32 -0
  257. package/src/clis/bluesky/trending.yaml +27 -0
  258. package/src/clis/bluesky/user.yaml +34 -0
  259. package/src/clis/chatgpt/ask.ts +28 -14
  260. package/src/clis/chatgpt/ax.ts +180 -1
  261. package/src/clis/chatgpt/model.ts +27 -0
  262. package/src/clis/chatgpt/send.ts +16 -6
  263. package/src/clis/douban/download.test.ts +196 -0
  264. package/src/clis/douban/download.ts +78 -0
  265. package/src/clis/douban/photos.ts +36 -0
  266. package/src/clis/douban/utils.test.ts +97 -0
  267. package/src/clis/douban/utils.ts +232 -1
  268. package/src/clis/imdb/person.ts +232 -0
  269. package/src/clis/imdb/reviews.ts +111 -0
  270. package/src/clis/imdb/search.ts +179 -0
  271. package/src/clis/imdb/title.ts +121 -0
  272. package/src/clis/imdb/top.ts +67 -0
  273. package/src/clis/imdb/trending.ts +66 -0
  274. package/src/clis/imdb/utils.test.ts +117 -0
  275. package/src/clis/imdb/utils.ts +305 -0
  276. package/src/clis/jd/item.test.ts +18 -1
  277. package/src/clis/jd/item.ts +18 -15
  278. package/src/clis/linux-do/categories.yaml +38 -9
  279. package/src/clis/linux-do/category.ts +37 -0
  280. package/src/clis/linux-do/feed.test.ts +132 -0
  281. package/src/clis/linux-do/feed.ts +501 -0
  282. package/src/clis/linux-do/hot.ts +26 -0
  283. package/src/clis/linux-do/latest.ts +19 -0
  284. package/src/clis/linux-do/tags.yaml +41 -0
  285. package/src/clis/linux-do/topic.yaml +41 -3
  286. package/src/clis/linux-do/user-posts.yaml +67 -0
  287. package/src/clis/linux-do/user-topics.yaml +54 -0
  288. package/src/clis/paperreview/commands.test.ts +283 -0
  289. package/src/clis/paperreview/feedback.ts +64 -0
  290. package/src/clis/paperreview/review.ts +47 -0
  291. package/src/clis/paperreview/submit.ts +119 -0
  292. package/src/clis/paperreview/utils.test.ts +68 -0
  293. package/src/clis/paperreview/utils.ts +276 -0
  294. package/src/clis/producthunt/browse.ts +109 -0
  295. package/src/clis/producthunt/hot.ts +127 -0
  296. package/src/clis/producthunt/posts.ts +29 -0
  297. package/src/clis/producthunt/today.ts +37 -0
  298. package/src/clis/producthunt/utils.test.ts +72 -0
  299. package/src/clis/producthunt/utils.ts +122 -0
  300. package/src/clis/twitter/article.ts +5 -28
  301. package/src/clis/twitter/likes.test.ts +91 -0
  302. package/src/clis/twitter/likes.ts +256 -0
  303. package/src/clis/twitter/profile.ts +5 -28
  304. package/src/clis/twitter/search.test.ts +2 -0
  305. package/src/clis/twitter/search.ts +3 -1
  306. package/src/clis/twitter/shared.ts +45 -0
  307. package/src/clis/twitter/timeline.ts +2 -13
  308. package/src/clis/twitter/trending.ts +29 -77
  309. package/src/clis/v2ex/hot.yaml +17 -3
  310. package/src/clis/weixin/download.ts +114 -20
  311. package/src/clis/weread/book.ts +2 -2
  312. package/src/clis/weread/commands.test.ts +57 -0
  313. package/src/clis/weread/highlights.ts +2 -2
  314. package/src/clis/weread/notebooks.ts +2 -2
  315. package/src/clis/weread/notes.ts +3 -3
  316. package/src/clis/weread/shelf.ts +2 -2
  317. package/src/clis/weread/utils.test.ts +1 -32
  318. package/src/clis/weread/utils.ts +41 -16
  319. package/src/clis/xiaohongshu/comments.test.ts +96 -0
  320. package/src/clis/xiaohongshu/comments.ts +81 -0
  321. package/src/clis/xiaohongshu/publish.test.ts +151 -0
  322. package/src/clis/xiaohongshu/publish.ts +206 -54
  323. package/src/clis/xiaohongshu/search.test.ts +39 -1
  324. package/src/clis/xiaohongshu/search.ts +19 -1
  325. package/src/commanderAdapter.test.ts +78 -0
  326. package/src/commanderAdapter.ts +188 -24
  327. package/src/daemon.ts +19 -1
  328. package/src/discovery.ts +49 -48
  329. package/src/doctor.ts +15 -5
  330. package/src/download/index.test.ts +14 -4
  331. package/src/download/index.ts +67 -55
  332. package/src/engine.test.ts +38 -0
  333. package/src/errors.ts +26 -63
  334. package/src/execution.test.ts +47 -0
  335. package/src/execution.ts +67 -9
  336. package/src/external.ts +6 -1
  337. package/src/hooks.ts +1 -0
  338. package/src/main.ts +7 -0
  339. package/src/output.ts +3 -1
  340. package/src/pipeline/executor.ts +4 -6
  341. package/src/plugin-manifest.test.ts +223 -0
  342. package/src/plugin-manifest.ts +206 -0
  343. package/src/plugin-scaffold.test.ts +98 -0
  344. package/src/plugin-scaffold.ts +170 -0
  345. package/src/plugin.test.ts +1104 -17
  346. package/src/plugin.ts +1101 -86
  347. package/src/registry.ts +6 -1
  348. package/src/runtime-detect.test.ts +30 -0
  349. package/src/runtime-detect.ts +36 -0
  350. package/src/runtime.ts +3 -3
  351. package/src/serialization.ts +4 -0
  352. package/src/types.ts +3 -0
  353. package/src/update-check.ts +114 -0
  354. package/src/weixin-download.test.ts +64 -0
  355. package/src/weread-private-api-regression.test.ts +150 -0
  356. package/src/yaml-schema.ts +20 -0
  357. package/tests/e2e/browser-auth.test.ts +13 -9
  358. package/tests/e2e/browser-public-extended.test.ts +1 -1
  359. package/tests/e2e/browser-public.test.ts +62 -4
  360. package/tests/e2e/helpers.ts +2 -1
  361. package/tests/e2e/public-commands.test.ts +37 -3
  362. package/tests/smoke/api-health.test.ts +1 -1
  363. package/vitest.config.ts +10 -0
  364. package/dist/clis/linux-do/category.yaml +0 -51
  365. package/dist/clis/linux-do/hot.yaml +0 -50
  366. package/dist/clis/linux-do/latest.yaml +0 -40
  367. package/src/clis/linux-do/category.yaml +0 -51
  368. package/src/clis/linux-do/hot.yaml +0 -50
  369. package/src/clis/linux-do/latest.yaml +0 -40
@@ -1,4 +1,116 @@
1
1
  [
2
+ {
3
+ "site": "36kr",
4
+ "name": "article",
5
+ "description": "获取36氪文章正文内容",
6
+ "strategy": "intercept",
7
+ "browser": true,
8
+ "args": [
9
+ {
10
+ "name": "id",
11
+ "type": "str",
12
+ "required": true,
13
+ "positional": true,
14
+ "help": "Article ID or full 36kr article URL"
15
+ }
16
+ ],
17
+ "type": "ts",
18
+ "modulePath": "36kr/article.js",
19
+ "domain": "www.36kr.com",
20
+ "columns": [
21
+ "field",
22
+ "value"
23
+ ]
24
+ },
25
+ {
26
+ "site": "36kr",
27
+ "name": "hot",
28
+ "description": "36氪热榜 — trending articles (renqi/zonghe/shoucang/catalog)",
29
+ "strategy": "intercept",
30
+ "browser": true,
31
+ "args": [
32
+ {
33
+ "name": "limit",
34
+ "type": "int",
35
+ "default": 20,
36
+ "required": false,
37
+ "help": "Number of items (max 50)"
38
+ },
39
+ {
40
+ "name": "type",
41
+ "type": "string",
42
+ "default": "catalog",
43
+ "required": false,
44
+ "help": "List type: renqi (人气), zonghe (综合), shoucang (收藏), catalog (热门资讯)"
45
+ }
46
+ ],
47
+ "type": "ts",
48
+ "modulePath": "36kr/hot.js",
49
+ "domain": "www.36kr.com",
50
+ "columns": [
51
+ "rank",
52
+ "title",
53
+ "url"
54
+ ]
55
+ },
56
+ {
57
+ "site": "36kr",
58
+ "name": "news",
59
+ "description": "Latest tech/startup news from 36kr (36氪)",
60
+ "strategy": "public",
61
+ "browser": false,
62
+ "args": [
63
+ {
64
+ "name": "limit",
65
+ "type": "int",
66
+ "default": 20,
67
+ "required": false,
68
+ "help": "Number of articles (max 50)"
69
+ }
70
+ ],
71
+ "type": "ts",
72
+ "modulePath": "36kr/news.js",
73
+ "domain": "www.36kr.com",
74
+ "columns": [
75
+ "rank",
76
+ "title",
77
+ "summary",
78
+ "date",
79
+ "url"
80
+ ]
81
+ },
82
+ {
83
+ "site": "36kr",
84
+ "name": "search",
85
+ "description": "搜索36氪文章",
86
+ "strategy": "intercept",
87
+ "browser": true,
88
+ "args": [
89
+ {
90
+ "name": "query",
91
+ "type": "str",
92
+ "required": true,
93
+ "positional": true,
94
+ "help": "Search keyword (e.g. "
95
+ },
96
+ {
97
+ "name": "limit",
98
+ "type": "int",
99
+ "default": 20,
100
+ "required": false,
101
+ "help": "Number of results (max 50)"
102
+ }
103
+ ],
104
+ "type": "ts",
105
+ "modulePath": "36kr/search.js",
106
+ "domain": "www.36kr.com",
107
+ "columns": [
108
+ "rank",
109
+ "title",
110
+ "date",
111
+ "url"
112
+ ]
113
+ },
2
114
  {
3
115
  "site": "_shared",
4
116
  "name": "desktop-commands",
@@ -512,6 +624,40 @@
512
624
  "url"
513
625
  ]
514
626
  },
627
+ {
628
+ "site": "bilibili",
629
+ "name": "comments",
630
+ "description": "获取 B站视频评论(使用官方 API + WBI 签名)",
631
+ "strategy": "cookie",
632
+ "browser": true,
633
+ "args": [
634
+ {
635
+ "name": "bvid",
636
+ "type": "str",
637
+ "required": true,
638
+ "positional": true,
639
+ "help": "Video BV ID (e.g. BV1WtAGzYEBm)"
640
+ },
641
+ {
642
+ "name": "limit",
643
+ "type": "int",
644
+ "default": 20,
645
+ "required": false,
646
+ "help": "Number of comments (max 50)"
647
+ }
648
+ ],
649
+ "type": "ts",
650
+ "modulePath": "bilibili/comments.js",
651
+ "domain": "www.bilibili.com",
652
+ "columns": [
653
+ "rank",
654
+ "author",
655
+ "text",
656
+ "likes",
657
+ "replies",
658
+ "time"
659
+ ]
660
+ },
515
661
  {
516
662
  "site": "bilibili",
517
663
  "name": "download",
@@ -721,6 +867,7 @@
721
867
  "type": "int",
722
868
  "default": 20,
723
869
  "required": false,
870
+ "positional": false,
724
871
  "help": "Number of videos"
725
872
  }
726
873
  ],
@@ -1147,22 +1294,480 @@
1147
1294
  "browser": false,
1148
1295
  "args": [
1149
1296
  {
1150
- "name": "limit",
1151
- "type": "int",
1152
- "default": 1,
1153
- "required": false,
1154
- "help": "Number of feed items to return (max 20)"
1297
+ "name": "limit",
1298
+ "type": "int",
1299
+ "default": 1,
1300
+ "required": false,
1301
+ "help": "Number of feed items to return (max 20)"
1302
+ }
1303
+ ],
1304
+ "type": "ts",
1305
+ "modulePath": "bloomberg/tech.js",
1306
+ "domain": "feeds.bloomberg.com",
1307
+ "columns": [
1308
+ "title",
1309
+ "summary",
1310
+ "link",
1311
+ "mediaLinks"
1312
+ ]
1313
+ },
1314
+ {
1315
+ "site": "bluesky",
1316
+ "name": "feeds",
1317
+ "description": "Popular Bluesky feed generators",
1318
+ "domain": "public.api.bsky.app",
1319
+ "strategy": "public",
1320
+ "browser": false,
1321
+ "args": [
1322
+ {
1323
+ "name": "limit",
1324
+ "type": "int",
1325
+ "default": 20,
1326
+ "required": false,
1327
+ "positional": false,
1328
+ "help": "Number of feeds"
1329
+ }
1330
+ ],
1331
+ "columns": [
1332
+ "rank",
1333
+ "name",
1334
+ "likes",
1335
+ "creator",
1336
+ "description"
1337
+ ],
1338
+ "pipeline": [
1339
+ {
1340
+ "fetch": {
1341
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.unspecced.getPopularFeedGenerators?limit=${{ args.limit }}"
1342
+ }
1343
+ },
1344
+ {
1345
+ "select": "feeds"
1346
+ },
1347
+ {
1348
+ "map": {
1349
+ "rank": "${{ index + 1 }}",
1350
+ "name": "${{ item.displayName }}",
1351
+ "likes": "${{ item.likeCount }}",
1352
+ "creator": "${{ item.creator.handle }}",
1353
+ "description": "${{ item.description }}"
1354
+ }
1355
+ },
1356
+ {
1357
+ "limit": "${{ args.limit }}"
1358
+ }
1359
+ ],
1360
+ "type": "yaml"
1361
+ },
1362
+ {
1363
+ "site": "bluesky",
1364
+ "name": "followers",
1365
+ "description": "List followers of a Bluesky user",
1366
+ "domain": "public.api.bsky.app",
1367
+ "strategy": "public",
1368
+ "browser": false,
1369
+ "args": [
1370
+ {
1371
+ "name": "handle",
1372
+ "type": "str",
1373
+ "required": true,
1374
+ "positional": true,
1375
+ "help": "Bluesky handle"
1376
+ },
1377
+ {
1378
+ "name": "limit",
1379
+ "type": "int",
1380
+ "default": 20,
1381
+ "required": false,
1382
+ "positional": false,
1383
+ "help": "Number of followers"
1384
+ }
1385
+ ],
1386
+ "columns": [
1387
+ "rank",
1388
+ "handle",
1389
+ "name",
1390
+ "description"
1391
+ ],
1392
+ "pipeline": [
1393
+ {
1394
+ "fetch": {
1395
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.graph.getFollowers?actor=${{ args.handle }}&limit=${{ args.limit }}"
1396
+ }
1397
+ },
1398
+ {
1399
+ "select": "followers"
1400
+ },
1401
+ {
1402
+ "map": {
1403
+ "rank": "${{ index + 1 }}",
1404
+ "handle": "${{ item.handle }}",
1405
+ "name": "${{ item.displayName }}",
1406
+ "description": "${{ item.description }}"
1407
+ }
1408
+ },
1409
+ {
1410
+ "limit": "${{ args.limit }}"
1411
+ }
1412
+ ],
1413
+ "type": "yaml"
1414
+ },
1415
+ {
1416
+ "site": "bluesky",
1417
+ "name": "following",
1418
+ "description": "List accounts a Bluesky user is following",
1419
+ "domain": "public.api.bsky.app",
1420
+ "strategy": "public",
1421
+ "browser": false,
1422
+ "args": [
1423
+ {
1424
+ "name": "handle",
1425
+ "type": "str",
1426
+ "required": true,
1427
+ "positional": true,
1428
+ "help": "Bluesky handle"
1429
+ },
1430
+ {
1431
+ "name": "limit",
1432
+ "type": "int",
1433
+ "default": 20,
1434
+ "required": false,
1435
+ "positional": false,
1436
+ "help": "Number of accounts"
1437
+ }
1438
+ ],
1439
+ "columns": [
1440
+ "rank",
1441
+ "handle",
1442
+ "name",
1443
+ "description"
1444
+ ],
1445
+ "pipeline": [
1446
+ {
1447
+ "fetch": {
1448
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.graph.getFollows?actor=${{ args.handle }}&limit=${{ args.limit }}"
1449
+ }
1450
+ },
1451
+ {
1452
+ "select": "follows"
1453
+ },
1454
+ {
1455
+ "map": {
1456
+ "rank": "${{ index + 1 }}",
1457
+ "handle": "${{ item.handle }}",
1458
+ "name": "${{ item.displayName }}",
1459
+ "description": "${{ item.description }}"
1460
+ }
1461
+ },
1462
+ {
1463
+ "limit": "${{ args.limit }}"
1464
+ }
1465
+ ],
1466
+ "type": "yaml"
1467
+ },
1468
+ {
1469
+ "site": "bluesky",
1470
+ "name": "profile",
1471
+ "description": "Get Bluesky user profile info",
1472
+ "domain": "public.api.bsky.app",
1473
+ "strategy": "public",
1474
+ "browser": false,
1475
+ "args": [
1476
+ {
1477
+ "name": "handle",
1478
+ "type": "str",
1479
+ "required": true,
1480
+ "positional": true,
1481
+ "help": "Bluesky handle (e.g. bsky.app, jay.bsky.team)"
1482
+ }
1483
+ ],
1484
+ "columns": [
1485
+ "handle",
1486
+ "name",
1487
+ "followers",
1488
+ "following",
1489
+ "posts",
1490
+ "description"
1491
+ ],
1492
+ "pipeline": [
1493
+ {
1494
+ "fetch": {
1495
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${{ args.handle }}"
1496
+ }
1497
+ },
1498
+ {
1499
+ "map": {
1500
+ "handle": "${{ item.handle }}",
1501
+ "name": "${{ item.displayName }}",
1502
+ "followers": "${{ item.followersCount }}",
1503
+ "following": "${{ item.followsCount }}",
1504
+ "posts": "${{ item.postsCount }}",
1505
+ "description": "${{ item.description }}"
1506
+ }
1507
+ }
1508
+ ],
1509
+ "type": "yaml"
1510
+ },
1511
+ {
1512
+ "site": "bluesky",
1513
+ "name": "search",
1514
+ "description": "Search Bluesky users",
1515
+ "domain": "public.api.bsky.app",
1516
+ "strategy": "public",
1517
+ "browser": false,
1518
+ "args": [
1519
+ {
1520
+ "name": "query",
1521
+ "type": "str",
1522
+ "required": true,
1523
+ "positional": true,
1524
+ "help": "Search query"
1525
+ },
1526
+ {
1527
+ "name": "limit",
1528
+ "type": "int",
1529
+ "default": 10,
1530
+ "required": false,
1531
+ "positional": false,
1532
+ "help": "Number of results"
1533
+ }
1534
+ ],
1535
+ "columns": [
1536
+ "rank",
1537
+ "handle",
1538
+ "name",
1539
+ "followers",
1540
+ "description"
1541
+ ],
1542
+ "pipeline": [
1543
+ {
1544
+ "fetch": {
1545
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.actor.searchActors?q=${{ args.query }}&limit=${{ args.limit }}"
1546
+ }
1547
+ },
1548
+ {
1549
+ "select": "actors"
1550
+ },
1551
+ {
1552
+ "map": {
1553
+ "rank": "${{ index + 1 }}",
1554
+ "handle": "${{ item.handle }}",
1555
+ "name": "${{ item.displayName }}",
1556
+ "followers": "${{ item.followersCount }}",
1557
+ "description": "${{ item.description }}"
1558
+ }
1559
+ },
1560
+ {
1561
+ "limit": "${{ args.limit }}"
1562
+ }
1563
+ ],
1564
+ "type": "yaml"
1565
+ },
1566
+ {
1567
+ "site": "bluesky",
1568
+ "name": "starter-packs",
1569
+ "description": "Get starter packs created by a Bluesky user",
1570
+ "domain": "public.api.bsky.app",
1571
+ "strategy": "public",
1572
+ "browser": false,
1573
+ "args": [
1574
+ {
1575
+ "name": "handle",
1576
+ "type": "str",
1577
+ "required": true,
1578
+ "positional": true,
1579
+ "help": "Bluesky handle"
1580
+ },
1581
+ {
1582
+ "name": "limit",
1583
+ "type": "int",
1584
+ "default": 10,
1585
+ "required": false,
1586
+ "positional": false,
1587
+ "help": "Number of starter packs"
1588
+ }
1589
+ ],
1590
+ "columns": [
1591
+ "rank",
1592
+ "name",
1593
+ "description",
1594
+ "members",
1595
+ "joins"
1596
+ ],
1597
+ "pipeline": [
1598
+ {
1599
+ "fetch": {
1600
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.graph.getActorStarterPacks?actor=${{ args.handle }}&limit=${{ args.limit }}"
1601
+ }
1602
+ },
1603
+ {
1604
+ "select": "starterPacks"
1605
+ },
1606
+ {
1607
+ "map": {
1608
+ "rank": "${{ index + 1 }}",
1609
+ "name": "${{ item.record.name }}",
1610
+ "description": "${{ item.record.description }}",
1611
+ "members": "${{ item.listItemCount }}",
1612
+ "joins": "${{ item.joinedAllTimeCount }}"
1613
+ }
1614
+ },
1615
+ {
1616
+ "limit": "${{ args.limit }}"
1617
+ }
1618
+ ],
1619
+ "type": "yaml"
1620
+ },
1621
+ {
1622
+ "site": "bluesky",
1623
+ "name": "thread",
1624
+ "description": "Get a Bluesky post thread with replies",
1625
+ "domain": "public.api.bsky.app",
1626
+ "strategy": "public",
1627
+ "browser": false,
1628
+ "args": [
1629
+ {
1630
+ "name": "uri",
1631
+ "type": "str",
1632
+ "required": true,
1633
+ "positional": true,
1634
+ "help": "Post AT URI (at://did:.../app.bsky.feed.post/...) or bsky.app URL"
1635
+ },
1636
+ {
1637
+ "name": "limit",
1638
+ "type": "int",
1639
+ "default": 20,
1640
+ "required": false,
1641
+ "positional": false,
1642
+ "help": "Number of replies"
1643
+ }
1644
+ ],
1645
+ "columns": [
1646
+ "author",
1647
+ "text",
1648
+ "likes",
1649
+ "reposts",
1650
+ "replies_count"
1651
+ ],
1652
+ "pipeline": [
1653
+ {
1654
+ "fetch": {
1655
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${{ args.uri }}&depth=2"
1656
+ }
1657
+ },
1658
+ {
1659
+ "select": "thread"
1660
+ },
1661
+ {
1662
+ "map": {
1663
+ "author": "${{ item.post.author.handle }}",
1664
+ "text": "${{ item.post.record.text }}",
1665
+ "likes": "${{ item.post.likeCount }}",
1666
+ "reposts": "${{ item.post.repostCount }}",
1667
+ "replies_count": "${{ item.post.replyCount }}"
1668
+ }
1669
+ }
1670
+ ],
1671
+ "type": "yaml"
1672
+ },
1673
+ {
1674
+ "site": "bluesky",
1675
+ "name": "trending",
1676
+ "description": "Trending topics on Bluesky",
1677
+ "domain": "public.api.bsky.app",
1678
+ "strategy": "public",
1679
+ "browser": false,
1680
+ "args": [
1681
+ {
1682
+ "name": "limit",
1683
+ "type": "int",
1684
+ "default": 20,
1685
+ "required": false,
1686
+ "positional": false,
1687
+ "help": "Number of topics"
1688
+ }
1689
+ ],
1690
+ "columns": [
1691
+ "rank",
1692
+ "topic",
1693
+ "link"
1694
+ ],
1695
+ "pipeline": [
1696
+ {
1697
+ "fetch": {
1698
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.unspecced.getTrendingTopics"
1699
+ }
1700
+ },
1701
+ {
1702
+ "select": "topics"
1703
+ },
1704
+ {
1705
+ "map": {
1706
+ "rank": "${{ index + 1 }}",
1707
+ "topic": "${{ item.topic }}",
1708
+ "link": "${{ item.link }}"
1709
+ }
1710
+ },
1711
+ {
1712
+ "limit": "${{ args.limit }}"
1713
+ }
1714
+ ],
1715
+ "type": "yaml"
1716
+ },
1717
+ {
1718
+ "site": "bluesky",
1719
+ "name": "user",
1720
+ "description": "Get recent posts from a Bluesky user",
1721
+ "domain": "public.api.bsky.app",
1722
+ "strategy": "public",
1723
+ "browser": false,
1724
+ "args": [
1725
+ {
1726
+ "name": "handle",
1727
+ "type": "str",
1728
+ "required": true,
1729
+ "positional": true,
1730
+ "help": "Bluesky handle (e.g. bsky.app)"
1731
+ },
1732
+ {
1733
+ "name": "limit",
1734
+ "type": "int",
1735
+ "default": 20,
1736
+ "required": false,
1737
+ "positional": false,
1738
+ "help": "Number of posts"
1739
+ }
1740
+ ],
1741
+ "columns": [
1742
+ "rank",
1743
+ "text",
1744
+ "likes",
1745
+ "reposts",
1746
+ "replies"
1747
+ ],
1748
+ "pipeline": [
1749
+ {
1750
+ "fetch": {
1751
+ "url": "https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${{ args.handle }}&limit=${{ args.limit }}"
1752
+ }
1753
+ },
1754
+ {
1755
+ "select": "feed"
1756
+ },
1757
+ {
1758
+ "map": {
1759
+ "rank": "${{ index + 1 }}",
1760
+ "text": "${{ item.post.record.text }}",
1761
+ "likes": "${{ item.post.likeCount }}",
1762
+ "reposts": "${{ item.post.repostCount }}",
1763
+ "replies": "${{ item.post.replyCount }}"
1764
+ }
1765
+ },
1766
+ {
1767
+ "limit": "${{ args.limit }}"
1155
1768
  }
1156
1769
  ],
1157
- "type": "ts",
1158
- "modulePath": "bloomberg/tech.js",
1159
- "domain": "feeds.bloomberg.com",
1160
- "columns": [
1161
- "title",
1162
- "summary",
1163
- "link",
1164
- "mediaLinks"
1165
- ]
1770
+ "type": "yaml"
1166
1771
  },
1167
1772
  {
1168
1773
  "site": "boss",
@@ -1804,6 +2409,12 @@
1804
2409
  "positional": true,
1805
2410
  "help": "Prompt to send"
1806
2411
  },
2412
+ {
2413
+ "name": "model",
2414
+ "type": "str",
2415
+ "required": false,
2416
+ "help": "Model/mode to use: auto, instant, thinking, 5.2-instant, 5.2-thinking"
2417
+ },
1807
2418
  {
1808
2419
  "name": "timeout",
1809
2420
  "type": "str",
@@ -1820,6 +2431,29 @@
1820
2431
  "Text"
1821
2432
  ]
1822
2433
  },
2434
+ {
2435
+ "site": "chatgpt",
2436
+ "name": "model",
2437
+ "description": "Switch ChatGPT Desktop model/mode (auto, instant, thinking, 5.2-instant, 5.2-thinking)",
2438
+ "strategy": "public",
2439
+ "browser": false,
2440
+ "args": [
2441
+ {
2442
+ "name": "model",
2443
+ "type": "str",
2444
+ "required": true,
2445
+ "positional": true,
2446
+ "help": "Model to switch to"
2447
+ }
2448
+ ],
2449
+ "type": "ts",
2450
+ "modulePath": "chatgpt/model.js",
2451
+ "domain": "localhost",
2452
+ "columns": [
2453
+ "Status",
2454
+ "Model"
2455
+ ]
2456
+ },
1823
2457
  {
1824
2458
  "site": "chatgpt",
1825
2459
  "name": "new",
@@ -1862,6 +2496,12 @@
1862
2496
  "required": true,
1863
2497
  "positional": true,
1864
2498
  "help": "Message to send"
2499
+ },
2500
+ {
2501
+ "name": "model",
2502
+ "type": "str",
2503
+ "required": false,
2504
+ "help": "Model/mode to use: auto, instant, thinking, 5.2-instant, 5.2-thinking"
1865
2505
  }
1866
2506
  ],
1867
2507
  "type": "ts",
@@ -2461,6 +3101,7 @@
2461
3101
  "type": "int",
2462
3102
  "default": 20,
2463
3103
  "required": false,
3104
+ "positional": false,
2464
3105
  "help": "Number of articles"
2465
3106
  }
2466
3107
  ],
@@ -2508,6 +3149,7 @@
2508
3149
  "type": "int",
2509
3150
  "default": 20,
2510
3151
  "required": false,
3152
+ "positional": false,
2511
3153
  "help": "Number of articles"
2512
3154
  }
2513
3155
  ],
@@ -2562,6 +3204,7 @@
2562
3204
  "type": "int",
2563
3205
  "default": 20,
2564
3206
  "required": false,
3207
+ "positional": false,
2565
3208
  "help": "Number of articles"
2566
3209
  }
2567
3210
  ],
@@ -2874,6 +3517,58 @@
2874
3517
  "url"
2875
3518
  ]
2876
3519
  },
3520
+ {
3521
+ "site": "douban",
3522
+ "name": "download",
3523
+ "description": "下载电影海报/剧照图片",
3524
+ "strategy": "cookie",
3525
+ "browser": true,
3526
+ "args": [
3527
+ {
3528
+ "name": "id",
3529
+ "type": "str",
3530
+ "required": true,
3531
+ "positional": true,
3532
+ "help": "电影 subject ID"
3533
+ },
3534
+ {
3535
+ "name": "type",
3536
+ "type": "str",
3537
+ "default": "Rb",
3538
+ "required": false,
3539
+ "help": "豆瓣 photos 的 type 参数,默认 Rb(海报)"
3540
+ },
3541
+ {
3542
+ "name": "limit",
3543
+ "type": "int",
3544
+ "default": 120,
3545
+ "required": false,
3546
+ "help": "最多下载多少张图片"
3547
+ },
3548
+ {
3549
+ "name": "photo-id",
3550
+ "type": "str",
3551
+ "required": false,
3552
+ "help": "只下载指定 photo_id 的图片"
3553
+ },
3554
+ {
3555
+ "name": "output",
3556
+ "type": "str",
3557
+ "default": "./douban-downloads",
3558
+ "required": false,
3559
+ "help": "输出目录"
3560
+ }
3561
+ ],
3562
+ "type": "ts",
3563
+ "modulePath": "douban/download.js",
3564
+ "domain": "movie.douban.com",
3565
+ "columns": [
3566
+ "index",
3567
+ "title",
3568
+ "status",
3569
+ "size"
3570
+ ]
3571
+ },
2877
3572
  {
2878
3573
  "site": "douban",
2879
3574
  "name": "marks",
@@ -2950,6 +3645,45 @@
2950
3645
  "url"
2951
3646
  ]
2952
3647
  },
3648
+ {
3649
+ "site": "douban",
3650
+ "name": "photos",
3651
+ "description": "获取电影海报/剧照图片列表",
3652
+ "strategy": "cookie",
3653
+ "browser": true,
3654
+ "args": [
3655
+ {
3656
+ "name": "id",
3657
+ "type": "str",
3658
+ "required": true,
3659
+ "positional": true,
3660
+ "help": "电影 subject ID"
3661
+ },
3662
+ {
3663
+ "name": "type",
3664
+ "type": "str",
3665
+ "default": "Rb",
3666
+ "required": false,
3667
+ "help": "豆瓣 photos 的 type 参数,默认 Rb(海报)"
3668
+ },
3669
+ {
3670
+ "name": "limit",
3671
+ "type": "int",
3672
+ "default": 120,
3673
+ "required": false,
3674
+ "help": "最多返回多少张图片"
3675
+ }
3676
+ ],
3677
+ "type": "ts",
3678
+ "modulePath": "douban/photos.js",
3679
+ "domain": "movie.douban.com",
3680
+ "columns": [
3681
+ "index",
3682
+ "title",
3683
+ "image_url",
3684
+ "detail_url"
3685
+ ]
3686
+ },
2953
3687
  {
2954
3688
  "site": "douban",
2955
3689
  "name": "reviews",
@@ -3087,6 +3821,7 @@
3087
3821
  "type": "int",
3088
3822
  "default": 250,
3089
3823
  "required": false,
3824
+ "positional": false,
3090
3825
  "help": "返回结果数量"
3091
3826
  }
3092
3827
  ],
@@ -3859,6 +4594,7 @@
3859
4594
  "type": "int",
3860
4595
  "default": 15,
3861
4596
  "required": false,
4597
+ "positional": false,
3862
4598
  "help": "Number of categories"
3863
4599
  }
3864
4600
  ],
@@ -3892,6 +4628,7 @@
3892
4628
  "type": "int",
3893
4629
  "default": 10,
3894
4630
  "required": false,
4631
+ "positional": false,
3895
4632
  "help": "Number of posts"
3896
4633
  }
3897
4634
  ],
@@ -3929,6 +4666,7 @@
3929
4666
  "type": "int",
3930
4667
  "default": 10,
3931
4668
  "required": false,
4669
+ "positional": false,
3932
4670
  "help": "Number of friend suggestions"
3933
4671
  }
3934
4672
  ],
@@ -3963,6 +4701,7 @@
3963
4701
  "type": "int",
3964
4702
  "default": 20,
3965
4703
  "required": false,
4704
+ "positional": false,
3966
4705
  "help": "Number of groups"
3967
4706
  }
3968
4707
  ],
@@ -4031,6 +4770,7 @@
4031
4770
  "type": "int",
4032
4771
  "default": 10,
4033
4772
  "required": false,
4773
+ "positional": false,
4034
4774
  "help": "Number of memories"
4035
4775
  }
4036
4776
  ],
@@ -4066,6 +4806,7 @@
4066
4806
  "type": "int",
4067
4807
  "default": 15,
4068
4808
  "required": false,
4809
+ "positional": false,
4069
4810
  "help": "Number of notifications"
4070
4811
  }
4071
4812
  ],
@@ -4143,6 +4884,7 @@
4143
4884
  "type": "int",
4144
4885
  "default": 10,
4145
4886
  "required": false,
4887
+ "positional": false,
4146
4888
  "help": "Number of results"
4147
4889
  }
4148
4890
  ],
@@ -4360,6 +5102,7 @@
4360
5102
  "type": "int",
4361
5103
  "default": 20,
4362
5104
  "required": false,
5105
+ "positional": false,
4363
5106
  "help": "Number of stories"
4364
5107
  }
4365
5108
  ],
@@ -4421,6 +5164,7 @@
4421
5164
  "type": "int",
4422
5165
  "default": 20,
4423
5166
  "required": false,
5167
+ "positional": false,
4424
5168
  "help": "Number of stories"
4425
5169
  }
4426
5170
  ],
@@ -4482,6 +5226,7 @@
4482
5226
  "type": "int",
4483
5227
  "default": 20,
4484
5228
  "required": false,
5229
+ "positional": false,
4485
5230
  "help": "Number of job postings"
4486
5231
  }
4487
5232
  ],
@@ -4540,6 +5285,7 @@
4540
5285
  "type": "int",
4541
5286
  "default": 20,
4542
5287
  "required": false,
5288
+ "positional": false,
4543
5289
  "help": "Number of stories"
4544
5290
  }
4545
5291
  ],
@@ -4608,6 +5354,7 @@
4608
5354
  "type": "int",
4609
5355
  "default": 20,
4610
5356
  "required": false,
5357
+ "positional": false,
4611
5358
  "help": "Number of results"
4612
5359
  },
4613
5360
  {
@@ -4615,6 +5362,7 @@
4615
5362
  "type": "str",
4616
5363
  "default": "relevance",
4617
5364
  "required": false,
5365
+ "positional": false,
4618
5366
  "help": "Sort by relevance or date",
4619
5367
  "choices": [
4620
5368
  "relevance",
@@ -4673,6 +5421,7 @@
4673
5421
  "type": "int",
4674
5422
  "default": 20,
4675
5423
  "required": false,
5424
+ "positional": false,
4676
5425
  "help": "Number of stories"
4677
5426
  }
4678
5427
  ],
@@ -4734,6 +5483,7 @@
4734
5483
  "type": "int",
4735
5484
  "default": 20,
4736
5485
  "required": false,
5486
+ "positional": false,
4737
5487
  "help": "Number of stories"
4738
5488
  }
4739
5489
  ],
@@ -4862,8 +5612,182 @@
4862
5612
  }
4863
5613
  ],
4864
5614
  "type": "ts",
4865
- "modulePath": "hf/top.js",
4866
- "domain": "huggingface.co"
5615
+ "modulePath": "hf/top.js",
5616
+ "domain": "huggingface.co"
5617
+ },
5618
+ {
5619
+ "site": "imdb",
5620
+ "name": "person",
5621
+ "description": "Get actor or director info",
5622
+ "strategy": "public",
5623
+ "browser": true,
5624
+ "args": [
5625
+ {
5626
+ "name": "id",
5627
+ "type": "str",
5628
+ "required": true,
5629
+ "positional": true,
5630
+ "help": "IMDb person ID (nm0634240) or URL"
5631
+ },
5632
+ {
5633
+ "name": "limit",
5634
+ "type": "int",
5635
+ "default": 10,
5636
+ "required": false,
5637
+ "help": "Max filmography entries"
5638
+ }
5639
+ ],
5640
+ "type": "ts",
5641
+ "modulePath": "imdb/person.js",
5642
+ "domain": "www.imdb.com",
5643
+ "columns": [
5644
+ "field",
5645
+ "value"
5646
+ ]
5647
+ },
5648
+ {
5649
+ "site": "imdb",
5650
+ "name": "reviews",
5651
+ "description": "Get user reviews for a movie or TV show",
5652
+ "strategy": "public",
5653
+ "browser": true,
5654
+ "args": [
5655
+ {
5656
+ "name": "id",
5657
+ "type": "str",
5658
+ "required": true,
5659
+ "positional": true,
5660
+ "help": "IMDb title ID (tt1375666) or URL"
5661
+ },
5662
+ {
5663
+ "name": "limit",
5664
+ "type": "int",
5665
+ "default": 10,
5666
+ "required": false,
5667
+ "help": "Number of reviews"
5668
+ }
5669
+ ],
5670
+ "type": "ts",
5671
+ "modulePath": "imdb/reviews.js",
5672
+ "domain": "www.imdb.com",
5673
+ "columns": [
5674
+ "rank",
5675
+ "title",
5676
+ "rating",
5677
+ "author",
5678
+ "date",
5679
+ "text"
5680
+ ]
5681
+ },
5682
+ {
5683
+ "site": "imdb",
5684
+ "name": "search",
5685
+ "description": "Search IMDb for movies, TV shows, and people",
5686
+ "strategy": "public",
5687
+ "browser": true,
5688
+ "args": [
5689
+ {
5690
+ "name": "query",
5691
+ "type": "str",
5692
+ "required": true,
5693
+ "positional": true,
5694
+ "help": "Search query"
5695
+ },
5696
+ {
5697
+ "name": "limit",
5698
+ "type": "int",
5699
+ "default": 20,
5700
+ "required": false,
5701
+ "help": "Number of results"
5702
+ }
5703
+ ],
5704
+ "type": "ts",
5705
+ "modulePath": "imdb/search.js",
5706
+ "domain": "www.imdb.com",
5707
+ "columns": [
5708
+ "rank",
5709
+ "id",
5710
+ "title",
5711
+ "year",
5712
+ "type",
5713
+ "url"
5714
+ ]
5715
+ },
5716
+ {
5717
+ "site": "imdb",
5718
+ "name": "title",
5719
+ "description": "Get movie or TV show details",
5720
+ "strategy": "public",
5721
+ "browser": true,
5722
+ "args": [
5723
+ {
5724
+ "name": "id",
5725
+ "type": "str",
5726
+ "required": true,
5727
+ "positional": true,
5728
+ "help": "IMDb title ID (tt1375666) or URL"
5729
+ }
5730
+ ],
5731
+ "type": "ts",
5732
+ "modulePath": "imdb/title.js",
5733
+ "domain": "www.imdb.com",
5734
+ "columns": [
5735
+ "field",
5736
+ "value"
5737
+ ]
5738
+ },
5739
+ {
5740
+ "site": "imdb",
5741
+ "name": "top",
5742
+ "description": "IMDb Top 250 Movies",
5743
+ "strategy": "public",
5744
+ "browser": true,
5745
+ "args": [
5746
+ {
5747
+ "name": "limit",
5748
+ "type": "int",
5749
+ "default": 20,
5750
+ "required": false,
5751
+ "help": "Number of results"
5752
+ }
5753
+ ],
5754
+ "type": "ts",
5755
+ "modulePath": "imdb/top.js",
5756
+ "domain": "www.imdb.com",
5757
+ "columns": [
5758
+ "rank",
5759
+ "title",
5760
+ "rating",
5761
+ "votes",
5762
+ "genre",
5763
+ "url"
5764
+ ]
5765
+ },
5766
+ {
5767
+ "site": "imdb",
5768
+ "name": "trending",
5769
+ "description": "IMDb Most Popular Movies",
5770
+ "strategy": "public",
5771
+ "browser": true,
5772
+ "args": [
5773
+ {
5774
+ "name": "limit",
5775
+ "type": "int",
5776
+ "default": 20,
5777
+ "required": false,
5778
+ "help": "Number of results"
5779
+ }
5780
+ ],
5781
+ "type": "ts",
5782
+ "modulePath": "imdb/trending.js",
5783
+ "domain": "www.imdb.com",
5784
+ "columns": [
5785
+ "rank",
5786
+ "title",
5787
+ "rating",
5788
+ "genre",
5789
+ "url"
5790
+ ]
4867
5791
  },
4868
5792
  {
4869
5793
  "site": "instagram",
@@ -4892,6 +5816,7 @@
4892
5816
  "type": "int",
4893
5817
  "default": 1,
4894
5818
  "required": false,
5819
+ "positional": false,
4895
5820
  "help": "Post index (1 = most recent)"
4896
5821
  }
4897
5822
  ],
@@ -4923,6 +5848,7 @@
4923
5848
  "type": "int",
4924
5849
  "default": 20,
4925
5850
  "required": false,
5851
+ "positional": false,
4926
5852
  "help": "Number of posts"
4927
5853
  }
4928
5854
  ],
@@ -4994,6 +5920,7 @@
4994
5920
  "type": "int",
4995
5921
  "default": 20,
4996
5922
  "required": false,
5923
+ "positional": false,
4997
5924
  "help": "Number of followers"
4998
5925
  }
4999
5926
  ],
@@ -5034,6 +5961,7 @@
5034
5961
  "type": "int",
5035
5962
  "default": 20,
5036
5963
  "required": false,
5964
+ "positional": false,
5037
5965
  "help": "Number of accounts"
5038
5966
  }
5039
5967
  ],
@@ -5074,6 +6002,7 @@
5074
6002
  "type": "int",
5075
6003
  "default": 1,
5076
6004
  "required": false,
6005
+ "positional": false,
5077
6006
  "help": "Post index (1 = most recent)"
5078
6007
  }
5079
6008
  ],
@@ -5147,6 +6076,7 @@
5147
6076
  "type": "int",
5148
6077
  "default": 1,
5149
6078
  "required": false,
6079
+ "positional": false,
5150
6080
  "help": "Post index (1 = most recent)"
5151
6081
  }
5152
6082
  ],
@@ -5178,6 +6108,7 @@
5178
6108
  "type": "int",
5179
6109
  "default": 20,
5180
6110
  "required": false,
6111
+ "positional": false,
5181
6112
  "help": "Number of saved posts"
5182
6113
  }
5183
6114
  ],
@@ -5219,6 +6150,7 @@
5219
6150
  "type": "int",
5220
6151
  "default": 10,
5221
6152
  "required": false,
6153
+ "positional": false,
5222
6154
  "help": "Number of results"
5223
6155
  }
5224
6156
  ],
@@ -5290,6 +6222,7 @@
5290
6222
  "type": "int",
5291
6223
  "default": 1,
5292
6224
  "required": false,
6225
+ "positional": false,
5293
6226
  "help": "Post index (1 = most recent)"
5294
6227
  }
5295
6228
  ],
@@ -5328,6 +6261,7 @@
5328
6261
  "type": "int",
5329
6262
  "default": 1,
5330
6263
  "required": false,
6264
+ "positional": false,
5331
6265
  "help": "Post index (1 = most recent)"
5332
6266
  }
5333
6267
  ],
@@ -5366,6 +6300,7 @@
5366
6300
  "type": "int",
5367
6301
  "default": 12,
5368
6302
  "required": false,
6303
+ "positional": false,
5369
6304
  "help": "Number of posts"
5370
6305
  }
5371
6306
  ],
@@ -5390,7 +6325,7 @@
5390
6325
  {
5391
6326
  "site": "jd",
5392
6327
  "name": "item",
5393
- "description": "京东商品详情(价格、主图、详情图、规格参数)",
6328
+ "description": "京东商品详情(价格、店铺、规格参数、AVIF 图片)",
5394
6329
  "strategy": "cookie",
5395
6330
  "browser": true,
5396
6331
  "args": [
@@ -5406,7 +6341,7 @@
5406
6341
  "type": "int",
5407
6342
  "default": 10,
5408
6343
  "required": false,
5409
- "help": "详情图数量(默认10)"
6344
+ "help": "AVIF 图片数量上限(默认10)"
5410
6345
  }
5411
6346
  ],
5412
6347
  "type": "ts",
@@ -5417,8 +6352,7 @@
5417
6352
  "price",
5418
6353
  "shop",
5419
6354
  "specs",
5420
- "mainImages",
5421
- "detailImages"
6355
+ "avifImages"
5422
6356
  ]
5423
6357
  },
5424
6358
  {
@@ -5675,6 +6609,7 @@
5675
6609
  "type": "int",
5676
6610
  "default": 20,
5677
6611
  "required": false,
6612
+ "positional": false,
5678
6613
  "help": "Number of posts"
5679
6614
  }
5680
6615
  ],
@@ -5729,6 +6664,7 @@
5729
6664
  "type": "int",
5730
6665
  "default": 20,
5731
6666
  "required": false,
6667
+ "positional": false,
5732
6668
  "help": "Number of posts"
5733
6669
  }
5734
6670
  ],
@@ -5783,6 +6719,7 @@
5783
6719
  "type": "string",
5784
6720
  "default": "high_aes_general_v50",
5785
6721
  "required": false,
6722
+ "positional": false,
5786
6723
  "help": "模型: high_aes_general_v50 (5.0 Lite), high_aes_general_v42 (4.6), high_aes_general_v40 (4.0)"
5787
6724
  },
5788
6725
  {
@@ -5790,6 +6727,7 @@
5790
6727
  "type": "int",
5791
6728
  "default": 40,
5792
6729
  "required": false,
6730
+ "positional": false,
5793
6731
  "help": "等待生成完成的秒数"
5794
6732
  }
5795
6733
  ],
@@ -5833,6 +6771,7 @@
5833
6771
  "type": "int",
5834
6772
  "default": 5,
5835
6773
  "required": false,
6774
+ "positional": false,
5836
6775
  "help": ""
5837
6776
  }
5838
6777
  ],
@@ -5988,11 +6927,20 @@
5988
6927
  "strategy": "cookie",
5989
6928
  "browser": true,
5990
6929
  "args": [
6930
+ {
6931
+ "name": "subcategories",
6932
+ "type": "boolean",
6933
+ "default": false,
6934
+ "required": false,
6935
+ "positional": false,
6936
+ "help": "Include subcategories"
6937
+ },
5991
6938
  {
5992
6939
  "name": "limit",
5993
6940
  "type": "int",
5994
6941
  "default": 20,
5995
6942
  "required": false,
6943
+ "positional": false,
5996
6944
  "help": "Number of categories"
5997
6945
  }
5998
6946
  ],
@@ -6008,7 +6956,7 @@
6008
6956
  "navigate": "https://linux.do"
6009
6957
  },
6010
6958
  {
6011
- "evaluate": "(async () => {\n const res = await fetch('/categories.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const cats = data?.category_list?.categories || [];\n return cats.slice(0, ${{ args.limit }}).map(c => ({\n name: c.name,\n slug: c.slug,\n id: c.id,\n topics: c.topic_count,\n description: (c.description_text || '').slice(0, 80),\n }));\n})()\n"
6959
+ "evaluate": "(async () => {\n const res = await fetch('/categories.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const cats = data?.category_list?.categories || [];\n const showSub = ${{ args.subcategories }};\n const results = [];\n const limit = ${{ args.limit }};\n for (const c of cats.slice(0, ${{ args.limit }})) {\n results.push({\n name: c.name,\n slug: c.slug,\n id: c.id,\n topics: c.topic_count,\n description: (c.description_text || '').slice(0, 80),\n });\n if (results.length >= limit) break;\n if (showSub && c.subcategory_ids && c.subcategory_ids.length > 0) {\n const subRes = await fetch('/categories.json?parent_category_id=' + c.id, { credentials: 'include' });\n if (subRes.ok) {\n let subData;\n try { subData = await subRes.json(); } catch { continue; }\n const subCats = subData?.category_list?.categories || [];\n for (const sc of subCats) {\n results.push({\n name: c.name + ' / ' + sc.name,\n slug: sc.slug,\n id: sc.id,\n topics: sc.topic_count,\n description: (sc.description_text || '').slice(0, 80),\n });\n if (results.length >= limit) break;\n }\n }\n }\n if (results.length >= limit) break;\n }\n return results;\n})()\n"
6012
6960
  },
6013
6961
  {
6014
6962
  "map": {
@@ -6018,9 +6966,6 @@
6018
6966
  "topics": "${{ item.topics }}",
6019
6967
  "description": "${{ item.description }}"
6020
6968
  }
6021
- },
6022
- {
6023
- "limit": "${{ args.limit }}"
6024
6969
  }
6025
6970
  ],
6026
6971
  "type": "yaml"
@@ -6029,7 +6974,6 @@
6029
6974
  "site": "linux-do",
6030
6975
  "name": "category",
6031
6976
  "description": "linux.do 分类内话题",
6032
- "domain": "linux.do",
6033
6977
  "strategy": "cookie",
6034
6978
  "browser": true,
6035
6979
  "args": [
@@ -6038,57 +6982,60 @@
6038
6982
  "type": "str",
6039
6983
  "required": true,
6040
6984
  "positional": true,
6041
- "help": "Category slug (use 'categories' command to find)"
6985
+ "help": "Category slug (legacy compatibility argument)"
6042
6986
  },
6043
6987
  {
6044
6988
  "name": "id",
6045
6989
  "type": "int",
6046
6990
  "required": true,
6047
6991
  "positional": true,
6048
- "help": "Category ID (use 'categories' command to find)"
6992
+ "help": "Category ID"
6049
6993
  },
6050
6994
  {
6051
6995
  "name": "limit",
6052
6996
  "type": "int",
6053
6997
  "default": 20,
6054
6998
  "required": false,
6055
- "help": "Number of topics"
6999
+ "help": "Number of items (per_page)"
6056
7000
  }
6057
7001
  ],
7002
+ "type": "ts",
7003
+ "modulePath": "linux-do/category.js",
7004
+ "domain": "linux.do",
6058
7005
  "columns": [
6059
- "rank",
6060
7006
  "title",
6061
7007
  "replies",
7008
+ "created",
7009
+ "likes",
6062
7010
  "views",
6063
- "likes"
6064
- ],
6065
- "pipeline": [
6066
- {
6067
- "navigate": "https://linux.do"
6068
- },
6069
- {
6070
- "evaluate": "(async () => {\n const slug = ${{ args.slug | json }};\n const res = await fetch('/c/' + encodeURIComponent(slug) + '/${{ args.id }}.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const topics = data?.topic_list?.topics || [];\n return topics.slice(0, ${{ args.limit }}).map(t => ({\n title: t.title,\n replies: (t.posts_count || 1) - 1,\n views: t.views,\n likes: t.like_count,\n }));\n})()\n"
6071
- },
6072
- {
6073
- "map": {
6074
- "rank": "${{ index + 1 }}",
6075
- "title": "${{ item.title }}",
6076
- "replies": "${{ item.replies }}",
6077
- "views": "${{ item.views }}",
6078
- "likes": "${{ item.likes }}"
6079
- }
6080
- },
6081
- {
6082
- "limit": "${{ args.limit }}"
6083
- }
7011
+ "url"
6084
7012
  ],
6085
- "type": "yaml"
7013
+ "deprecated": "opencli linux-do category is kept for backward compatibility.",
7014
+ "replacedBy": "opencli linux-do feed --category <id-or-name>"
7015
+ },
7016
+ {
7017
+ "site": "linux-do",
7018
+ "name": "feed",
7019
+ "description": "linux.do 话题列表(需登录;支持全站、标签、分类)",
7020
+ "strategy": "cookie",
7021
+ "browser": true,
7022
+ "args": [],
7023
+ "type": "ts",
7024
+ "modulePath": "linux-do/feed.js",
7025
+ "domain": "linux.do",
7026
+ "columns": [
7027
+ "title",
7028
+ "replies",
7029
+ "created",
7030
+ "likes",
7031
+ "views",
7032
+ "url"
7033
+ ]
6086
7034
  },
6087
7035
  {
6088
7036
  "site": "linux-do",
6089
7037
  "name": "hot",
6090
7038
  "description": "linux.do 热门话题",
6091
- "domain": "linux.do",
6092
7039
  "strategy": "cookie",
6093
7040
  "browser": true,
6094
7041
  "args": [
@@ -6097,7 +7044,7 @@
6097
7044
  "type": "int",
6098
7045
  "default": 20,
6099
7046
  "required": false,
6100
- "help": "Number of topics"
7047
+ "help": "Number of items (per_page)"
6101
7048
  },
6102
7049
  {
6103
7050
  "name": "period",
@@ -6110,33 +7057,101 @@
6110
7057
  "daily",
6111
7058
  "weekly",
6112
7059
  "monthly",
7060
+ "quarterly",
6113
7061
  "yearly"
6114
7062
  ]
6115
7063
  }
6116
7064
  ],
7065
+ "type": "ts",
7066
+ "modulePath": "linux-do/hot.js",
7067
+ "domain": "linux.do",
6117
7068
  "columns": [
6118
- "rank",
6119
7069
  "title",
6120
7070
  "replies",
7071
+ "created",
7072
+ "likes",
6121
7073
  "views",
7074
+ "url"
7075
+ ],
7076
+ "deprecated": "opencli linux-do hot is kept for backward compatibility.",
7077
+ "replacedBy": "opencli linux-do feed --view top --period <period>"
7078
+ },
7079
+ {
7080
+ "site": "linux-do",
7081
+ "name": "latest",
7082
+ "description": "linux.do 最新话题",
7083
+ "strategy": "cookie",
7084
+ "browser": true,
7085
+ "args": [
7086
+ {
7087
+ "name": "limit",
7088
+ "type": "int",
7089
+ "default": 20,
7090
+ "required": false,
7091
+ "help": "Number of items (per_page)"
7092
+ }
7093
+ ],
7094
+ "type": "ts",
7095
+ "modulePath": "linux-do/latest.js",
7096
+ "domain": "linux.do",
7097
+ "columns": [
7098
+ "title",
7099
+ "replies",
7100
+ "created",
6122
7101
  "likes",
6123
- "category"
7102
+ "views",
7103
+ "url"
7104
+ ],
7105
+ "deprecated": "opencli linux-do latest is kept for backward compatibility.",
7106
+ "replacedBy": "opencli linux-do feed --view latest"
7107
+ },
7108
+ {
7109
+ "site": "linux-do",
7110
+ "name": "search",
7111
+ "description": "搜索 linux.do",
7112
+ "domain": "linux.do",
7113
+ "strategy": "cookie",
7114
+ "browser": true,
7115
+ "args": [
7116
+ {
7117
+ "name": "query",
7118
+ "type": "str",
7119
+ "required": true,
7120
+ "positional": true,
7121
+ "help": "Search query"
7122
+ },
7123
+ {
7124
+ "name": "limit",
7125
+ "type": "int",
7126
+ "default": 20,
7127
+ "required": false,
7128
+ "positional": false,
7129
+ "help": "Number of results"
7130
+ }
7131
+ ],
7132
+ "columns": [
7133
+ "rank",
7134
+ "title",
7135
+ "views",
7136
+ "likes",
7137
+ "replies",
7138
+ "url"
6124
7139
  ],
6125
7140
  "pipeline": [
6126
7141
  {
6127
7142
  "navigate": "https://linux.do"
6128
7143
  },
6129
7144
  {
6130
- "evaluate": "(async () => {\n const period = ${{ args.period | json }};\n const res = await fetch('/top.json?period=' + encodeURIComponent(period), { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const topics = data?.topic_list?.topics || [];\n const cats = data?.topic_list?.categories || data?.categories || [];\n const catMap = Object.fromEntries(cats.map(c => [c.id, c.name]));\n return topics.slice(0, ${{ args.limit }}).map(t => ({\n title: t.title,\n replies: (t.posts_count || 1) - 1,\n views: t.views,\n likes: t.like_count,\n category: catMap[t.category_id] || String(t.category_id),\n }));\n})()\n"
7145
+ "evaluate": "(async () => {\n const keyword = ${{ args.query | json }};\n const res = await fetch('/search.json?q=' + encodeURIComponent(keyword), { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const topics = data?.topics || [];\n return topics.slice(0, ${{ args.limit }}).map(t => ({\n title: t.title,\n views: t.views,\n likes: t.like_count,\n replies: (t.posts_count || 1) - 1,\n url: 'https://linux.do/t/topic/' + t.id,\n }));\n})()\n"
6131
7146
  },
6132
7147
  {
6133
7148
  "map": {
6134
7149
  "rank": "${{ index + 1 }}",
6135
7150
  "title": "${{ item.title }}",
6136
- "replies": "${{ item.replies }}",
6137
7151
  "views": "${{ item.views }}",
6138
7152
  "likes": "${{ item.likes }}",
6139
- "category": "${{ item.category }}"
7153
+ "replies": "${{ item.replies }}",
7154
+ "url": "${{ item.url }}"
6140
7155
  }
6141
7156
  },
6142
7157
  {
@@ -6147,8 +7162,8 @@
6147
7162
  },
6148
7163
  {
6149
7164
  "site": "linux-do",
6150
- "name": "latest",
6151
- "description": "linux.do 最新话题",
7165
+ "name": "tags",
7166
+ "description": "linux.do 标签列表",
6152
7167
  "domain": "linux.do",
6153
7168
  "strategy": "cookie",
6154
7169
  "browser": true,
@@ -6156,69 +7171,124 @@
6156
7171
  {
6157
7172
  "name": "limit",
6158
7173
  "type": "int",
6159
- "default": 20,
7174
+ "default": 30,
6160
7175
  "required": false,
6161
- "help": "Number of topics"
7176
+ "positional": false,
7177
+ "help": "Number of tags"
6162
7178
  }
6163
7179
  ],
6164
7180
  "columns": [
6165
7181
  "rank",
6166
- "title",
6167
- "replies",
6168
- "views",
6169
- "likes"
7182
+ "name",
7183
+ "count",
7184
+ "url"
6170
7185
  ],
6171
7186
  "pipeline": [
6172
7187
  {
6173
7188
  "navigate": "https://linux.do"
6174
7189
  },
6175
7190
  {
6176
- "evaluate": "(async () => {\n const res = await fetch('/latest.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const topics = data?.topic_list?.topics || [];\n return topics.slice(0, ${{ args.limit }}).map(t => ({\n title: t.title,\n replies: (t.posts_count || 1) - 1,\n views: t.views,\n likes: t.like_count,\n }));\n})()\n"
7191
+ "evaluate": "(async () => {\n const res = await fetch('/tags.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n let tags = data?.tags || [];\n tags.sort((a, b) => (b.count || 0) - (a.count || 0));\n return tags.slice(0, ${{ args.limit }}).map(t => ({\n id: t.id,\n name: t.name || t.id,\n slug: t.slug,\n count: t.count || 0,\n }));\n})()\n"
6177
7192
  },
6178
7193
  {
6179
7194
  "map": {
6180
7195
  "rank": "${{ index + 1 }}",
6181
- "title": "${{ item.title }}",
6182
- "replies": "${{ item.replies }}",
6183
- "views": "${{ item.views }}",
6184
- "likes": "${{ item.likes }}"
7196
+ "name": "${{ item.name }}",
7197
+ "count": "${{ item.count }}",
7198
+ "slug": "${{ item.slug }}",
7199
+ "id": "${{ item.id }}",
7200
+ "url": "https://linux.do/tag/${{ item.slug }}"
6185
7201
  }
7202
+ }
7203
+ ],
7204
+ "type": "yaml"
7205
+ },
7206
+ {
7207
+ "site": "linux-do",
7208
+ "name": "topic",
7209
+ "description": "linux.do 帖子详情和回复(首页)",
7210
+ "domain": "linux.do",
7211
+ "strategy": "cookie",
7212
+ "browser": true,
7213
+ "args": [
7214
+ {
7215
+ "name": "id",
7216
+ "type": "int",
7217
+ "required": true,
7218
+ "positional": true,
7219
+ "help": "Topic ID"
6186
7220
  },
6187
7221
  {
6188
- "limit": "${{ args.limit }}"
7222
+ "name": "limit",
7223
+ "type": "int",
7224
+ "default": 20,
7225
+ "required": false,
7226
+ "positional": false,
7227
+ "help": "Number of posts"
7228
+ },
7229
+ {
7230
+ "name": "main_only",
7231
+ "type": "bool",
7232
+ "default": false,
7233
+ "required": false,
7234
+ "positional": false,
7235
+ "help": "Only return the main post body without truncation"
7236
+ }
7237
+ ],
7238
+ "columns": [
7239
+ "author",
7240
+ "content",
7241
+ "likes",
7242
+ "created_at"
7243
+ ],
7244
+ "pipeline": [
7245
+ {
7246
+ "navigate": "https://linux.do"
7247
+ },
7248
+ {
7249
+ "evaluate": "(async () => {\n const mainOnly = ${{ args.main_only }};\n const toLocalTime = (utcStr) => {\n if (!utcStr) return '';\n const date = new Date(utcStr);\n return Number.isNaN(date.getTime()) ? utcStr : date.toLocaleString();\n };\n const res = await fetch('/t/${{ args.id }}.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const strip = (html) => (html || '')\n .replace(/<br\\s*\\/?>/gi, ' ')\n .replace(/<\\/(p|div|li|blockquote|h[1-6])>/gi, ' ')\n .replace(/<[^>]+>/g, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#(?:(\\d+)|x([0-9a-fA-F]+));/g, (_, dec, hex) => {\n try { return String.fromCodePoint(dec !== undefined ? Number(dec) : parseInt(hex, 16)); } catch { return ''; }\n })\n .replace(/\\s+/g, ' ')\n .trim();\n const posts = data?.post_stream?.posts || [];\n if (mainOnly) {\n const mainPost = posts.find(p => p.post_number === 1);\n if (!mainPost) return [];\n return [{\n author: mainPost.username || '',\n content: mainPost.cooked || '',\n likes: mainPost.like_count || 0,\n created_at: toLocalTime(mainPost.created_at),\n }];\n }\n return posts.slice(0, ${{ args.limit }}).map(p => ({\n author: p.username,\n content: strip(p.cooked).slice(0, 200),\n likes: p.like_count,\n created_at: toLocalTime(p.created_at),\n }));\n})()\n"
7250
+ },
7251
+ {
7252
+ "map": {
7253
+ "author": "${{ item.author }}",
7254
+ "content": "${{ item.content }}",
7255
+ "likes": "${{ item.likes }}",
7256
+ "created_at": "${{ item.created_at }}"
7257
+ }
6189
7258
  }
6190
7259
  ],
6191
7260
  "type": "yaml"
6192
7261
  },
6193
7262
  {
6194
7263
  "site": "linux-do",
6195
- "name": "search",
6196
- "description": "搜索 linux.do",
7264
+ "name": "user-posts",
7265
+ "description": "linux.do 用户的帖子",
6197
7266
  "domain": "linux.do",
6198
7267
  "strategy": "cookie",
6199
7268
  "browser": true,
6200
7269
  "args": [
6201
7270
  {
6202
- "name": "query",
7271
+ "name": "username",
6203
7272
  "type": "str",
6204
7273
  "required": true,
6205
7274
  "positional": true,
6206
- "help": "Search query"
7275
+ "help": "Username"
6207
7276
  },
6208
7277
  {
6209
7278
  "name": "limit",
6210
7279
  "type": "int",
6211
7280
  "default": 20,
6212
7281
  "required": false,
6213
- "help": "Number of results"
7282
+ "positional": false,
7283
+ "help": "Number of posts"
6214
7284
  }
6215
7285
  ],
6216
7286
  "columns": [
6217
- "rank",
6218
- "title",
6219
- "views",
6220
- "likes",
6221
- "replies",
7287
+ "index",
7288
+ "topic_user",
7289
+ "topic",
7290
+ "reply",
7291
+ "time",
6222
7292
  "url"
6223
7293
  ],
6224
7294
  "pipeline": [
@@ -6226,59 +7296,70 @@
6226
7296
  "navigate": "https://linux.do"
6227
7297
  },
6228
7298
  {
6229
- "evaluate": "(async () => {\n const keyword = ${{ args.query | json }};\n const res = await fetch('/search.json?q=' + encodeURIComponent(keyword), { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const topics = data?.topics || [];\n return topics.slice(0, ${{ args.limit }}).map(t => ({\n title: t.title,\n views: t.views,\n likes: t.like_count,\n replies: (t.posts_count || 1) - 1,\n url: 'https://linux.do/t/topic/' + t.id,\n }));\n})()\n"
7299
+ "evaluate": "(async () => {\n const username = ${{ args.username | json }};\n const toLocalTime = (utcStr) => {\n if (!utcStr) return '';\n const date = new Date(utcStr);\n return Number.isNaN(date.getTime()) ? utcStr : date.toLocaleString();\n };\n const strip = (html) => (html || '')\n .replace(/<br\\s*\\/?>/gi, ' ')\n .replace(/<\\/(p|div|li|blockquote|h[1-6])>/gi, ' ')\n .replace(/<[^>]+>/g, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#(?:(\\d+)|x([0-9a-fA-F]+));/g, (_, dec, hex) => {\n try { return String.fromCodePoint(dec !== undefined ? Number(dec) : parseInt(hex, 16)); } catch { return ''; }\n })\n .replace(/\\s+/g, ' ')\n .trim();\n const limit = ${{ args.limit | default(20) }};\n const res = await fetch('/user_actions.json?username=' + encodeURIComponent(username) + '&filter=5&offset=0&limit=' + limit, { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const actions = data?.user_actions || [];\n return actions.slice(0, limit).map(a => ({\n author: a.acting_username || a.username || '',\n title: a.title || '',\n content: strip(a.excerpt).slice(0, 200),\n created_at: toLocalTime(a.created_at),\n url: 'https://linux.do/t/topic/' + a.topic_id + '/' + a.post_number,\n }));\n})()\n"
6230
7300
  },
6231
7301
  {
6232
7302
  "map": {
6233
- "rank": "${{ index + 1 }}",
6234
- "title": "${{ item.title }}",
6235
- "views": "${{ item.views }}",
6236
- "likes": "${{ item.likes }}",
6237
- "replies": "${{ item.replies }}",
7303
+ "index": "${{ index + 1 }}",
7304
+ "topic_user": "${{ item.author }}",
7305
+ "topic": "${{ item.title }}",
7306
+ "reply": "${{ item.content }}",
7307
+ "time": "${{ item.created_at }}",
6238
7308
  "url": "${{ item.url }}"
6239
7309
  }
6240
- },
6241
- {
6242
- "limit": "${{ args.limit }}"
6243
7310
  }
6244
7311
  ],
6245
7312
  "type": "yaml"
6246
7313
  },
6247
7314
  {
6248
7315
  "site": "linux-do",
6249
- "name": "topic",
6250
- "description": "linux.do 帖子详情和回复(首页)",
7316
+ "name": "user-topics",
7317
+ "description": "linux.do 用户创建的话题",
6251
7318
  "domain": "linux.do",
6252
7319
  "strategy": "cookie",
6253
7320
  "browser": true,
6254
7321
  "args": [
6255
7322
  {
6256
- "name": "id",
6257
- "type": "int",
7323
+ "name": "username",
7324
+ "type": "str",
6258
7325
  "required": true,
6259
7326
  "positional": true,
6260
- "help": "Topic ID"
7327
+ "help": "Username"
7328
+ },
7329
+ {
7330
+ "name": "limit",
7331
+ "type": "int",
7332
+ "default": 20,
7333
+ "required": false,
7334
+ "positional": false,
7335
+ "help": "Number of topics"
6261
7336
  }
6262
7337
  ],
6263
7338
  "columns": [
6264
- "author",
6265
- "content",
7339
+ "rank",
7340
+ "title",
7341
+ "replies",
7342
+ "created_at",
6266
7343
  "likes",
6267
- "created_at"
7344
+ "views",
7345
+ "url"
6268
7346
  ],
6269
7347
  "pipeline": [
6270
7348
  {
6271
7349
  "navigate": "https://linux.do"
6272
7350
  },
6273
7351
  {
6274
- "evaluate": "(async () => {\n const res = await fetch('/t/${{ args.id }}.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const strip = (html) => (html || '').replace(/<br\\s*\\/?>/gi, ' ').replace(/<\\/(p|div|li|blockquote|h[1-6])>/gi, ' ').replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '\"').replace(/&#(?:(\\d+)|x([0-9a-fA-F]+));/g, (_, dec, hex) => { try { return String.fromCodePoint(dec !== undefined ? Number(dec) : parseInt(hex, 16)); } catch { return ''; } }).replace(/\\s+/g, ' ').trim();\n const posts = data?.post_stream?.posts || [];\n return posts.map(p => ({\n author: p.username,\n content: strip(p.cooked).slice(0, 200),\n likes: p.like_count,\n created_at: p.created_at,\n }));\n})()\n"
7352
+ "evaluate": "(async () => {\n const username = ${{ args.username | json }};\n const toLocalTime = (utcStr) => {\n if (!utcStr) return '';\n const date = new Date(utcStr);\n return Number.isNaN(date.getTime()) ? utcStr : date.toLocaleString();\n };\n const res = await fetch('/topics/created-by/' + encodeURIComponent(username) + '.json', { credentials: 'include' });\n if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');\n let data;\n try { data = await res.json(); } catch { throw new Error('响应不是有效 JSON - 请先登录 linux.do'); }\n const topics = data?.topic_list?.topics || [];\n return topics.slice(0, ${{ args.limit }}).map(t => ({\n title: t.fancy_title || t.title || '',\n replies: t.posts_count || 0,\n created_at: toLocalTime(t.created_at),\n likes: t.like_count || 0,\n views: t.views || 0,\n url: 'https://linux.do/t/topic/' + t.id,\n }));\n})()\n"
6275
7353
  },
6276
7354
  {
6277
7355
  "map": {
6278
- "author": "${{ item.author }}",
6279
- "content": "${{ item.content }}",
7356
+ "rank": "${{ index + 1 }}",
7357
+ "title": "${{ item.title }}",
7358
+ "replies": "${{ item.replies }}",
7359
+ "created_at": "${{ item.created_at }}",
6280
7360
  "likes": "${{ item.likes }}",
6281
- "created_at": "${{ item.created_at }}"
7361
+ "views": "${{ item.views }}",
7362
+ "url": "${{ item.url }}"
6282
7363
  }
6283
7364
  }
6284
7365
  ],
@@ -6297,6 +7378,7 @@
6297
7378
  "type": "int",
6298
7379
  "default": 20,
6299
7380
  "required": false,
7381
+ "positional": false,
6300
7382
  "help": "Number of stories"
6301
7383
  }
6302
7384
  ],
@@ -6344,6 +7426,7 @@
6344
7426
  "type": "int",
6345
7427
  "default": 20,
6346
7428
  "required": false,
7429
+ "positional": false,
6347
7430
  "help": "Number of stories"
6348
7431
  }
6349
7432
  ],
@@ -6391,6 +7474,7 @@
6391
7474
  "type": "int",
6392
7475
  "default": 20,
6393
7476
  "required": false,
7477
+ "positional": false,
6394
7478
  "help": "Number of stories"
6395
7479
  }
6396
7480
  ],
@@ -6445,6 +7529,7 @@
6445
7529
  "type": "int",
6446
7530
  "default": 20,
6447
7531
  "required": false,
7532
+ "positional": false,
6448
7533
  "help": "Number of stories"
6449
7534
  }
6450
7535
  ],
@@ -6734,6 +7819,143 @@
6734
7819
  "Status"
6735
7820
  ]
6736
7821
  },
7822
+ {
7823
+ "site": "paperreview",
7824
+ "name": "feedback",
7825
+ "description": "Submit feedback for a paperreview.ai review token",
7826
+ "strategy": "public",
7827
+ "browser": false,
7828
+ "args": [
7829
+ {
7830
+ "name": "token",
7831
+ "type": "str",
7832
+ "required": true,
7833
+ "positional": true,
7834
+ "help": "Review token returned by paperreview.ai"
7835
+ },
7836
+ {
7837
+ "name": "helpfulness",
7838
+ "type": "int",
7839
+ "required": true,
7840
+ "help": "Helpfulness score from 1 to 5"
7841
+ },
7842
+ {
7843
+ "name": "critical-error",
7844
+ "type": "str",
7845
+ "required": true,
7846
+ "help": "Whether the review contains a critical error",
7847
+ "choices": [
7848
+ "yes",
7849
+ "no"
7850
+ ]
7851
+ },
7852
+ {
7853
+ "name": "actionable-suggestions",
7854
+ "type": "str",
7855
+ "required": true,
7856
+ "help": "Whether the review contains actionable suggestions",
7857
+ "choices": [
7858
+ "yes",
7859
+ "no"
7860
+ ]
7861
+ },
7862
+ {
7863
+ "name": "additional-comments",
7864
+ "type": "str",
7865
+ "required": false,
7866
+ "help": "Optional free-text feedback"
7867
+ }
7868
+ ],
7869
+ "type": "ts",
7870
+ "modulePath": "paperreview/feedback.js",
7871
+ "columns": [
7872
+ "status",
7873
+ "token",
7874
+ "helpfulness",
7875
+ "critical_error",
7876
+ "actionable_suggestions",
7877
+ "message"
7878
+ ]
7879
+ },
7880
+ {
7881
+ "site": "paperreview",
7882
+ "name": "review",
7883
+ "description": "Fetch a paperreview.ai review by token",
7884
+ "strategy": "public",
7885
+ "browser": false,
7886
+ "args": [
7887
+ {
7888
+ "name": "token",
7889
+ "type": "str",
7890
+ "required": true,
7891
+ "positional": true,
7892
+ "help": "Review token returned by paperreview.ai"
7893
+ }
7894
+ ],
7895
+ "type": "ts",
7896
+ "modulePath": "paperreview/review.js",
7897
+ "columns": [
7898
+ "status",
7899
+ "title",
7900
+ "venue",
7901
+ "numerical_score",
7902
+ "has_feedback",
7903
+ "review_url"
7904
+ ]
7905
+ },
7906
+ {
7907
+ "site": "paperreview",
7908
+ "name": "submit",
7909
+ "description": "Submit a PDF to paperreview.ai for review",
7910
+ "strategy": "public",
7911
+ "browser": false,
7912
+ "args": [
7913
+ {
7914
+ "name": "pdf",
7915
+ "type": "str",
7916
+ "required": true,
7917
+ "positional": true,
7918
+ "help": "Path to the paper PDF"
7919
+ },
7920
+ {
7921
+ "name": "email",
7922
+ "type": "str",
7923
+ "required": true,
7924
+ "help": "Email address for the submission"
7925
+ },
7926
+ {
7927
+ "name": "venue",
7928
+ "type": "str",
7929
+ "required": false,
7930
+ "help": "Optional target venue such as ICLR or NeurIPS"
7931
+ },
7932
+ {
7933
+ "name": "dry-run",
7934
+ "type": "bool",
7935
+ "default": false,
7936
+ "required": false,
7937
+ "help": "Validate the input and stop before remote submission"
7938
+ },
7939
+ {
7940
+ "name": "prepare-only",
7941
+ "type": "bool",
7942
+ "default": false,
7943
+ "required": false,
7944
+ "help": "Request an upload slot but stop before uploading the PDF"
7945
+ }
7946
+ ],
7947
+ "type": "ts",
7948
+ "modulePath": "paperreview/submit.js",
7949
+ "columns": [
7950
+ "status",
7951
+ "file",
7952
+ "email",
7953
+ "venue",
7954
+ "token",
7955
+ "review_url",
7956
+ "message"
7957
+ ]
7958
+ },
6737
7959
  {
6738
7960
  "site": "pixiv",
6739
7961
  "name": "detail",
@@ -6853,6 +8075,7 @@
6853
8075
  "type": "str",
6854
8076
  "default": "daily",
6855
8077
  "required": false,
8078
+ "positional": false,
6856
8079
  "help": "Ranking mode",
6857
8080
  "choices": [
6858
8081
  "daily",
@@ -6871,6 +8094,7 @@
6871
8094
  "type": "int",
6872
8095
  "default": 1,
6873
8096
  "required": false,
8097
+ "positional": false,
6874
8098
  "help": "Page number"
6875
8099
  },
6876
8100
  {
@@ -6878,6 +8102,7 @@
6878
8102
  "type": "int",
6879
8103
  "default": 20,
6880
8104
  "required": false,
8105
+ "positional": false,
6881
8106
  "help": "Number of results"
6882
8107
  }
6883
8108
  ],
@@ -7003,6 +8228,124 @@
7003
8228
  ],
7004
8229
  "type": "yaml"
7005
8230
  },
8231
+ {
8232
+ "site": "producthunt",
8233
+ "name": "browse",
8234
+ "description": "Best products in a Product Hunt category",
8235
+ "strategy": "intercept",
8236
+ "browser": true,
8237
+ "args": [
8238
+ {
8239
+ "name": "category",
8240
+ "type": "string",
8241
+ "required": true,
8242
+ "positional": true,
8243
+ "help": "Category slug, e.g. vibe-coding, ai-agents, developer-tools"
8244
+ },
8245
+ {
8246
+ "name": "limit",
8247
+ "type": "int",
8248
+ "default": 20,
8249
+ "required": false,
8250
+ "help": "Number of results (max 50)"
8251
+ }
8252
+ ],
8253
+ "type": "ts",
8254
+ "modulePath": "producthunt/browse.js",
8255
+ "domain": "www.producthunt.com",
8256
+ "columns": [
8257
+ "rank",
8258
+ "name",
8259
+ "tagline",
8260
+ "reviews",
8261
+ "url"
8262
+ ]
8263
+ },
8264
+ {
8265
+ "site": "producthunt",
8266
+ "name": "hot",
8267
+ "description": "Today",
8268
+ "strategy": "intercept",
8269
+ "browser": true,
8270
+ "args": [
8271
+ {
8272
+ "name": "limit",
8273
+ "type": "int",
8274
+ "default": 20,
8275
+ "required": false,
8276
+ "help": "Number of results (max 50)"
8277
+ }
8278
+ ],
8279
+ "type": "ts",
8280
+ "modulePath": "producthunt/hot.js",
8281
+ "domain": "www.producthunt.com",
8282
+ "columns": [
8283
+ "rank",
8284
+ "name",
8285
+ "votes",
8286
+ "url"
8287
+ ]
8288
+ },
8289
+ {
8290
+ "site": "producthunt",
8291
+ "name": "posts",
8292
+ "description": "Latest Product Hunt launches (optional category filter)",
8293
+ "strategy": "public",
8294
+ "browser": false,
8295
+ "args": [
8296
+ {
8297
+ "name": "limit",
8298
+ "type": "int",
8299
+ "default": 20,
8300
+ "required": false,
8301
+ "help": "Number of results (max 50)"
8302
+ },
8303
+ {
8304
+ "name": "category",
8305
+ "type": "string",
8306
+ "default": "",
8307
+ "required": false,
8308
+ "help": "Category filter: ${PRODUCTHUNT_CATEGORY_SLUGS.join("
8309
+ }
8310
+ ],
8311
+ "type": "ts",
8312
+ "modulePath": "producthunt/posts.js",
8313
+ "domain": "www.producthunt.com",
8314
+ "columns": [
8315
+ "rank",
8316
+ "name",
8317
+ "tagline",
8318
+ "author",
8319
+ "date",
8320
+ "url"
8321
+ ]
8322
+ },
8323
+ {
8324
+ "site": "producthunt",
8325
+ "name": "today",
8326
+ "description": "Today",
8327
+ "strategy": "public",
8328
+ "browser": false,
8329
+ "args": [
8330
+ {
8331
+ "name": "limit",
8332
+ "type": "int",
8333
+ "default": 20,
8334
+ "required": false,
8335
+ "help": "Max results"
8336
+ }
8337
+ ],
8338
+ "type": "ts",
8339
+ "modulePath": "producthunt/today.js",
8340
+ "domain": "www.producthunt.com",
8341
+ "columns": [
8342
+ "rank",
8343
+ "name",
8344
+ "tagline",
8345
+ "author",
8346
+ "url"
8347
+ ]
8348
+ },
7006
8349
  {
7007
8350
  "site": "reddit",
7008
8351
  "name": "comment",
@@ -7046,6 +8389,7 @@
7046
8389
  "type": "int",
7047
8390
  "default": 15,
7048
8391
  "required": false,
8392
+ "positional": false,
7049
8393
  "help": ""
7050
8394
  }
7051
8395
  ],
@@ -7093,6 +8437,7 @@
7093
8437
  "type": "str",
7094
8438
  "default": "",
7095
8439
  "required": false,
8440
+ "positional": false,
7096
8441
  "help": "Subreddit name (e.g. programming). Empty for frontpage"
7097
8442
  },
7098
8443
  {
@@ -7100,6 +8445,7 @@
7100
8445
  "type": "int",
7101
8446
  "default": 20,
7102
8447
  "required": false,
8448
+ "positional": false,
7103
8449
  "help": "Number of posts"
7104
8450
  }
7105
8451
  ],
@@ -7145,6 +8491,7 @@
7145
8491
  "type": "int",
7146
8492
  "default": 20,
7147
8493
  "required": false,
8494
+ "positional": false,
7148
8495
  "help": ""
7149
8496
  }
7150
8497
  ],
@@ -7315,6 +8662,7 @@
7315
8662
  "type": "string",
7316
8663
  "default": "",
7317
8664
  "required": false,
8665
+ "positional": false,
7318
8666
  "help": "Search within a specific subreddit"
7319
8667
  },
7320
8668
  {
@@ -7322,6 +8670,7 @@
7322
8670
  "type": "string",
7323
8671
  "default": "relevance",
7324
8672
  "required": false,
8673
+ "positional": false,
7325
8674
  "help": "Sort order: relevance, hot, top, new, comments"
7326
8675
  },
7327
8676
  {
@@ -7329,6 +8678,7 @@
7329
8678
  "type": "string",
7330
8679
  "default": "all",
7331
8680
  "required": false,
8681
+ "positional": false,
7332
8682
  "help": "Time filter: hour, day, week, month, year, all"
7333
8683
  },
7334
8684
  {
@@ -7336,6 +8686,7 @@
7336
8686
  "type": "int",
7337
8687
  "default": 15,
7338
8688
  "required": false,
8689
+ "positional": false,
7339
8690
  "help": ""
7340
8691
  }
7341
8692
  ],
@@ -7390,6 +8741,7 @@
7390
8741
  "type": "string",
7391
8742
  "default": "hot",
7392
8743
  "required": false,
8744
+ "positional": false,
7393
8745
  "help": "Sorting method: hot, new, top, rising, controversial"
7394
8746
  },
7395
8747
  {
@@ -7397,6 +8749,7 @@
7397
8749
  "type": "string",
7398
8750
  "default": "all",
7399
8751
  "required": false,
8752
+ "positional": false,
7400
8753
  "help": "Time filter for top/controversial: hour, day, week, month, year, all"
7401
8754
  },
7402
8755
  {
@@ -7404,6 +8757,7 @@
7404
8757
  "type": "int",
7405
8758
  "default": 15,
7406
8759
  "required": false,
8760
+ "positional": false,
7407
8761
  "help": ""
7408
8762
  }
7409
8763
  ],
@@ -7542,6 +8896,7 @@
7542
8896
  "type": "int",
7543
8897
  "default": 15,
7544
8898
  "required": false,
8899
+ "positional": false,
7545
8900
  "help": ""
7546
8901
  }
7547
8902
  ],
@@ -7592,6 +8947,7 @@
7592
8947
  "type": "int",
7593
8948
  "default": 15,
7594
8949
  "required": false,
8950
+ "positional": false,
7595
8951
  "help": ""
7596
8952
  }
7597
8953
  ],
@@ -7894,6 +9250,7 @@
7894
9250
  "type": "int",
7895
9251
  "default": 10,
7896
9252
  "required": false,
9253
+ "positional": false,
7897
9254
  "help": "Max number of results"
7898
9255
  }
7899
9256
  ],
@@ -7941,6 +9298,7 @@
7941
9298
  "type": "int",
7942
9299
  "default": 10,
7943
9300
  "required": false,
9301
+ "positional": false,
7944
9302
  "help": "Max number of results"
7945
9303
  }
7946
9304
  ],
@@ -7993,6 +9351,7 @@
7993
9351
  "type": "int",
7994
9352
  "default": 10,
7995
9353
  "required": false,
9354
+ "positional": false,
7996
9355
  "help": "Max number of results"
7997
9356
  }
7998
9357
  ],
@@ -8038,6 +9397,7 @@
8038
9397
  "type": "int",
8039
9398
  "default": 10,
8040
9399
  "required": false,
9400
+ "positional": false,
8041
9401
  "help": "Max number of results"
8042
9402
  }
8043
9403
  ],
@@ -8083,6 +9443,7 @@
8083
9443
  "type": "int",
8084
9444
  "default": 10,
8085
9445
  "required": false,
9446
+ "positional": false,
8086
9447
  "help": "Number of games"
8087
9448
  }
8088
9449
  ],
@@ -8283,6 +9644,7 @@
8283
9644
  "type": "int",
8284
9645
  "default": 20,
8285
9646
  "required": false,
9647
+ "positional": false,
8286
9648
  "help": "Number of videos"
8287
9649
  }
8288
9650
  ],
@@ -8351,6 +9713,7 @@
8351
9713
  "type": "int",
8352
9714
  "default": 20,
8353
9715
  "required": false,
9716
+ "positional": false,
8354
9717
  "help": "Number of accounts"
8355
9718
  }
8356
9719
  ],
@@ -8385,6 +9748,7 @@
8385
9748
  "type": "int",
8386
9749
  "default": 20,
8387
9750
  "required": false,
9751
+ "positional": false,
8388
9752
  "help": "Number of suggestions"
8389
9753
  }
8390
9754
  ],
@@ -8453,6 +9817,7 @@
8453
9817
  "type": "int",
8454
9818
  "default": 10,
8455
9819
  "required": false,
9820
+ "positional": false,
8456
9821
  "help": "Number of streams"
8457
9822
  }
8458
9823
  ],
@@ -8488,6 +9853,7 @@
8488
9853
  "type": "int",
8489
9854
  "default": 15,
8490
9855
  "required": false,
9856
+ "positional": false,
8491
9857
  "help": "Number of notifications"
8492
9858
  },
8493
9859
  {
@@ -8495,6 +9861,7 @@
8495
9861
  "type": "str",
8496
9862
  "default": "all",
8497
9863
  "required": false,
9864
+ "positional": false,
8498
9865
  "help": "Notification type",
8499
9866
  "choices": [
8500
9867
  "all",
@@ -8614,6 +9981,7 @@
8614
9981
  "type": "int",
8615
9982
  "default": 10,
8616
9983
  "required": false,
9984
+ "positional": false,
8617
9985
  "help": "Number of results"
8618
9986
  }
8619
9987
  ],
@@ -8760,6 +10128,7 @@
8760
10128
  "type": "int",
8761
10129
  "default": 10,
8762
10130
  "required": false,
10131
+ "positional": false,
8763
10132
  "help": "Number of videos"
8764
10133
  }
8765
10134
  ],
@@ -9110,6 +10479,39 @@
9110
10479
  "message"
9111
10480
  ]
9112
10481
  },
10482
+ {
10483
+ "site": "twitter",
10484
+ "name": "likes",
10485
+ "description": "Fetch liked tweets of a Twitter user",
10486
+ "strategy": "cookie",
10487
+ "browser": true,
10488
+ "args": [
10489
+ {
10490
+ "name": "username",
10491
+ "type": "string",
10492
+ "required": false,
10493
+ "positional": true,
10494
+ "help": "Twitter screen name (without @). Defaults to logged-in user."
10495
+ },
10496
+ {
10497
+ "name": "limit",
10498
+ "type": "int",
10499
+ "default": 20,
10500
+ "required": false,
10501
+ "help": ""
10502
+ }
10503
+ ],
10504
+ "type": "ts",
10505
+ "modulePath": "twitter/likes.js",
10506
+ "domain": "x.com",
10507
+ "columns": [
10508
+ "author",
10509
+ "name",
10510
+ "text",
10511
+ "likes",
10512
+ "url"
10513
+ ]
10514
+ },
9113
10515
  {
9114
10516
  "site": "twitter",
9115
10517
  "name": "notifications",
@@ -9302,6 +10704,7 @@
9302
10704
  "id",
9303
10705
  "author",
9304
10706
  "text",
10707
+ "created_at",
9305
10708
  "likes",
9306
10709
  "views",
9307
10710
  "url"
@@ -9497,13 +10900,14 @@
9497
10900
  "description": "V2EX 热门话题",
9498
10901
  "domain": "www.v2ex.com",
9499
10902
  "strategy": "public",
9500
- "browser": false,
10903
+ "browser": true,
9501
10904
  "args": [
9502
10905
  {
9503
10906
  "name": "limit",
9504
10907
  "type": "int",
9505
10908
  "default": 20,
9506
10909
  "required": false,
10910
+ "positional": false,
9507
10911
  "help": "Number of topics"
9508
10912
  }
9509
10913
  ],
@@ -9514,9 +10918,10 @@
9514
10918
  ],
9515
10919
  "pipeline": [
9516
10920
  {
9517
- "fetch": {
9518
- "url": "https://www.v2ex.com/api/topics/hot.json"
9519
- }
10921
+ "navigate": "https://www.v2ex.com/"
10922
+ },
10923
+ {
10924
+ "evaluate": "(async () => {\n const response = await fetch('/api/topics/hot.json', {\n credentials: 'include',\n headers: {\n accept: 'application/json, text/plain, */*',\n 'x-requested-with': 'XMLHttpRequest',\n },\n });\n if (!response.ok) {\n throw new Error(`V2EX hot API request failed: ${response.status}`);\n }\n return await response.json();\n})()\n"
9520
10925
  },
9521
10926
  {
9522
10927
  "map": {
@@ -9544,6 +10949,7 @@
9544
10949
  "type": "int",
9545
10950
  "default": 20,
9546
10951
  "required": false,
10952
+ "positional": false,
9547
10953
  "help": "Number of topics"
9548
10954
  }
9549
10955
  ],
@@ -9654,6 +11060,7 @@
9654
11060
  "type": "int",
9655
11061
  "default": 10,
9656
11062
  "required": false,
11063
+ "positional": false,
9657
11064
  "help": "Number of topics (API returns max 20)"
9658
11065
  }
9659
11066
  ],
@@ -9701,6 +11108,7 @@
9701
11108
  "type": "int",
9702
11109
  "default": 30,
9703
11110
  "required": false,
11111
+ "positional": false,
9704
11112
  "help": "Number of nodes"
9705
11113
  }
9706
11114
  ],
@@ -9782,6 +11190,7 @@
9782
11190
  "type": "int",
9783
11191
  "default": 20,
9784
11192
  "required": false,
11193
+ "positional": false,
9785
11194
  "help": "Number of replies"
9786
11195
  }
9787
11196
  ],
@@ -9875,6 +11284,7 @@
9875
11284
  "type": "int",
9876
11285
  "default": 10,
9877
11286
  "required": false,
11287
+ "positional": false,
9878
11288
  "help": "Number of topics (API returns max 20)"
9879
11289
  }
9880
11290
  ],
@@ -10512,6 +11922,39 @@
10512
11922
  "views"
10513
11923
  ]
10514
11924
  },
11925
+ {
11926
+ "site": "xiaohongshu",
11927
+ "name": "comments",
11928
+ "description": "获取小红书笔记评论(仅主评论,不含楼中楼)",
11929
+ "strategy": "cookie",
11930
+ "browser": true,
11931
+ "args": [
11932
+ {
11933
+ "name": "note-id",
11934
+ "type": "str",
11935
+ "required": true,
11936
+ "positional": true,
11937
+ "help": "Note ID or full /explore/<id> URL"
11938
+ },
11939
+ {
11940
+ "name": "limit",
11941
+ "type": "int",
11942
+ "default": 20,
11943
+ "required": false,
11944
+ "help": "Number of comments (max 50)"
11945
+ }
11946
+ ],
11947
+ "type": "ts",
11948
+ "modulePath": "xiaohongshu/comments.js",
11949
+ "domain": "www.xiaohongshu.com",
11950
+ "columns": [
11951
+ "rank",
11952
+ "author",
11953
+ "text",
11954
+ "likes",
11955
+ "time"
11956
+ ]
11957
+ },
10515
11958
  {
10516
11959
  "site": "xiaohongshu",
10517
11960
  "name": "creator-note-detail",
@@ -10689,6 +12132,7 @@
10689
12132
  "type": "int",
10690
12133
  "default": 20,
10691
12134
  "required": false,
12135
+ "positional": false,
10692
12136
  "help": "Number of items to return"
10693
12137
  }
10694
12138
  ],
@@ -10741,6 +12185,7 @@
10741
12185
  "type": "str",
10742
12186
  "default": "mentions",
10743
12187
  "required": false,
12188
+ "positional": false,
10744
12189
  "help": "Notification type: mentions, likes, or connections"
10745
12190
  },
10746
12191
  {
@@ -10748,6 +12193,7 @@
10748
12193
  "type": "int",
10749
12194
  "default": 20,
10750
12195
  "required": false,
12196
+ "positional": false,
10751
12197
  "help": "Number of notifications to return"
10752
12198
  }
10753
12199
  ],
@@ -10814,7 +12260,7 @@
10814
12260
  {
10815
12261
  "name": "images",
10816
12262
  "type": "str",
10817
- "required": false,
12263
+ "required": true,
10818
12264
  "help": "图片路径,逗号分隔,最多9张 (jpg/png/gif/webp)"
10819
12265
  },
10820
12266
  {
@@ -10869,6 +12315,7 @@
10869
12315
  "title",
10870
12316
  "author",
10871
12317
  "likes",
12318
+ "published_at",
10872
12319
  "url"
10873
12320
  ]
10874
12321
  },
@@ -11013,6 +12460,7 @@
11013
12460
  "type": "bool",
11014
12461
  "default": false,
11015
12462
  "required": false,
12463
+ "positional": false,
11016
12464
  "help": "仅返回最近一次未发布的财报日期"
11017
12465
  },
11018
12466
  {
@@ -11020,6 +12468,7 @@
11020
12468
  "type": "int",
11021
12469
  "default": 10,
11022
12470
  "required": false,
12471
+ "positional": false,
11023
12472
  "help": "返回数量,默认 10"
11024
12473
  }
11025
12474
  ],
@@ -11061,6 +12510,7 @@
11061
12510
  "type": "int",
11062
12511
  "default": 1,
11063
12512
  "required": false,
12513
+ "positional": false,
11064
12514
  "help": "页码,默认 1"
11065
12515
  },
11066
12516
  {
@@ -11068,6 +12518,7 @@
11068
12518
  "type": "int",
11069
12519
  "default": 20,
11070
12520
  "required": false,
12521
+ "positional": false,
11071
12522
  "help": "每页数量,默认 20"
11072
12523
  }
11073
12524
  ],
@@ -11163,6 +12614,7 @@
11163
12614
  "type": "int",
11164
12615
  "default": 20,
11165
12616
  "required": false,
12617
+ "positional": false,
11166
12618
  "help": "返回数量,默认 20,最大 50"
11167
12619
  },
11168
12620
  {
@@ -11170,6 +12622,7 @@
11170
12622
  "type": "str",
11171
12623
  "default": "10",
11172
12624
  "required": false,
12625
+ "positional": false,
11173
12626
  "help": "榜单类型 10=人气榜(默认) 12=关注榜"
11174
12627
  }
11175
12628
  ],
@@ -11217,6 +12670,7 @@
11217
12670
  "type": "int",
11218
12671
  "default": 20,
11219
12672
  "required": false,
12673
+ "positional": false,
11220
12674
  "help": "返回数量,默认 20,最大 50"
11221
12675
  }
11222
12676
  ],
@@ -11269,6 +12723,7 @@
11269
12723
  "type": "int",
11270
12724
  "default": 10,
11271
12725
  "required": false,
12726
+ "positional": false,
11272
12727
  "help": "返回数量,默认 10"
11273
12728
  }
11274
12729
  ],
@@ -11358,6 +12813,7 @@
11358
12813
  "type": "str",
11359
12814
  "default": "1",
11360
12815
  "required": false,
12816
+ "positional": false,
11361
12817
  "help": "分类:1=自选(默认) 2=持仓 3=关注"
11362
12818
  },
11363
12819
  {
@@ -11365,6 +12821,7 @@
11365
12821
  "type": "int",
11366
12822
  "default": 100,
11367
12823
  "required": false,
12824
+ "positional": false,
11368
12825
  "help": "默认 100"
11369
12826
  }
11370
12827
  ],
@@ -12188,6 +13645,7 @@
12188
13645
  "type": "int",
12189
13646
  "default": 20,
12190
13647
  "required": false,
13648
+ "positional": false,
12191
13649
  "help": "Number of items to return"
12192
13650
  }
12193
13651
  ],
@@ -12271,6 +13729,7 @@
12271
13729
  "type": "int",
12272
13730
  "default": 10,
12273
13731
  "required": false,
13732
+ "positional": false,
12274
13733
  "help": "Number of results"
12275
13734
  }
12276
13735
  ],