@jackwener/opencli 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) 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/discover.d.ts +4 -1
  8. package/dist/browser/discover.js +6 -2
  9. package/dist/browser/errors.d.ts +2 -2
  10. package/dist/browser/errors.js +4 -12
  11. package/dist/browser/mcp.d.ts +2 -1
  12. package/dist/build-manifest.d.ts +2 -0
  13. package/dist/build-manifest.js +39 -14
  14. package/dist/build-manifest.test.js +21 -0
  15. package/dist/capabilityRouting.d.ts +2 -0
  16. package/dist/capabilityRouting.js +2 -1
  17. package/dist/cli-manifest.json +1111 -112
  18. package/dist/cli.js +34 -3
  19. package/dist/clis/36kr/article.d.ts +1 -0
  20. package/dist/clis/36kr/article.js +62 -0
  21. package/dist/clis/36kr/hot.d.ts +3 -0
  22. package/dist/clis/36kr/hot.js +80 -0
  23. package/dist/clis/36kr/hot.test.d.ts +1 -0
  24. package/dist/clis/36kr/hot.test.js +15 -0
  25. package/dist/clis/36kr/news.d.ts +1 -0
  26. package/dist/clis/36kr/news.js +51 -0
  27. package/dist/clis/36kr/news.test.d.ts +1 -0
  28. package/dist/clis/36kr/news.test.js +85 -0
  29. package/dist/clis/36kr/search.d.ts +1 -0
  30. package/dist/clis/36kr/search.js +72 -0
  31. package/dist/clis/bilibili/comments.d.ts +5 -0
  32. package/dist/clis/bilibili/comments.js +40 -0
  33. package/dist/clis/bilibili/comments.test.d.ts +1 -0
  34. package/dist/clis/bilibili/comments.test.js +82 -0
  35. package/dist/clis/chatgpt/ask.js +29 -14
  36. package/dist/clis/chatgpt/ax.d.ts +6 -0
  37. package/dist/clis/chatgpt/ax.js +172 -1
  38. package/dist/clis/chatgpt/model.d.ts +1 -0
  39. package/dist/clis/chatgpt/model.js +24 -0
  40. package/dist/clis/chatgpt/send.js +12 -3
  41. package/dist/clis/douban/download.d.ts +1 -0
  42. package/dist/clis/douban/download.js +67 -0
  43. package/dist/clis/douban/download.test.d.ts +1 -0
  44. package/dist/clis/douban/download.test.js +170 -0
  45. package/dist/clis/douban/photos.d.ts +1 -0
  46. package/dist/clis/douban/photos.js +34 -0
  47. package/dist/clis/douban/utils.d.ts +25 -0
  48. package/dist/clis/douban/utils.js +190 -1
  49. package/dist/clis/douban/utils.test.d.ts +1 -0
  50. package/dist/clis/douban/utils.test.js +64 -0
  51. package/dist/clis/imdb/person.d.ts +1 -0
  52. package/dist/clis/imdb/person.js +203 -0
  53. package/dist/clis/imdb/reviews.d.ts +1 -0
  54. package/dist/clis/imdb/reviews.js +88 -0
  55. package/dist/clis/imdb/search.d.ts +1 -0
  56. package/dist/clis/imdb/search.js +161 -0
  57. package/dist/clis/imdb/title.d.ts +1 -0
  58. package/dist/clis/imdb/title.js +93 -0
  59. package/dist/clis/imdb/top.d.ts +1 -0
  60. package/dist/clis/imdb/top.js +53 -0
  61. package/dist/clis/imdb/trending.d.ts +1 -0
  62. package/dist/clis/imdb/trending.js +52 -0
  63. package/dist/clis/imdb/utils.d.ts +46 -0
  64. package/dist/clis/imdb/utils.js +285 -0
  65. package/dist/clis/imdb/utils.test.d.ts +1 -0
  66. package/dist/clis/imdb/utils.test.js +88 -0
  67. package/dist/clis/jd/item.d.ts +4 -0
  68. package/dist/clis/jd/item.js +16 -15
  69. package/dist/clis/jd/item.test.js +16 -1
  70. package/dist/clis/linux-do/categories.yaml +38 -9
  71. package/dist/clis/linux-do/category.d.ts +1 -0
  72. package/dist/clis/linux-do/category.js +36 -0
  73. package/dist/clis/linux-do/feed.d.ts +45 -0
  74. package/dist/clis/linux-do/feed.js +397 -0
  75. package/dist/clis/linux-do/feed.test.d.ts +1 -0
  76. package/dist/clis/linux-do/feed.test.js +118 -0
  77. package/dist/clis/linux-do/hot.d.ts +1 -0
  78. package/dist/clis/linux-do/hot.js +25 -0
  79. package/dist/clis/linux-do/latest.d.ts +1 -0
  80. package/dist/clis/linux-do/latest.js +18 -0
  81. package/dist/clis/linux-do/tags.yaml +41 -0
  82. package/dist/clis/linux-do/topic.yaml +41 -3
  83. package/dist/clis/linux-do/user-posts.yaml +67 -0
  84. package/dist/clis/linux-do/user-topics.yaml +54 -0
  85. package/dist/clis/paperreview/commands.test.d.ts +3 -0
  86. package/dist/clis/paperreview/commands.test.js +243 -0
  87. package/dist/clis/paperreview/feedback.d.ts +1 -0
  88. package/dist/clis/paperreview/feedback.js +52 -0
  89. package/dist/clis/paperreview/review.d.ts +1 -0
  90. package/dist/clis/paperreview/review.js +37 -0
  91. package/dist/clis/paperreview/submit.d.ts +1 -0
  92. package/dist/clis/paperreview/submit.js +85 -0
  93. package/dist/clis/paperreview/utils.d.ts +46 -0
  94. package/dist/clis/paperreview/utils.js +197 -0
  95. package/dist/clis/paperreview/utils.test.d.ts +1 -0
  96. package/dist/clis/paperreview/utils.test.js +49 -0
  97. package/dist/clis/producthunt/browse.d.ts +1 -0
  98. package/dist/clis/producthunt/browse.js +99 -0
  99. package/dist/clis/producthunt/hot.d.ts +1 -0
  100. package/dist/clis/producthunt/hot.js +110 -0
  101. package/dist/clis/producthunt/posts.d.ts +1 -0
  102. package/dist/clis/producthunt/posts.js +28 -0
  103. package/dist/clis/producthunt/today.d.ts +1 -0
  104. package/dist/clis/producthunt/today.js +35 -0
  105. package/dist/clis/producthunt/utils.d.ts +29 -0
  106. package/dist/clis/producthunt/utils.js +99 -0
  107. package/dist/clis/producthunt/utils.test.d.ts +1 -0
  108. package/dist/clis/producthunt/utils.test.js +64 -0
  109. package/dist/clis/twitter/article.js +4 -28
  110. package/dist/clis/twitter/likes.d.ts +24 -0
  111. package/dist/clis/twitter/likes.js +217 -0
  112. package/dist/clis/twitter/likes.test.d.ts +1 -0
  113. package/dist/clis/twitter/likes.test.js +85 -0
  114. package/dist/clis/twitter/profile.js +4 -28
  115. package/dist/clis/twitter/search.js +2 -1
  116. package/dist/clis/twitter/search.test.js +2 -0
  117. package/dist/clis/twitter/shared.d.ts +6 -0
  118. package/dist/clis/twitter/shared.js +35 -0
  119. package/dist/clis/twitter/timeline.js +2 -13
  120. package/dist/clis/weixin/download.d.ts +17 -0
  121. package/dist/clis/weixin/download.js +88 -20
  122. package/dist/clis/weread/book.js +2 -2
  123. package/dist/clis/weread/commands.test.d.ts +3 -0
  124. package/dist/clis/weread/commands.test.js +43 -0
  125. package/dist/clis/weread/highlights.js +2 -2
  126. package/dist/clis/weread/notebooks.js +2 -2
  127. package/dist/clis/weread/notes.js +3 -3
  128. package/dist/clis/weread/shelf.js +2 -2
  129. package/dist/clis/weread/utils.d.ts +4 -4
  130. package/dist/clis/weread/utils.js +32 -14
  131. package/dist/clis/weread/utils.test.js +1 -28
  132. package/dist/clis/xiaohongshu/comments.d.ts +5 -0
  133. package/dist/clis/xiaohongshu/comments.js +74 -0
  134. package/dist/clis/xiaohongshu/comments.test.d.ts +1 -0
  135. package/dist/clis/xiaohongshu/comments.test.js +79 -0
  136. package/dist/clis/xiaohongshu/publish.js +114 -18
  137. package/dist/clis/xiaohongshu/publish.test.d.ts +1 -0
  138. package/dist/clis/xiaohongshu/publish.test.js +119 -0
  139. package/dist/commanderAdapter.d.ts +1 -0
  140. package/dist/commanderAdapter.js +176 -29
  141. package/dist/commanderAdapter.test.d.ts +1 -0
  142. package/dist/commanderAdapter.test.js +62 -0
  143. package/dist/daemon.js +17 -1
  144. package/dist/discovery.js +8 -14
  145. package/dist/doctor.d.ts +1 -0
  146. package/dist/doctor.js +9 -2
  147. package/dist/download/index.js +63 -51
  148. package/dist/download/index.test.js +17 -4
  149. package/dist/errors.d.ts +3 -1
  150. package/dist/errors.js +15 -32
  151. package/dist/execution.d.ts +1 -3
  152. package/dist/execution.js +21 -1
  153. package/dist/hooks.js +2 -0
  154. package/dist/main.js +5 -0
  155. package/dist/output.js +5 -1
  156. package/dist/pipeline/executor.js +3 -4
  157. package/dist/plugin-manifest.d.ts +70 -0
  158. package/dist/plugin-manifest.js +160 -0
  159. package/dist/plugin-manifest.test.d.ts +4 -0
  160. package/dist/plugin-manifest.test.js +179 -0
  161. package/dist/plugin.d.ts +38 -5
  162. package/dist/plugin.js +267 -33
  163. package/dist/plugin.test.js +220 -3
  164. package/dist/registry.d.ts +4 -0
  165. package/dist/registry.js +2 -0
  166. package/dist/runtime-detect.d.ts +21 -0
  167. package/dist/runtime-detect.js +32 -0
  168. package/dist/runtime-detect.test.d.ts +1 -0
  169. package/dist/runtime-detect.test.js +27 -0
  170. package/dist/runtime.js +1 -1
  171. package/dist/serialization.d.ts +2 -0
  172. package/dist/serialization.js +6 -0
  173. package/dist/types.d.ts +1 -0
  174. package/dist/update-check.d.ts +22 -0
  175. package/dist/update-check.js +112 -0
  176. package/dist/weixin-download.test.d.ts +1 -0
  177. package/dist/weixin-download.test.js +30 -0
  178. package/dist/weread-private-api-regression.test.d.ts +1 -0
  179. package/dist/weread-private-api-regression.test.js +122 -0
  180. package/dist/yaml-schema.d.ts +3 -0
  181. package/dist/yaml-schema.js +18 -1
  182. package/docs/.vitepress/config.mts +4 -0
  183. package/docs/adapters/browser/36kr.md +47 -0
  184. package/docs/adapters/browser/douban.md +14 -0
  185. package/docs/adapters/browser/imdb.md +47 -0
  186. package/docs/adapters/browser/jd.md +2 -2
  187. package/docs/adapters/browser/linux-do.md +181 -20
  188. package/docs/adapters/browser/paperreview.md +43 -0
  189. package/docs/adapters/browser/producthunt.md +49 -0
  190. package/docs/adapters/desktop/chatgpt.md +5 -0
  191. package/docs/adapters/index.md +6 -2
  192. package/docs/advanced/download.md +4 -0
  193. package/docs/advanced/rate-limiter-plugin.md +99 -0
  194. package/docs/guide/electron-app-cli.md +200 -0
  195. package/docs/guide/getting-started.md +1 -0
  196. package/docs/guide/plugins.md +87 -0
  197. package/docs/zh/guide/electron-app-cli.md +188 -0
  198. package/docs/zh/guide/getting-started.md +1 -0
  199. package/docs/zh/guide/plugins.md +65 -0
  200. package/extension/package.json +1 -0
  201. package/extension/scripts/package-release.mjs +179 -0
  202. package/extension/src/background.ts +2 -0
  203. package/package.json +4 -1
  204. package/scripts/postinstall.js +10 -0
  205. package/src/browser/cdp.ts +2 -1
  206. package/src/browser/discover.ts +8 -3
  207. package/src/browser/errors.ts +13 -14
  208. package/src/browser/mcp.ts +2 -1
  209. package/src/build-manifest.test.ts +23 -0
  210. package/src/build-manifest.ts +40 -15
  211. package/src/capabilityRouting.ts +2 -1
  212. package/src/cli.ts +35 -3
  213. package/src/clis/36kr/article.ts +69 -0
  214. package/src/clis/36kr/hot.test.ts +19 -0
  215. package/src/clis/36kr/hot.ts +100 -0
  216. package/src/clis/36kr/news.test.ts +90 -0
  217. package/src/clis/36kr/news.ts +54 -0
  218. package/src/clis/36kr/search.ts +78 -0
  219. package/src/clis/bilibili/comments.test.ts +102 -0
  220. package/src/clis/bilibili/comments.ts +44 -0
  221. package/src/clis/chatgpt/ask.ts +28 -14
  222. package/src/clis/chatgpt/ax.ts +180 -1
  223. package/src/clis/chatgpt/model.ts +27 -0
  224. package/src/clis/chatgpt/send.ts +16 -6
  225. package/src/clis/douban/download.test.ts +196 -0
  226. package/src/clis/douban/download.ts +78 -0
  227. package/src/clis/douban/photos.ts +36 -0
  228. package/src/clis/douban/utils.test.ts +97 -0
  229. package/src/clis/douban/utils.ts +232 -1
  230. package/src/clis/imdb/person.ts +232 -0
  231. package/src/clis/imdb/reviews.ts +111 -0
  232. package/src/clis/imdb/search.ts +179 -0
  233. package/src/clis/imdb/title.ts +121 -0
  234. package/src/clis/imdb/top.ts +67 -0
  235. package/src/clis/imdb/trending.ts +66 -0
  236. package/src/clis/imdb/utils.test.ts +117 -0
  237. package/src/clis/imdb/utils.ts +305 -0
  238. package/src/clis/jd/item.test.ts +18 -1
  239. package/src/clis/jd/item.ts +18 -15
  240. package/src/clis/linux-do/categories.yaml +38 -9
  241. package/src/clis/linux-do/category.ts +37 -0
  242. package/src/clis/linux-do/feed.test.ts +132 -0
  243. package/src/clis/linux-do/feed.ts +501 -0
  244. package/src/clis/linux-do/hot.ts +26 -0
  245. package/src/clis/linux-do/latest.ts +19 -0
  246. package/src/clis/linux-do/tags.yaml +41 -0
  247. package/src/clis/linux-do/topic.yaml +41 -3
  248. package/src/clis/linux-do/user-posts.yaml +67 -0
  249. package/src/clis/linux-do/user-topics.yaml +54 -0
  250. package/src/clis/paperreview/commands.test.ts +283 -0
  251. package/src/clis/paperreview/feedback.ts +64 -0
  252. package/src/clis/paperreview/review.ts +47 -0
  253. package/src/clis/paperreview/submit.ts +119 -0
  254. package/src/clis/paperreview/utils.test.ts +68 -0
  255. package/src/clis/paperreview/utils.ts +276 -0
  256. package/src/clis/producthunt/browse.ts +109 -0
  257. package/src/clis/producthunt/hot.ts +127 -0
  258. package/src/clis/producthunt/posts.ts +29 -0
  259. package/src/clis/producthunt/today.ts +37 -0
  260. package/src/clis/producthunt/utils.test.ts +72 -0
  261. package/src/clis/producthunt/utils.ts +122 -0
  262. package/src/clis/twitter/article.ts +5 -28
  263. package/src/clis/twitter/likes.test.ts +91 -0
  264. package/src/clis/twitter/likes.ts +256 -0
  265. package/src/clis/twitter/profile.ts +5 -28
  266. package/src/clis/twitter/search.test.ts +2 -0
  267. package/src/clis/twitter/search.ts +3 -1
  268. package/src/clis/twitter/shared.ts +45 -0
  269. package/src/clis/twitter/timeline.ts +2 -13
  270. package/src/clis/weixin/download.ts +114 -20
  271. package/src/clis/weread/book.ts +2 -2
  272. package/src/clis/weread/commands.test.ts +57 -0
  273. package/src/clis/weread/highlights.ts +2 -2
  274. package/src/clis/weread/notebooks.ts +2 -2
  275. package/src/clis/weread/notes.ts +3 -3
  276. package/src/clis/weread/shelf.ts +2 -2
  277. package/src/clis/weread/utils.test.ts +1 -32
  278. package/src/clis/weread/utils.ts +41 -16
  279. package/src/clis/xiaohongshu/comments.test.ts +96 -0
  280. package/src/clis/xiaohongshu/comments.ts +81 -0
  281. package/src/clis/xiaohongshu/publish.test.ts +137 -0
  282. package/src/clis/xiaohongshu/publish.ts +129 -18
  283. package/src/commanderAdapter.test.ts +78 -0
  284. package/src/commanderAdapter.ts +188 -24
  285. package/src/daemon.ts +19 -1
  286. package/src/discovery.ts +8 -15
  287. package/src/doctor.ts +13 -2
  288. package/src/download/index.test.ts +14 -4
  289. package/src/download/index.ts +67 -55
  290. package/src/errors.ts +25 -66
  291. package/src/execution.ts +28 -3
  292. package/src/hooks.ts +1 -0
  293. package/src/main.ts +6 -0
  294. package/src/output.ts +3 -1
  295. package/src/pipeline/executor.ts +4 -6
  296. package/src/plugin-manifest.test.ts +223 -0
  297. package/src/plugin-manifest.ts +206 -0
  298. package/src/plugin.test.ts +246 -2
  299. package/src/plugin.ts +338 -36
  300. package/src/registry.ts +6 -1
  301. package/src/runtime-detect.test.ts +30 -0
  302. package/src/runtime-detect.ts +36 -0
  303. package/src/runtime.ts +1 -1
  304. package/src/serialization.ts +4 -0
  305. package/src/types.ts +1 -0
  306. package/src/update-check.ts +114 -0
  307. package/src/weixin-download.test.ts +64 -0
  308. package/src/weread-private-api-regression.test.ts +150 -0
  309. package/src/yaml-schema.ts +20 -0
  310. package/tests/e2e/browser-auth.test.ts +13 -9
  311. package/tests/e2e/browser-public-extended.test.ts +1 -1
  312. package/tests/e2e/browser-public.test.ts +62 -4
  313. package/tests/e2e/helpers.ts +2 -1
  314. package/tests/e2e/public-commands.test.ts +37 -3
  315. package/tests/smoke/api-health.test.ts +1 -1
  316. package/vitest.config.ts +10 -0
  317. package/dist/clis/linux-do/category.yaml +0 -51
  318. package/dist/clis/linux-do/hot.yaml +0 -50
  319. package/dist/clis/linux-do/latest.yaml +0 -40
  320. package/src/clis/linux-do/category.yaml +0 -51
  321. package/src/clis/linux-do/hot.yaml +0 -50
  322. 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
  ],
@@ -1804,6 +1951,12 @@
1804
1951
  "positional": true,
1805
1952
  "help": "Prompt to send"
1806
1953
  },
1954
+ {
1955
+ "name": "model",
1956
+ "type": "str",
1957
+ "required": false,
1958
+ "help": "Model/mode to use: auto, instant, thinking, 5.2-instant, 5.2-thinking"
1959
+ },
1807
1960
  {
1808
1961
  "name": "timeout",
1809
1962
  "type": "str",
@@ -1820,6 +1973,29 @@
1820
1973
  "Text"
1821
1974
  ]
1822
1975
  },
1976
+ {
1977
+ "site": "chatgpt",
1978
+ "name": "model",
1979
+ "description": "Switch ChatGPT Desktop model/mode (auto, instant, thinking, 5.2-instant, 5.2-thinking)",
1980
+ "strategy": "public",
1981
+ "browser": false,
1982
+ "args": [
1983
+ {
1984
+ "name": "model",
1985
+ "type": "str",
1986
+ "required": true,
1987
+ "positional": true,
1988
+ "help": "Model to switch to"
1989
+ }
1990
+ ],
1991
+ "type": "ts",
1992
+ "modulePath": "chatgpt/model.js",
1993
+ "domain": "localhost",
1994
+ "columns": [
1995
+ "Status",
1996
+ "Model"
1997
+ ]
1998
+ },
1823
1999
  {
1824
2000
  "site": "chatgpt",
1825
2001
  "name": "new",
@@ -1862,6 +2038,12 @@
1862
2038
  "required": true,
1863
2039
  "positional": true,
1864
2040
  "help": "Message to send"
2041
+ },
2042
+ {
2043
+ "name": "model",
2044
+ "type": "str",
2045
+ "required": false,
2046
+ "help": "Model/mode to use: auto, instant, thinking, 5.2-instant, 5.2-thinking"
1865
2047
  }
1866
2048
  ],
1867
2049
  "type": "ts",
@@ -2461,6 +2643,7 @@
2461
2643
  "type": "int",
2462
2644
  "default": 20,
2463
2645
  "required": false,
2646
+ "positional": false,
2464
2647
  "help": "Number of articles"
2465
2648
  }
2466
2649
  ],
@@ -2508,6 +2691,7 @@
2508
2691
  "type": "int",
2509
2692
  "default": 20,
2510
2693
  "required": false,
2694
+ "positional": false,
2511
2695
  "help": "Number of articles"
2512
2696
  }
2513
2697
  ],
@@ -2562,6 +2746,7 @@
2562
2746
  "type": "int",
2563
2747
  "default": 20,
2564
2748
  "required": false,
2749
+ "positional": false,
2565
2750
  "help": "Number of articles"
2566
2751
  }
2567
2752
  ],
@@ -2874,6 +3059,58 @@
2874
3059
  "url"
2875
3060
  ]
2876
3061
  },
3062
+ {
3063
+ "site": "douban",
3064
+ "name": "download",
3065
+ "description": "下载电影海报/剧照图片",
3066
+ "strategy": "cookie",
3067
+ "browser": true,
3068
+ "args": [
3069
+ {
3070
+ "name": "id",
3071
+ "type": "str",
3072
+ "required": true,
3073
+ "positional": true,
3074
+ "help": "电影 subject ID"
3075
+ },
3076
+ {
3077
+ "name": "type",
3078
+ "type": "str",
3079
+ "default": "Rb",
3080
+ "required": false,
3081
+ "help": "豆瓣 photos 的 type 参数,默认 Rb(海报)"
3082
+ },
3083
+ {
3084
+ "name": "limit",
3085
+ "type": "int",
3086
+ "default": 120,
3087
+ "required": false,
3088
+ "help": "最多下载多少张图片"
3089
+ },
3090
+ {
3091
+ "name": "photo-id",
3092
+ "type": "str",
3093
+ "required": false,
3094
+ "help": "只下载指定 photo_id 的图片"
3095
+ },
3096
+ {
3097
+ "name": "output",
3098
+ "type": "str",
3099
+ "default": "./douban-downloads",
3100
+ "required": false,
3101
+ "help": "输出目录"
3102
+ }
3103
+ ],
3104
+ "type": "ts",
3105
+ "modulePath": "douban/download.js",
3106
+ "domain": "movie.douban.com",
3107
+ "columns": [
3108
+ "index",
3109
+ "title",
3110
+ "status",
3111
+ "size"
3112
+ ]
3113
+ },
2877
3114
  {
2878
3115
  "site": "douban",
2879
3116
  "name": "marks",
@@ -2950,6 +3187,45 @@
2950
3187
  "url"
2951
3188
  ]
2952
3189
  },
3190
+ {
3191
+ "site": "douban",
3192
+ "name": "photos",
3193
+ "description": "获取电影海报/剧照图片列表",
3194
+ "strategy": "cookie",
3195
+ "browser": true,
3196
+ "args": [
3197
+ {
3198
+ "name": "id",
3199
+ "type": "str",
3200
+ "required": true,
3201
+ "positional": true,
3202
+ "help": "电影 subject ID"
3203
+ },
3204
+ {
3205
+ "name": "type",
3206
+ "type": "str",
3207
+ "default": "Rb",
3208
+ "required": false,
3209
+ "help": "豆瓣 photos 的 type 参数,默认 Rb(海报)"
3210
+ },
3211
+ {
3212
+ "name": "limit",
3213
+ "type": "int",
3214
+ "default": 120,
3215
+ "required": false,
3216
+ "help": "最多返回多少张图片"
3217
+ }
3218
+ ],
3219
+ "type": "ts",
3220
+ "modulePath": "douban/photos.js",
3221
+ "domain": "movie.douban.com",
3222
+ "columns": [
3223
+ "index",
3224
+ "title",
3225
+ "image_url",
3226
+ "detail_url"
3227
+ ]
3228
+ },
2953
3229
  {
2954
3230
  "site": "douban",
2955
3231
  "name": "reviews",
@@ -3087,6 +3363,7 @@
3087
3363
  "type": "int",
3088
3364
  "default": 250,
3089
3365
  "required": false,
3366
+ "positional": false,
3090
3367
  "help": "返回结果数量"
3091
3368
  }
3092
3369
  ],
@@ -3859,6 +4136,7 @@
3859
4136
  "type": "int",
3860
4137
  "default": 15,
3861
4138
  "required": false,
4139
+ "positional": false,
3862
4140
  "help": "Number of categories"
3863
4141
  }
3864
4142
  ],
@@ -3892,6 +4170,7 @@
3892
4170
  "type": "int",
3893
4171
  "default": 10,
3894
4172
  "required": false,
4173
+ "positional": false,
3895
4174
  "help": "Number of posts"
3896
4175
  }
3897
4176
  ],
@@ -3929,6 +4208,7 @@
3929
4208
  "type": "int",
3930
4209
  "default": 10,
3931
4210
  "required": false,
4211
+ "positional": false,
3932
4212
  "help": "Number of friend suggestions"
3933
4213
  }
3934
4214
  ],
@@ -3963,6 +4243,7 @@
3963
4243
  "type": "int",
3964
4244
  "default": 20,
3965
4245
  "required": false,
4246
+ "positional": false,
3966
4247
  "help": "Number of groups"
3967
4248
  }
3968
4249
  ],
@@ -4031,6 +4312,7 @@
4031
4312
  "type": "int",
4032
4313
  "default": 10,
4033
4314
  "required": false,
4315
+ "positional": false,
4034
4316
  "help": "Number of memories"
4035
4317
  }
4036
4318
  ],
@@ -4066,6 +4348,7 @@
4066
4348
  "type": "int",
4067
4349
  "default": 15,
4068
4350
  "required": false,
4351
+ "positional": false,
4069
4352
  "help": "Number of notifications"
4070
4353
  }
4071
4354
  ],
@@ -4143,6 +4426,7 @@
4143
4426
  "type": "int",
4144
4427
  "default": 10,
4145
4428
  "required": false,
4429
+ "positional": false,
4146
4430
  "help": "Number of results"
4147
4431
  }
4148
4432
  ],
@@ -4360,6 +4644,7 @@
4360
4644
  "type": "int",
4361
4645
  "default": 20,
4362
4646
  "required": false,
4647
+ "positional": false,
4363
4648
  "help": "Number of stories"
4364
4649
  }
4365
4650
  ],
@@ -4421,6 +4706,7 @@
4421
4706
  "type": "int",
4422
4707
  "default": 20,
4423
4708
  "required": false,
4709
+ "positional": false,
4424
4710
  "help": "Number of stories"
4425
4711
  }
4426
4712
  ],
@@ -4482,6 +4768,7 @@
4482
4768
  "type": "int",
4483
4769
  "default": 20,
4484
4770
  "required": false,
4771
+ "positional": false,
4485
4772
  "help": "Number of job postings"
4486
4773
  }
4487
4774
  ],
@@ -4540,6 +4827,7 @@
4540
4827
  "type": "int",
4541
4828
  "default": 20,
4542
4829
  "required": false,
4830
+ "positional": false,
4543
4831
  "help": "Number of stories"
4544
4832
  }
4545
4833
  ],
@@ -4608,6 +4896,7 @@
4608
4896
  "type": "int",
4609
4897
  "default": 20,
4610
4898
  "required": false,
4899
+ "positional": false,
4611
4900
  "help": "Number of results"
4612
4901
  },
4613
4902
  {
@@ -4615,6 +4904,7 @@
4615
4904
  "type": "str",
4616
4905
  "default": "relevance",
4617
4906
  "required": false,
4907
+ "positional": false,
4618
4908
  "help": "Sort by relevance or date",
4619
4909
  "choices": [
4620
4910
  "relevance",
@@ -4673,6 +4963,7 @@
4673
4963
  "type": "int",
4674
4964
  "default": 20,
4675
4965
  "required": false,
4966
+ "positional": false,
4676
4967
  "help": "Number of stories"
4677
4968
  }
4678
4969
  ],
@@ -4734,6 +5025,7 @@
4734
5025
  "type": "int",
4735
5026
  "default": 20,
4736
5027
  "required": false,
5028
+ "positional": false,
4737
5029
  "help": "Number of stories"
4738
5030
  }
4739
5031
  ],
@@ -4866,44 +5158,219 @@
4866
5158
  "domain": "huggingface.co"
4867
5159
  },
4868
5160
  {
4869
- "site": "instagram",
4870
- "name": "comment",
4871
- "description": "Comment on an Instagram post",
4872
- "domain": "www.instagram.com",
4873
- "strategy": "cookie",
5161
+ "site": "imdb",
5162
+ "name": "person",
5163
+ "description": "Get actor or director info",
5164
+ "strategy": "public",
4874
5165
  "browser": true,
4875
5166
  "args": [
4876
5167
  {
4877
- "name": "username",
4878
- "type": "str",
4879
- "required": true,
4880
- "positional": true,
4881
- "help": "Username of the post author"
4882
- },
4883
- {
4884
- "name": "text",
5168
+ "name": "id",
4885
5169
  "type": "str",
4886
5170
  "required": true,
4887
5171
  "positional": true,
4888
- "help": "Comment text"
5172
+ "help": "IMDb person ID (nm0634240) or URL"
4889
5173
  },
4890
5174
  {
4891
- "name": "index",
5175
+ "name": "limit",
4892
5176
  "type": "int",
4893
- "default": 1,
5177
+ "default": 10,
4894
5178
  "required": false,
4895
- "help": "Post index (1 = most recent)"
5179
+ "help": "Max filmography entries"
4896
5180
  }
4897
5181
  ],
5182
+ "type": "ts",
5183
+ "modulePath": "imdb/person.js",
5184
+ "domain": "www.imdb.com",
4898
5185
  "columns": [
4899
- "status",
4900
- "user",
4901
- "text"
4902
- ],
4903
- "pipeline": [
4904
- {
4905
- "navigate": "https://www.instagram.com"
4906
- },
5186
+ "field",
5187
+ "value"
5188
+ ]
5189
+ },
5190
+ {
5191
+ "site": "imdb",
5192
+ "name": "reviews",
5193
+ "description": "Get user reviews for a movie or TV show",
5194
+ "strategy": "public",
5195
+ "browser": true,
5196
+ "args": [
5197
+ {
5198
+ "name": "id",
5199
+ "type": "str",
5200
+ "required": true,
5201
+ "positional": true,
5202
+ "help": "IMDb title ID (tt1375666) or URL"
5203
+ },
5204
+ {
5205
+ "name": "limit",
5206
+ "type": "int",
5207
+ "default": 10,
5208
+ "required": false,
5209
+ "help": "Number of reviews"
5210
+ }
5211
+ ],
5212
+ "type": "ts",
5213
+ "modulePath": "imdb/reviews.js",
5214
+ "domain": "www.imdb.com",
5215
+ "columns": [
5216
+ "rank",
5217
+ "title",
5218
+ "rating",
5219
+ "author",
5220
+ "date",
5221
+ "text"
5222
+ ]
5223
+ },
5224
+ {
5225
+ "site": "imdb",
5226
+ "name": "search",
5227
+ "description": "Search IMDb for movies, TV shows, and people",
5228
+ "strategy": "public",
5229
+ "browser": true,
5230
+ "args": [
5231
+ {
5232
+ "name": "query",
5233
+ "type": "str",
5234
+ "required": true,
5235
+ "positional": true,
5236
+ "help": "Search query"
5237
+ },
5238
+ {
5239
+ "name": "limit",
5240
+ "type": "int",
5241
+ "default": 20,
5242
+ "required": false,
5243
+ "help": "Number of results"
5244
+ }
5245
+ ],
5246
+ "type": "ts",
5247
+ "modulePath": "imdb/search.js",
5248
+ "domain": "www.imdb.com",
5249
+ "columns": [
5250
+ "rank",
5251
+ "id",
5252
+ "title",
5253
+ "year",
5254
+ "type",
5255
+ "url"
5256
+ ]
5257
+ },
5258
+ {
5259
+ "site": "imdb",
5260
+ "name": "title",
5261
+ "description": "Get movie or TV show details",
5262
+ "strategy": "public",
5263
+ "browser": true,
5264
+ "args": [
5265
+ {
5266
+ "name": "id",
5267
+ "type": "str",
5268
+ "required": true,
5269
+ "positional": true,
5270
+ "help": "IMDb title ID (tt1375666) or URL"
5271
+ }
5272
+ ],
5273
+ "type": "ts",
5274
+ "modulePath": "imdb/title.js",
5275
+ "domain": "www.imdb.com",
5276
+ "columns": [
5277
+ "field",
5278
+ "value"
5279
+ ]
5280
+ },
5281
+ {
5282
+ "site": "imdb",
5283
+ "name": "top",
5284
+ "description": "IMDb Top 250 Movies",
5285
+ "strategy": "public",
5286
+ "browser": true,
5287
+ "args": [
5288
+ {
5289
+ "name": "limit",
5290
+ "type": "int",
5291
+ "default": 20,
5292
+ "required": false,
5293
+ "help": "Number of results"
5294
+ }
5295
+ ],
5296
+ "type": "ts",
5297
+ "modulePath": "imdb/top.js",
5298
+ "domain": "www.imdb.com",
5299
+ "columns": [
5300
+ "rank",
5301
+ "title",
5302
+ "rating",
5303
+ "votes",
5304
+ "genre",
5305
+ "url"
5306
+ ]
5307
+ },
5308
+ {
5309
+ "site": "imdb",
5310
+ "name": "trending",
5311
+ "description": "IMDb Most Popular Movies",
5312
+ "strategy": "public",
5313
+ "browser": true,
5314
+ "args": [
5315
+ {
5316
+ "name": "limit",
5317
+ "type": "int",
5318
+ "default": 20,
5319
+ "required": false,
5320
+ "help": "Number of results"
5321
+ }
5322
+ ],
5323
+ "type": "ts",
5324
+ "modulePath": "imdb/trending.js",
5325
+ "domain": "www.imdb.com",
5326
+ "columns": [
5327
+ "rank",
5328
+ "title",
5329
+ "rating",
5330
+ "genre",
5331
+ "url"
5332
+ ]
5333
+ },
5334
+ {
5335
+ "site": "instagram",
5336
+ "name": "comment",
5337
+ "description": "Comment on an Instagram post",
5338
+ "domain": "www.instagram.com",
5339
+ "strategy": "cookie",
5340
+ "browser": true,
5341
+ "args": [
5342
+ {
5343
+ "name": "username",
5344
+ "type": "str",
5345
+ "required": true,
5346
+ "positional": true,
5347
+ "help": "Username of the post author"
5348
+ },
5349
+ {
5350
+ "name": "text",
5351
+ "type": "str",
5352
+ "required": true,
5353
+ "positional": true,
5354
+ "help": "Comment text"
5355
+ },
5356
+ {
5357
+ "name": "index",
5358
+ "type": "int",
5359
+ "default": 1,
5360
+ "required": false,
5361
+ "positional": false,
5362
+ "help": "Post index (1 = most recent)"
5363
+ }
5364
+ ],
5365
+ "columns": [
5366
+ "status",
5367
+ "user",
5368
+ "text"
5369
+ ],
5370
+ "pipeline": [
5371
+ {
5372
+ "navigate": "https://www.instagram.com"
5373
+ },
4907
5374
  {
4908
5375
  "evaluate": "(async () => {\n const username = ${{ args.username | json }};\n const commentText = ${{ args.text | json }};\n const idx = ${{ args.index }} - 1;\n const headers = { 'X-IG-App-ID': '936619743392459' };\n const opts = { credentials: 'include', headers };\n\n const r1 = await fetch('https://www.instagram.com/api/v1/users/web_profile_info/?username=' + encodeURIComponent(username), opts);\n if (!r1.ok) throw new Error('User not found: ' + username);\n const userId = (await r1.json())?.data?.user?.id;\n\n const r2 = await fetch('https://www.instagram.com/api/v1/feed/user/' + userId + '/?count=' + (idx + 1), opts);\n const posts = (await r2.json())?.items || [];\n if (idx >= posts.length) throw new Error('Post index ' + (idx + 1) + ' not found');\n const pk = posts[idx].pk;\n\n const csrf = document.cookie.match(/csrftoken=([^;]+)/)?.[1] || '';\n const r3 = await fetch('https://www.instagram.com/api/v1/web/comments/' + pk + '/add/', {\n method: 'POST', credentials: 'include',\n headers: { ...headers, 'X-CSRFToken': csrf, 'Content-Type': 'application/x-www-form-urlencoded' },\n body: 'comment_text=' + encodeURIComponent(commentText),\n });\n if (!r3.ok) throw new Error('Failed to comment: HTTP ' + r3.status);\n return [{ status: 'Commented', user: username, text: commentText }];\n})()\n"
4909
5376
  }
@@ -4923,6 +5390,7 @@
4923
5390
  "type": "int",
4924
5391
  "default": 20,
4925
5392
  "required": false,
5393
+ "positional": false,
4926
5394
  "help": "Number of posts"
4927
5395
  }
4928
5396
  ],
@@ -4994,6 +5462,7 @@
4994
5462
  "type": "int",
4995
5463
  "default": 20,
4996
5464
  "required": false,
5465
+ "positional": false,
4997
5466
  "help": "Number of followers"
4998
5467
  }
4999
5468
  ],
@@ -5034,6 +5503,7 @@
5034
5503
  "type": "int",
5035
5504
  "default": 20,
5036
5505
  "required": false,
5506
+ "positional": false,
5037
5507
  "help": "Number of accounts"
5038
5508
  }
5039
5509
  ],
@@ -5074,6 +5544,7 @@
5074
5544
  "type": "int",
5075
5545
  "default": 1,
5076
5546
  "required": false,
5547
+ "positional": false,
5077
5548
  "help": "Post index (1 = most recent)"
5078
5549
  }
5079
5550
  ],
@@ -5147,6 +5618,7 @@
5147
5618
  "type": "int",
5148
5619
  "default": 1,
5149
5620
  "required": false,
5621
+ "positional": false,
5150
5622
  "help": "Post index (1 = most recent)"
5151
5623
  }
5152
5624
  ],
@@ -5178,6 +5650,7 @@
5178
5650
  "type": "int",
5179
5651
  "default": 20,
5180
5652
  "required": false,
5653
+ "positional": false,
5181
5654
  "help": "Number of saved posts"
5182
5655
  }
5183
5656
  ],
@@ -5219,6 +5692,7 @@
5219
5692
  "type": "int",
5220
5693
  "default": 10,
5221
5694
  "required": false,
5695
+ "positional": false,
5222
5696
  "help": "Number of results"
5223
5697
  }
5224
5698
  ],
@@ -5290,6 +5764,7 @@
5290
5764
  "type": "int",
5291
5765
  "default": 1,
5292
5766
  "required": false,
5767
+ "positional": false,
5293
5768
  "help": "Post index (1 = most recent)"
5294
5769
  }
5295
5770
  ],
@@ -5328,6 +5803,7 @@
5328
5803
  "type": "int",
5329
5804
  "default": 1,
5330
5805
  "required": false,
5806
+ "positional": false,
5331
5807
  "help": "Post index (1 = most recent)"
5332
5808
  }
5333
5809
  ],
@@ -5366,6 +5842,7 @@
5366
5842
  "type": "int",
5367
5843
  "default": 12,
5368
5844
  "required": false,
5845
+ "positional": false,
5369
5846
  "help": "Number of posts"
5370
5847
  }
5371
5848
  ],
@@ -5390,7 +5867,7 @@
5390
5867
  {
5391
5868
  "site": "jd",
5392
5869
  "name": "item",
5393
- "description": "京东商品详情(价格、主图、详情图、规格参数)",
5870
+ "description": "京东商品详情(价格、店铺、规格参数、AVIF 图片)",
5394
5871
  "strategy": "cookie",
5395
5872
  "browser": true,
5396
5873
  "args": [
@@ -5406,7 +5883,7 @@
5406
5883
  "type": "int",
5407
5884
  "default": 10,
5408
5885
  "required": false,
5409
- "help": "详情图数量(默认10)"
5886
+ "help": "AVIF 图片数量上限(默认10)"
5410
5887
  }
5411
5888
  ],
5412
5889
  "type": "ts",
@@ -5417,8 +5894,7 @@
5417
5894
  "price",
5418
5895
  "shop",
5419
5896
  "specs",
5420
- "mainImages",
5421
- "detailImages"
5897
+ "avifImages"
5422
5898
  ]
5423
5899
  },
5424
5900
  {
@@ -5675,6 +6151,7 @@
5675
6151
  "type": "int",
5676
6152
  "default": 20,
5677
6153
  "required": false,
6154
+ "positional": false,
5678
6155
  "help": "Number of posts"
5679
6156
  }
5680
6157
  ],
@@ -5729,6 +6206,7 @@
5729
6206
  "type": "int",
5730
6207
  "default": 20,
5731
6208
  "required": false,
6209
+ "positional": false,
5732
6210
  "help": "Number of posts"
5733
6211
  }
5734
6212
  ],
@@ -5783,6 +6261,7 @@
5783
6261
  "type": "string",
5784
6262
  "default": "high_aes_general_v50",
5785
6263
  "required": false,
6264
+ "positional": false,
5786
6265
  "help": "模型: high_aes_general_v50 (5.0 Lite), high_aes_general_v42 (4.6), high_aes_general_v40 (4.0)"
5787
6266
  },
5788
6267
  {
@@ -5790,6 +6269,7 @@
5790
6269
  "type": "int",
5791
6270
  "default": 40,
5792
6271
  "required": false,
6272
+ "positional": false,
5793
6273
  "help": "等待生成完成的秒数"
5794
6274
  }
5795
6275
  ],
@@ -5833,6 +6313,7 @@
5833
6313
  "type": "int",
5834
6314
  "default": 5,
5835
6315
  "required": false,
6316
+ "positional": false,
5836
6317
  "help": ""
5837
6318
  }
5838
6319
  ],
@@ -5988,11 +6469,20 @@
5988
6469
  "strategy": "cookie",
5989
6470
  "browser": true,
5990
6471
  "args": [
6472
+ {
6473
+ "name": "subcategories",
6474
+ "type": "boolean",
6475
+ "default": false,
6476
+ "required": false,
6477
+ "positional": false,
6478
+ "help": "Include subcategories"
6479
+ },
5991
6480
  {
5992
6481
  "name": "limit",
5993
6482
  "type": "int",
5994
6483
  "default": 20,
5995
6484
  "required": false,
6485
+ "positional": false,
5996
6486
  "help": "Number of categories"
5997
6487
  }
5998
6488
  ],
@@ -6008,7 +6498,7 @@
6008
6498
  "navigate": "https://linux.do"
6009
6499
  },
6010
6500
  {
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"
6501
+ "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
6502
  },
6013
6503
  {
6014
6504
  "map": {
@@ -6018,9 +6508,6 @@
6018
6508
  "topics": "${{ item.topics }}",
6019
6509
  "description": "${{ item.description }}"
6020
6510
  }
6021
- },
6022
- {
6023
- "limit": "${{ args.limit }}"
6024
6511
  }
6025
6512
  ],
6026
6513
  "type": "yaml"
@@ -6029,7 +6516,6 @@
6029
6516
  "site": "linux-do",
6030
6517
  "name": "category",
6031
6518
  "description": "linux.do 分类内话题",
6032
- "domain": "linux.do",
6033
6519
  "strategy": "cookie",
6034
6520
  "browser": true,
6035
6521
  "args": [
@@ -6038,57 +6524,60 @@
6038
6524
  "type": "str",
6039
6525
  "required": true,
6040
6526
  "positional": true,
6041
- "help": "Category slug (use 'categories' command to find)"
6527
+ "help": "Category slug (legacy compatibility argument)"
6042
6528
  },
6043
6529
  {
6044
6530
  "name": "id",
6045
6531
  "type": "int",
6046
6532
  "required": true,
6047
6533
  "positional": true,
6048
- "help": "Category ID (use 'categories' command to find)"
6534
+ "help": "Category ID"
6049
6535
  },
6050
6536
  {
6051
6537
  "name": "limit",
6052
6538
  "type": "int",
6053
6539
  "default": 20,
6054
6540
  "required": false,
6055
- "help": "Number of topics"
6541
+ "help": "Number of items (per_page)"
6056
6542
  }
6057
6543
  ],
6544
+ "type": "ts",
6545
+ "modulePath": "linux-do/category.js",
6546
+ "domain": "linux.do",
6058
6547
  "columns": [
6059
- "rank",
6060
6548
  "title",
6061
6549
  "replies",
6550
+ "created",
6551
+ "likes",
6062
6552
  "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
- }
6553
+ "url"
6084
6554
  ],
6085
- "type": "yaml"
6555
+ "deprecated": "opencli linux-do category is kept for backward compatibility.",
6556
+ "replacedBy": "opencli linux-do feed --category <id-or-name>"
6557
+ },
6558
+ {
6559
+ "site": "linux-do",
6560
+ "name": "feed",
6561
+ "description": "linux.do 话题列表(需登录;支持全站、标签、分类)",
6562
+ "strategy": "cookie",
6563
+ "browser": true,
6564
+ "args": [],
6565
+ "type": "ts",
6566
+ "modulePath": "linux-do/feed.js",
6567
+ "domain": "linux.do",
6568
+ "columns": [
6569
+ "title",
6570
+ "replies",
6571
+ "created",
6572
+ "likes",
6573
+ "views",
6574
+ "url"
6575
+ ]
6086
6576
  },
6087
6577
  {
6088
6578
  "site": "linux-do",
6089
6579
  "name": "hot",
6090
6580
  "description": "linux.do 热门话题",
6091
- "domain": "linux.do",
6092
6581
  "strategy": "cookie",
6093
6582
  "browser": true,
6094
6583
  "args": [
@@ -6097,7 +6586,7 @@
6097
6586
  "type": "int",
6098
6587
  "default": 20,
6099
6588
  "required": false,
6100
- "help": "Number of topics"
6589
+ "help": "Number of items (per_page)"
6101
6590
  },
6102
6591
  {
6103
6592
  "name": "period",
@@ -6110,33 +6599,101 @@
6110
6599
  "daily",
6111
6600
  "weekly",
6112
6601
  "monthly",
6602
+ "quarterly",
6113
6603
  "yearly"
6114
6604
  ]
6115
6605
  }
6116
6606
  ],
6607
+ "type": "ts",
6608
+ "modulePath": "linux-do/hot.js",
6609
+ "domain": "linux.do",
6117
6610
  "columns": [
6118
- "rank",
6119
6611
  "title",
6120
6612
  "replies",
6613
+ "created",
6614
+ "likes",
6121
6615
  "views",
6616
+ "url"
6617
+ ],
6618
+ "deprecated": "opencli linux-do hot is kept for backward compatibility.",
6619
+ "replacedBy": "opencli linux-do feed --view top --period <period>"
6620
+ },
6621
+ {
6622
+ "site": "linux-do",
6623
+ "name": "latest",
6624
+ "description": "linux.do 最新话题",
6625
+ "strategy": "cookie",
6626
+ "browser": true,
6627
+ "args": [
6628
+ {
6629
+ "name": "limit",
6630
+ "type": "int",
6631
+ "default": 20,
6632
+ "required": false,
6633
+ "help": "Number of items (per_page)"
6634
+ }
6635
+ ],
6636
+ "type": "ts",
6637
+ "modulePath": "linux-do/latest.js",
6638
+ "domain": "linux.do",
6639
+ "columns": [
6640
+ "title",
6641
+ "replies",
6642
+ "created",
6122
6643
  "likes",
6123
- "category"
6644
+ "views",
6645
+ "url"
6646
+ ],
6647
+ "deprecated": "opencli linux-do latest is kept for backward compatibility.",
6648
+ "replacedBy": "opencli linux-do feed --view latest"
6649
+ },
6650
+ {
6651
+ "site": "linux-do",
6652
+ "name": "search",
6653
+ "description": "搜索 linux.do",
6654
+ "domain": "linux.do",
6655
+ "strategy": "cookie",
6656
+ "browser": true,
6657
+ "args": [
6658
+ {
6659
+ "name": "query",
6660
+ "type": "str",
6661
+ "required": true,
6662
+ "positional": true,
6663
+ "help": "Search query"
6664
+ },
6665
+ {
6666
+ "name": "limit",
6667
+ "type": "int",
6668
+ "default": 20,
6669
+ "required": false,
6670
+ "positional": false,
6671
+ "help": "Number of results"
6672
+ }
6673
+ ],
6674
+ "columns": [
6675
+ "rank",
6676
+ "title",
6677
+ "views",
6678
+ "likes",
6679
+ "replies",
6680
+ "url"
6124
6681
  ],
6125
6682
  "pipeline": [
6126
6683
  {
6127
6684
  "navigate": "https://linux.do"
6128
6685
  },
6129
6686
  {
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"
6687
+ "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
6688
  },
6132
6689
  {
6133
6690
  "map": {
6134
6691
  "rank": "${{ index + 1 }}",
6135
6692
  "title": "${{ item.title }}",
6136
- "replies": "${{ item.replies }}",
6137
6693
  "views": "${{ item.views }}",
6138
6694
  "likes": "${{ item.likes }}",
6139
- "category": "${{ item.category }}"
6695
+ "replies": "${{ item.replies }}",
6696
+ "url": "${{ item.url }}"
6140
6697
  }
6141
6698
  },
6142
6699
  {
@@ -6147,8 +6704,8 @@
6147
6704
  },
6148
6705
  {
6149
6706
  "site": "linux-do",
6150
- "name": "latest",
6151
- "description": "linux.do 最新话题",
6707
+ "name": "tags",
6708
+ "description": "linux.do 标签列表",
6152
6709
  "domain": "linux.do",
6153
6710
  "strategy": "cookie",
6154
6711
  "browser": true,
@@ -6156,69 +6713,124 @@
6156
6713
  {
6157
6714
  "name": "limit",
6158
6715
  "type": "int",
6159
- "default": 20,
6716
+ "default": 30,
6160
6717
  "required": false,
6161
- "help": "Number of topics"
6718
+ "positional": false,
6719
+ "help": "Number of tags"
6162
6720
  }
6163
6721
  ],
6164
6722
  "columns": [
6165
6723
  "rank",
6166
- "title",
6167
- "replies",
6168
- "views",
6169
- "likes"
6724
+ "name",
6725
+ "count",
6726
+ "url"
6170
6727
  ],
6171
6728
  "pipeline": [
6172
6729
  {
6173
6730
  "navigate": "https://linux.do"
6174
6731
  },
6175
6732
  {
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"
6733
+ "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
6734
  },
6178
6735
  {
6179
6736
  "map": {
6180
6737
  "rank": "${{ index + 1 }}",
6181
- "title": "${{ item.title }}",
6182
- "replies": "${{ item.replies }}",
6183
- "views": "${{ item.views }}",
6184
- "likes": "${{ item.likes }}"
6738
+ "name": "${{ item.name }}",
6739
+ "count": "${{ item.count }}",
6740
+ "slug": "${{ item.slug }}",
6741
+ "id": "${{ item.id }}",
6742
+ "url": "https://linux.do/tag/${{ item.slug }}"
6185
6743
  }
6744
+ }
6745
+ ],
6746
+ "type": "yaml"
6747
+ },
6748
+ {
6749
+ "site": "linux-do",
6750
+ "name": "topic",
6751
+ "description": "linux.do 帖子详情和回复(首页)",
6752
+ "domain": "linux.do",
6753
+ "strategy": "cookie",
6754
+ "browser": true,
6755
+ "args": [
6756
+ {
6757
+ "name": "id",
6758
+ "type": "int",
6759
+ "required": true,
6760
+ "positional": true,
6761
+ "help": "Topic ID"
6186
6762
  },
6187
6763
  {
6188
- "limit": "${{ args.limit }}"
6764
+ "name": "limit",
6765
+ "type": "int",
6766
+ "default": 20,
6767
+ "required": false,
6768
+ "positional": false,
6769
+ "help": "Number of posts"
6770
+ },
6771
+ {
6772
+ "name": "main_only",
6773
+ "type": "bool",
6774
+ "default": false,
6775
+ "required": false,
6776
+ "positional": false,
6777
+ "help": "Only return the main post body without truncation"
6778
+ }
6779
+ ],
6780
+ "columns": [
6781
+ "author",
6782
+ "content",
6783
+ "likes",
6784
+ "created_at"
6785
+ ],
6786
+ "pipeline": [
6787
+ {
6788
+ "navigate": "https://linux.do"
6789
+ },
6790
+ {
6791
+ "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"
6792
+ },
6793
+ {
6794
+ "map": {
6795
+ "author": "${{ item.author }}",
6796
+ "content": "${{ item.content }}",
6797
+ "likes": "${{ item.likes }}",
6798
+ "created_at": "${{ item.created_at }}"
6799
+ }
6189
6800
  }
6190
6801
  ],
6191
6802
  "type": "yaml"
6192
6803
  },
6193
6804
  {
6194
6805
  "site": "linux-do",
6195
- "name": "search",
6196
- "description": "搜索 linux.do",
6806
+ "name": "user-posts",
6807
+ "description": "linux.do 用户的帖子",
6197
6808
  "domain": "linux.do",
6198
6809
  "strategy": "cookie",
6199
6810
  "browser": true,
6200
6811
  "args": [
6201
6812
  {
6202
- "name": "query",
6813
+ "name": "username",
6203
6814
  "type": "str",
6204
6815
  "required": true,
6205
6816
  "positional": true,
6206
- "help": "Search query"
6817
+ "help": "Username"
6207
6818
  },
6208
6819
  {
6209
6820
  "name": "limit",
6210
6821
  "type": "int",
6211
6822
  "default": 20,
6212
6823
  "required": false,
6213
- "help": "Number of results"
6824
+ "positional": false,
6825
+ "help": "Number of posts"
6214
6826
  }
6215
6827
  ],
6216
6828
  "columns": [
6217
- "rank",
6218
- "title",
6219
- "views",
6220
- "likes",
6221
- "replies",
6829
+ "index",
6830
+ "topic_user",
6831
+ "topic",
6832
+ "reply",
6833
+ "time",
6222
6834
  "url"
6223
6835
  ],
6224
6836
  "pipeline": [
@@ -6226,59 +6838,70 @@
6226
6838
  "navigate": "https://linux.do"
6227
6839
  },
6228
6840
  {
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"
6841
+ "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
6842
  },
6231
6843
  {
6232
6844
  "map": {
6233
- "rank": "${{ index + 1 }}",
6234
- "title": "${{ item.title }}",
6235
- "views": "${{ item.views }}",
6236
- "likes": "${{ item.likes }}",
6237
- "replies": "${{ item.replies }}",
6845
+ "index": "${{ index + 1 }}",
6846
+ "topic_user": "${{ item.author }}",
6847
+ "topic": "${{ item.title }}",
6848
+ "reply": "${{ item.content }}",
6849
+ "time": "${{ item.created_at }}",
6238
6850
  "url": "${{ item.url }}"
6239
6851
  }
6240
- },
6241
- {
6242
- "limit": "${{ args.limit }}"
6243
6852
  }
6244
6853
  ],
6245
6854
  "type": "yaml"
6246
6855
  },
6247
6856
  {
6248
6857
  "site": "linux-do",
6249
- "name": "topic",
6250
- "description": "linux.do 帖子详情和回复(首页)",
6858
+ "name": "user-topics",
6859
+ "description": "linux.do 用户创建的话题",
6251
6860
  "domain": "linux.do",
6252
6861
  "strategy": "cookie",
6253
6862
  "browser": true,
6254
6863
  "args": [
6255
6864
  {
6256
- "name": "id",
6257
- "type": "int",
6865
+ "name": "username",
6866
+ "type": "str",
6258
6867
  "required": true,
6259
6868
  "positional": true,
6260
- "help": "Topic ID"
6869
+ "help": "Username"
6870
+ },
6871
+ {
6872
+ "name": "limit",
6873
+ "type": "int",
6874
+ "default": 20,
6875
+ "required": false,
6876
+ "positional": false,
6877
+ "help": "Number of topics"
6261
6878
  }
6262
6879
  ],
6263
6880
  "columns": [
6264
- "author",
6265
- "content",
6881
+ "rank",
6882
+ "title",
6883
+ "replies",
6884
+ "created_at",
6266
6885
  "likes",
6267
- "created_at"
6886
+ "views",
6887
+ "url"
6268
6888
  ],
6269
6889
  "pipeline": [
6270
6890
  {
6271
6891
  "navigate": "https://linux.do"
6272
6892
  },
6273
6893
  {
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"
6894
+ "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
6895
  },
6276
6896
  {
6277
6897
  "map": {
6278
- "author": "${{ item.author }}",
6279
- "content": "${{ item.content }}",
6898
+ "rank": "${{ index + 1 }}",
6899
+ "title": "${{ item.title }}",
6900
+ "replies": "${{ item.replies }}",
6901
+ "created_at": "${{ item.created_at }}",
6280
6902
  "likes": "${{ item.likes }}",
6281
- "created_at": "${{ item.created_at }}"
6903
+ "views": "${{ item.views }}",
6904
+ "url": "${{ item.url }}"
6282
6905
  }
6283
6906
  }
6284
6907
  ],
@@ -6297,6 +6920,7 @@
6297
6920
  "type": "int",
6298
6921
  "default": 20,
6299
6922
  "required": false,
6923
+ "positional": false,
6300
6924
  "help": "Number of stories"
6301
6925
  }
6302
6926
  ],
@@ -6344,6 +6968,7 @@
6344
6968
  "type": "int",
6345
6969
  "default": 20,
6346
6970
  "required": false,
6971
+ "positional": false,
6347
6972
  "help": "Number of stories"
6348
6973
  }
6349
6974
  ],
@@ -6391,6 +7016,7 @@
6391
7016
  "type": "int",
6392
7017
  "default": 20,
6393
7018
  "required": false,
7019
+ "positional": false,
6394
7020
  "help": "Number of stories"
6395
7021
  }
6396
7022
  ],
@@ -6445,6 +7071,7 @@
6445
7071
  "type": "int",
6446
7072
  "default": 20,
6447
7073
  "required": false,
7074
+ "positional": false,
6448
7075
  "help": "Number of stories"
6449
7076
  }
6450
7077
  ],
@@ -6734,6 +7361,143 @@
6734
7361
  "Status"
6735
7362
  ]
6736
7363
  },
7364
+ {
7365
+ "site": "paperreview",
7366
+ "name": "feedback",
7367
+ "description": "Submit feedback for a paperreview.ai review token",
7368
+ "strategy": "public",
7369
+ "browser": false,
7370
+ "args": [
7371
+ {
7372
+ "name": "token",
7373
+ "type": "str",
7374
+ "required": true,
7375
+ "positional": true,
7376
+ "help": "Review token returned by paperreview.ai"
7377
+ },
7378
+ {
7379
+ "name": "helpfulness",
7380
+ "type": "int",
7381
+ "required": true,
7382
+ "help": "Helpfulness score from 1 to 5"
7383
+ },
7384
+ {
7385
+ "name": "critical-error",
7386
+ "type": "str",
7387
+ "required": true,
7388
+ "help": "Whether the review contains a critical error",
7389
+ "choices": [
7390
+ "yes",
7391
+ "no"
7392
+ ]
7393
+ },
7394
+ {
7395
+ "name": "actionable-suggestions",
7396
+ "type": "str",
7397
+ "required": true,
7398
+ "help": "Whether the review contains actionable suggestions",
7399
+ "choices": [
7400
+ "yes",
7401
+ "no"
7402
+ ]
7403
+ },
7404
+ {
7405
+ "name": "additional-comments",
7406
+ "type": "str",
7407
+ "required": false,
7408
+ "help": "Optional free-text feedback"
7409
+ }
7410
+ ],
7411
+ "type": "ts",
7412
+ "modulePath": "paperreview/feedback.js",
7413
+ "columns": [
7414
+ "status",
7415
+ "token",
7416
+ "helpfulness",
7417
+ "critical_error",
7418
+ "actionable_suggestions",
7419
+ "message"
7420
+ ]
7421
+ },
7422
+ {
7423
+ "site": "paperreview",
7424
+ "name": "review",
7425
+ "description": "Fetch a paperreview.ai review by token",
7426
+ "strategy": "public",
7427
+ "browser": false,
7428
+ "args": [
7429
+ {
7430
+ "name": "token",
7431
+ "type": "str",
7432
+ "required": true,
7433
+ "positional": true,
7434
+ "help": "Review token returned by paperreview.ai"
7435
+ }
7436
+ ],
7437
+ "type": "ts",
7438
+ "modulePath": "paperreview/review.js",
7439
+ "columns": [
7440
+ "status",
7441
+ "title",
7442
+ "venue",
7443
+ "numerical_score",
7444
+ "has_feedback",
7445
+ "review_url"
7446
+ ]
7447
+ },
7448
+ {
7449
+ "site": "paperreview",
7450
+ "name": "submit",
7451
+ "description": "Submit a PDF to paperreview.ai for review",
7452
+ "strategy": "public",
7453
+ "browser": false,
7454
+ "args": [
7455
+ {
7456
+ "name": "pdf",
7457
+ "type": "str",
7458
+ "required": true,
7459
+ "positional": true,
7460
+ "help": "Path to the paper PDF"
7461
+ },
7462
+ {
7463
+ "name": "email",
7464
+ "type": "str",
7465
+ "required": true,
7466
+ "help": "Email address for the submission"
7467
+ },
7468
+ {
7469
+ "name": "venue",
7470
+ "type": "str",
7471
+ "required": false,
7472
+ "help": "Optional target venue such as ICLR or NeurIPS"
7473
+ },
7474
+ {
7475
+ "name": "dry-run",
7476
+ "type": "bool",
7477
+ "default": false,
7478
+ "required": false,
7479
+ "help": "Validate the input and stop before remote submission"
7480
+ },
7481
+ {
7482
+ "name": "prepare-only",
7483
+ "type": "bool",
7484
+ "default": false,
7485
+ "required": false,
7486
+ "help": "Request an upload slot but stop before uploading the PDF"
7487
+ }
7488
+ ],
7489
+ "type": "ts",
7490
+ "modulePath": "paperreview/submit.js",
7491
+ "columns": [
7492
+ "status",
7493
+ "file",
7494
+ "email",
7495
+ "venue",
7496
+ "token",
7497
+ "review_url",
7498
+ "message"
7499
+ ]
7500
+ },
6737
7501
  {
6738
7502
  "site": "pixiv",
6739
7503
  "name": "detail",
@@ -6853,6 +7617,7 @@
6853
7617
  "type": "str",
6854
7618
  "default": "daily",
6855
7619
  "required": false,
7620
+ "positional": false,
6856
7621
  "help": "Ranking mode",
6857
7622
  "choices": [
6858
7623
  "daily",
@@ -6871,6 +7636,7 @@
6871
7636
  "type": "int",
6872
7637
  "default": 1,
6873
7638
  "required": false,
7639
+ "positional": false,
6874
7640
  "help": "Page number"
6875
7641
  },
6876
7642
  {
@@ -6878,6 +7644,7 @@
6878
7644
  "type": "int",
6879
7645
  "default": 20,
6880
7646
  "required": false,
7647
+ "positional": false,
6881
7648
  "help": "Number of results"
6882
7649
  }
6883
7650
  ],
@@ -7003,6 +7770,124 @@
7003
7770
  ],
7004
7771
  "type": "yaml"
7005
7772
  },
7773
+ {
7774
+ "site": "producthunt",
7775
+ "name": "browse",
7776
+ "description": "Best products in a Product Hunt category",
7777
+ "strategy": "intercept",
7778
+ "browser": true,
7779
+ "args": [
7780
+ {
7781
+ "name": "category",
7782
+ "type": "string",
7783
+ "required": true,
7784
+ "positional": true,
7785
+ "help": "Category slug, e.g. vibe-coding, ai-agents, developer-tools"
7786
+ },
7787
+ {
7788
+ "name": "limit",
7789
+ "type": "int",
7790
+ "default": 20,
7791
+ "required": false,
7792
+ "help": "Number of results (max 50)"
7793
+ }
7794
+ ],
7795
+ "type": "ts",
7796
+ "modulePath": "producthunt/browse.js",
7797
+ "domain": "www.producthunt.com",
7798
+ "columns": [
7799
+ "rank",
7800
+ "name",
7801
+ "tagline",
7802
+ "reviews",
7803
+ "url"
7804
+ ]
7805
+ },
7806
+ {
7807
+ "site": "producthunt",
7808
+ "name": "hot",
7809
+ "description": "Today",
7810
+ "strategy": "intercept",
7811
+ "browser": true,
7812
+ "args": [
7813
+ {
7814
+ "name": "limit",
7815
+ "type": "int",
7816
+ "default": 20,
7817
+ "required": false,
7818
+ "help": "Number of results (max 50)"
7819
+ }
7820
+ ],
7821
+ "type": "ts",
7822
+ "modulePath": "producthunt/hot.js",
7823
+ "domain": "www.producthunt.com",
7824
+ "columns": [
7825
+ "rank",
7826
+ "name",
7827
+ "votes",
7828
+ "url"
7829
+ ]
7830
+ },
7831
+ {
7832
+ "site": "producthunt",
7833
+ "name": "posts",
7834
+ "description": "Latest Product Hunt launches (optional category filter)",
7835
+ "strategy": "public",
7836
+ "browser": false,
7837
+ "args": [
7838
+ {
7839
+ "name": "limit",
7840
+ "type": "int",
7841
+ "default": 20,
7842
+ "required": false,
7843
+ "help": "Number of results (max 50)"
7844
+ },
7845
+ {
7846
+ "name": "category",
7847
+ "type": "string",
7848
+ "default": "",
7849
+ "required": false,
7850
+ "help": "Category filter: ${PRODUCTHUNT_CATEGORY_SLUGS.join("
7851
+ }
7852
+ ],
7853
+ "type": "ts",
7854
+ "modulePath": "producthunt/posts.js",
7855
+ "domain": "www.producthunt.com",
7856
+ "columns": [
7857
+ "rank",
7858
+ "name",
7859
+ "tagline",
7860
+ "author",
7861
+ "date",
7862
+ "url"
7863
+ ]
7864
+ },
7865
+ {
7866
+ "site": "producthunt",
7867
+ "name": "today",
7868
+ "description": "Today",
7869
+ "strategy": "public",
7870
+ "browser": false,
7871
+ "args": [
7872
+ {
7873
+ "name": "limit",
7874
+ "type": "int",
7875
+ "default": 20,
7876
+ "required": false,
7877
+ "help": "Max results"
7878
+ }
7879
+ ],
7880
+ "type": "ts",
7881
+ "modulePath": "producthunt/today.js",
7882
+ "domain": "www.producthunt.com",
7883
+ "columns": [
7884
+ "rank",
7885
+ "name",
7886
+ "tagline",
7887
+ "author",
7888
+ "url"
7889
+ ]
7890
+ },
7006
7891
  {
7007
7892
  "site": "reddit",
7008
7893
  "name": "comment",
@@ -7046,6 +7931,7 @@
7046
7931
  "type": "int",
7047
7932
  "default": 15,
7048
7933
  "required": false,
7934
+ "positional": false,
7049
7935
  "help": ""
7050
7936
  }
7051
7937
  ],
@@ -7093,6 +7979,7 @@
7093
7979
  "type": "str",
7094
7980
  "default": "",
7095
7981
  "required": false,
7982
+ "positional": false,
7096
7983
  "help": "Subreddit name (e.g. programming). Empty for frontpage"
7097
7984
  },
7098
7985
  {
@@ -7100,6 +7987,7 @@
7100
7987
  "type": "int",
7101
7988
  "default": 20,
7102
7989
  "required": false,
7990
+ "positional": false,
7103
7991
  "help": "Number of posts"
7104
7992
  }
7105
7993
  ],
@@ -7145,6 +8033,7 @@
7145
8033
  "type": "int",
7146
8034
  "default": 20,
7147
8035
  "required": false,
8036
+ "positional": false,
7148
8037
  "help": ""
7149
8038
  }
7150
8039
  ],
@@ -7315,6 +8204,7 @@
7315
8204
  "type": "string",
7316
8205
  "default": "",
7317
8206
  "required": false,
8207
+ "positional": false,
7318
8208
  "help": "Search within a specific subreddit"
7319
8209
  },
7320
8210
  {
@@ -7322,6 +8212,7 @@
7322
8212
  "type": "string",
7323
8213
  "default": "relevance",
7324
8214
  "required": false,
8215
+ "positional": false,
7325
8216
  "help": "Sort order: relevance, hot, top, new, comments"
7326
8217
  },
7327
8218
  {
@@ -7329,6 +8220,7 @@
7329
8220
  "type": "string",
7330
8221
  "default": "all",
7331
8222
  "required": false,
8223
+ "positional": false,
7332
8224
  "help": "Time filter: hour, day, week, month, year, all"
7333
8225
  },
7334
8226
  {
@@ -7336,6 +8228,7 @@
7336
8228
  "type": "int",
7337
8229
  "default": 15,
7338
8230
  "required": false,
8231
+ "positional": false,
7339
8232
  "help": ""
7340
8233
  }
7341
8234
  ],
@@ -7390,6 +8283,7 @@
7390
8283
  "type": "string",
7391
8284
  "default": "hot",
7392
8285
  "required": false,
8286
+ "positional": false,
7393
8287
  "help": "Sorting method: hot, new, top, rising, controversial"
7394
8288
  },
7395
8289
  {
@@ -7397,6 +8291,7 @@
7397
8291
  "type": "string",
7398
8292
  "default": "all",
7399
8293
  "required": false,
8294
+ "positional": false,
7400
8295
  "help": "Time filter for top/controversial: hour, day, week, month, year, all"
7401
8296
  },
7402
8297
  {
@@ -7404,6 +8299,7 @@
7404
8299
  "type": "int",
7405
8300
  "default": 15,
7406
8301
  "required": false,
8302
+ "positional": false,
7407
8303
  "help": ""
7408
8304
  }
7409
8305
  ],
@@ -7542,6 +8438,7 @@
7542
8438
  "type": "int",
7543
8439
  "default": 15,
7544
8440
  "required": false,
8441
+ "positional": false,
7545
8442
  "help": ""
7546
8443
  }
7547
8444
  ],
@@ -7592,6 +8489,7 @@
7592
8489
  "type": "int",
7593
8490
  "default": 15,
7594
8491
  "required": false,
8492
+ "positional": false,
7595
8493
  "help": ""
7596
8494
  }
7597
8495
  ],
@@ -7894,6 +8792,7 @@
7894
8792
  "type": "int",
7895
8793
  "default": 10,
7896
8794
  "required": false,
8795
+ "positional": false,
7897
8796
  "help": "Max number of results"
7898
8797
  }
7899
8798
  ],
@@ -7941,6 +8840,7 @@
7941
8840
  "type": "int",
7942
8841
  "default": 10,
7943
8842
  "required": false,
8843
+ "positional": false,
7944
8844
  "help": "Max number of results"
7945
8845
  }
7946
8846
  ],
@@ -7993,6 +8893,7 @@
7993
8893
  "type": "int",
7994
8894
  "default": 10,
7995
8895
  "required": false,
8896
+ "positional": false,
7996
8897
  "help": "Max number of results"
7997
8898
  }
7998
8899
  ],
@@ -8038,6 +8939,7 @@
8038
8939
  "type": "int",
8039
8940
  "default": 10,
8040
8941
  "required": false,
8942
+ "positional": false,
8041
8943
  "help": "Max number of results"
8042
8944
  }
8043
8945
  ],
@@ -8083,6 +8985,7 @@
8083
8985
  "type": "int",
8084
8986
  "default": 10,
8085
8987
  "required": false,
8988
+ "positional": false,
8086
8989
  "help": "Number of games"
8087
8990
  }
8088
8991
  ],
@@ -8283,6 +9186,7 @@
8283
9186
  "type": "int",
8284
9187
  "default": 20,
8285
9188
  "required": false,
9189
+ "positional": false,
8286
9190
  "help": "Number of videos"
8287
9191
  }
8288
9192
  ],
@@ -8351,6 +9255,7 @@
8351
9255
  "type": "int",
8352
9256
  "default": 20,
8353
9257
  "required": false,
9258
+ "positional": false,
8354
9259
  "help": "Number of accounts"
8355
9260
  }
8356
9261
  ],
@@ -8385,6 +9290,7 @@
8385
9290
  "type": "int",
8386
9291
  "default": 20,
8387
9292
  "required": false,
9293
+ "positional": false,
8388
9294
  "help": "Number of suggestions"
8389
9295
  }
8390
9296
  ],
@@ -8453,6 +9359,7 @@
8453
9359
  "type": "int",
8454
9360
  "default": 10,
8455
9361
  "required": false,
9362
+ "positional": false,
8456
9363
  "help": "Number of streams"
8457
9364
  }
8458
9365
  ],
@@ -8488,6 +9395,7 @@
8488
9395
  "type": "int",
8489
9396
  "default": 15,
8490
9397
  "required": false,
9398
+ "positional": false,
8491
9399
  "help": "Number of notifications"
8492
9400
  },
8493
9401
  {
@@ -8495,6 +9403,7 @@
8495
9403
  "type": "str",
8496
9404
  "default": "all",
8497
9405
  "required": false,
9406
+ "positional": false,
8498
9407
  "help": "Notification type",
8499
9408
  "choices": [
8500
9409
  "all",
@@ -8614,6 +9523,7 @@
8614
9523
  "type": "int",
8615
9524
  "default": 10,
8616
9525
  "required": false,
9526
+ "positional": false,
8617
9527
  "help": "Number of results"
8618
9528
  }
8619
9529
  ],
@@ -8760,6 +9670,7 @@
8760
9670
  "type": "int",
8761
9671
  "default": 10,
8762
9672
  "required": false,
9673
+ "positional": false,
8763
9674
  "help": "Number of videos"
8764
9675
  }
8765
9676
  ],
@@ -9110,6 +10021,39 @@
9110
10021
  "message"
9111
10022
  ]
9112
10023
  },
10024
+ {
10025
+ "site": "twitter",
10026
+ "name": "likes",
10027
+ "description": "Fetch liked tweets of a Twitter user",
10028
+ "strategy": "cookie",
10029
+ "browser": true,
10030
+ "args": [
10031
+ {
10032
+ "name": "username",
10033
+ "type": "string",
10034
+ "required": false,
10035
+ "positional": true,
10036
+ "help": "Twitter screen name (without @). Defaults to logged-in user."
10037
+ },
10038
+ {
10039
+ "name": "limit",
10040
+ "type": "int",
10041
+ "default": 20,
10042
+ "required": false,
10043
+ "help": ""
10044
+ }
10045
+ ],
10046
+ "type": "ts",
10047
+ "modulePath": "twitter/likes.js",
10048
+ "domain": "x.com",
10049
+ "columns": [
10050
+ "author",
10051
+ "name",
10052
+ "text",
10053
+ "likes",
10054
+ "url"
10055
+ ]
10056
+ },
9113
10057
  {
9114
10058
  "site": "twitter",
9115
10059
  "name": "notifications",
@@ -9302,6 +10246,7 @@
9302
10246
  "id",
9303
10247
  "author",
9304
10248
  "text",
10249
+ "created_at",
9305
10250
  "likes",
9306
10251
  "views",
9307
10252
  "url"
@@ -9504,6 +10449,7 @@
9504
10449
  "type": "int",
9505
10450
  "default": 20,
9506
10451
  "required": false,
10452
+ "positional": false,
9507
10453
  "help": "Number of topics"
9508
10454
  }
9509
10455
  ],
@@ -9544,6 +10490,7 @@
9544
10490
  "type": "int",
9545
10491
  "default": 20,
9546
10492
  "required": false,
10493
+ "positional": false,
9547
10494
  "help": "Number of topics"
9548
10495
  }
9549
10496
  ],
@@ -9654,6 +10601,7 @@
9654
10601
  "type": "int",
9655
10602
  "default": 10,
9656
10603
  "required": false,
10604
+ "positional": false,
9657
10605
  "help": "Number of topics (API returns max 20)"
9658
10606
  }
9659
10607
  ],
@@ -9701,6 +10649,7 @@
9701
10649
  "type": "int",
9702
10650
  "default": 30,
9703
10651
  "required": false,
10652
+ "positional": false,
9704
10653
  "help": "Number of nodes"
9705
10654
  }
9706
10655
  ],
@@ -9782,6 +10731,7 @@
9782
10731
  "type": "int",
9783
10732
  "default": 20,
9784
10733
  "required": false,
10734
+ "positional": false,
9785
10735
  "help": "Number of replies"
9786
10736
  }
9787
10737
  ],
@@ -9875,6 +10825,7 @@
9875
10825
  "type": "int",
9876
10826
  "default": 10,
9877
10827
  "required": false,
10828
+ "positional": false,
9878
10829
  "help": "Number of topics (API returns max 20)"
9879
10830
  }
9880
10831
  ],
@@ -10512,6 +11463,39 @@
10512
11463
  "views"
10513
11464
  ]
10514
11465
  },
11466
+ {
11467
+ "site": "xiaohongshu",
11468
+ "name": "comments",
11469
+ "description": "获取小红书笔记评论(仅主评论,不含楼中楼)",
11470
+ "strategy": "cookie",
11471
+ "browser": true,
11472
+ "args": [
11473
+ {
11474
+ "name": "note-id",
11475
+ "type": "str",
11476
+ "required": true,
11477
+ "positional": true,
11478
+ "help": "Note ID or full /explore/<id> URL"
11479
+ },
11480
+ {
11481
+ "name": "limit",
11482
+ "type": "int",
11483
+ "default": 20,
11484
+ "required": false,
11485
+ "help": "Number of comments (max 50)"
11486
+ }
11487
+ ],
11488
+ "type": "ts",
11489
+ "modulePath": "xiaohongshu/comments.js",
11490
+ "domain": "www.xiaohongshu.com",
11491
+ "columns": [
11492
+ "rank",
11493
+ "author",
11494
+ "text",
11495
+ "likes",
11496
+ "time"
11497
+ ]
11498
+ },
10515
11499
  {
10516
11500
  "site": "xiaohongshu",
10517
11501
  "name": "creator-note-detail",
@@ -10689,6 +11673,7 @@
10689
11673
  "type": "int",
10690
11674
  "default": 20,
10691
11675
  "required": false,
11676
+ "positional": false,
10692
11677
  "help": "Number of items to return"
10693
11678
  }
10694
11679
  ],
@@ -10741,6 +11726,7 @@
10741
11726
  "type": "str",
10742
11727
  "default": "mentions",
10743
11728
  "required": false,
11729
+ "positional": false,
10744
11730
  "help": "Notification type: mentions, likes, or connections"
10745
11731
  },
10746
11732
  {
@@ -10748,6 +11734,7 @@
10748
11734
  "type": "int",
10749
11735
  "default": 20,
10750
11736
  "required": false,
11737
+ "positional": false,
10751
11738
  "help": "Number of notifications to return"
10752
11739
  }
10753
11740
  ],
@@ -11013,6 +12000,7 @@
11013
12000
  "type": "bool",
11014
12001
  "default": false,
11015
12002
  "required": false,
12003
+ "positional": false,
11016
12004
  "help": "仅返回最近一次未发布的财报日期"
11017
12005
  },
11018
12006
  {
@@ -11020,6 +12008,7 @@
11020
12008
  "type": "int",
11021
12009
  "default": 10,
11022
12010
  "required": false,
12011
+ "positional": false,
11023
12012
  "help": "返回数量,默认 10"
11024
12013
  }
11025
12014
  ],
@@ -11061,6 +12050,7 @@
11061
12050
  "type": "int",
11062
12051
  "default": 1,
11063
12052
  "required": false,
12053
+ "positional": false,
11064
12054
  "help": "页码,默认 1"
11065
12055
  },
11066
12056
  {
@@ -11068,6 +12058,7 @@
11068
12058
  "type": "int",
11069
12059
  "default": 20,
11070
12060
  "required": false,
12061
+ "positional": false,
11071
12062
  "help": "每页数量,默认 20"
11072
12063
  }
11073
12064
  ],
@@ -11163,6 +12154,7 @@
11163
12154
  "type": "int",
11164
12155
  "default": 20,
11165
12156
  "required": false,
12157
+ "positional": false,
11166
12158
  "help": "返回数量,默认 20,最大 50"
11167
12159
  },
11168
12160
  {
@@ -11170,6 +12162,7 @@
11170
12162
  "type": "str",
11171
12163
  "default": "10",
11172
12164
  "required": false,
12165
+ "positional": false,
11173
12166
  "help": "榜单类型 10=人气榜(默认) 12=关注榜"
11174
12167
  }
11175
12168
  ],
@@ -11217,6 +12210,7 @@
11217
12210
  "type": "int",
11218
12211
  "default": 20,
11219
12212
  "required": false,
12213
+ "positional": false,
11220
12214
  "help": "返回数量,默认 20,最大 50"
11221
12215
  }
11222
12216
  ],
@@ -11269,6 +12263,7 @@
11269
12263
  "type": "int",
11270
12264
  "default": 10,
11271
12265
  "required": false,
12266
+ "positional": false,
11272
12267
  "help": "返回数量,默认 10"
11273
12268
  }
11274
12269
  ],
@@ -11358,6 +12353,7 @@
11358
12353
  "type": "str",
11359
12354
  "default": "1",
11360
12355
  "required": false,
12356
+ "positional": false,
11361
12357
  "help": "分类:1=自选(默认) 2=持仓 3=关注"
11362
12358
  },
11363
12359
  {
@@ -11365,6 +12361,7 @@
11365
12361
  "type": "int",
11366
12362
  "default": 100,
11367
12363
  "required": false,
12364
+ "positional": false,
11368
12365
  "help": "默认 100"
11369
12366
  }
11370
12367
  ],
@@ -12188,6 +13185,7 @@
12188
13185
  "type": "int",
12189
13186
  "default": 20,
12190
13187
  "required": false,
13188
+ "positional": false,
12191
13189
  "help": "Number of items to return"
12192
13190
  }
12193
13191
  ],
@@ -12271,6 +13269,7 @@
12271
13269
  "type": "int",
12272
13270
  "default": 10,
12273
13271
  "required": false,
13272
+ "positional": false,
12274
13273
  "help": "Number of results"
12275
13274
  }
12276
13275
  ],