@jackwener/opencli 0.9.6 → 1.0.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 (307) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.yml +42 -0
  4. package/.github/ISSUE_TEMPLATE/new_site_adapter.yml +57 -0
  5. package/.github/dependabot.yml +27 -0
  6. package/.github/pull_request_template.md +24 -0
  7. package/.github/workflows/ci.yml +14 -8
  8. package/.github/workflows/e2e-headed.yml +6 -2
  9. package/.github/workflows/pkg-pr-new.yml +2 -2
  10. package/.github/workflows/release-please.yml +25 -0
  11. package/.github/workflows/release.yml +2 -2
  12. package/.github/workflows/security.yml +36 -0
  13. package/CDP.md +1 -1
  14. package/CDP.zh-CN.md +1 -1
  15. package/CLI-ELECTRON.md +89 -36
  16. package/CLI-EXPLORER.md +4 -4
  17. package/CONTRIBUTING.md +167 -0
  18. package/README.md +113 -89
  19. package/README.zh-CN.md +114 -91
  20. package/SKILL.md +10 -8
  21. package/TESTING.md +7 -7
  22. package/dist/browser/daemon-client.d.ts +37 -0
  23. package/dist/browser/daemon-client.js +82 -0
  24. package/dist/browser/discover.d.ts +11 -34
  25. package/dist/browser/discover.js +15 -190
  26. package/dist/browser/errors.d.ts +6 -20
  27. package/dist/browser/errors.js +24 -63
  28. package/dist/browser/index.d.ts +2 -11
  29. package/dist/browser/index.js +5 -11
  30. package/dist/browser/mcp.d.ts +9 -18
  31. package/dist/browser/mcp.js +70 -284
  32. package/dist/browser/page.d.ts +28 -6
  33. package/dist/browser/page.js +210 -85
  34. package/dist/browser.test.js +4 -202
  35. package/dist/build-manifest.d.ts +26 -0
  36. package/dist/build-manifest.js +132 -60
  37. package/dist/build-manifest.test.d.ts +1 -0
  38. package/dist/build-manifest.test.js +26 -0
  39. package/dist/cli-manifest.json +1582 -29
  40. package/dist/clis/bilibili/download.d.ts +10 -0
  41. package/dist/clis/bilibili/download.js +135 -0
  42. package/dist/clis/chatwise/ask.d.ts +1 -0
  43. package/dist/clis/chatwise/ask.js +76 -0
  44. package/dist/clis/chatwise/export.d.ts +1 -0
  45. package/dist/clis/chatwise/export.js +46 -0
  46. package/dist/clis/chatwise/history.d.ts +1 -0
  47. package/dist/clis/chatwise/history.js +43 -0
  48. package/dist/clis/chatwise/model.d.ts +1 -0
  49. package/dist/clis/chatwise/model.js +81 -0
  50. package/dist/clis/chatwise/new.d.ts +1 -0
  51. package/dist/clis/chatwise/new.js +18 -0
  52. package/dist/clis/chatwise/read.d.ts +1 -0
  53. package/dist/clis/chatwise/read.js +39 -0
  54. package/dist/clis/chatwise/screenshot.d.ts +1 -0
  55. package/dist/clis/chatwise/screenshot.js +27 -0
  56. package/dist/clis/chatwise/send.d.ts +1 -0
  57. package/dist/clis/chatwise/send.js +45 -0
  58. package/dist/clis/chatwise/status.d.ts +1 -0
  59. package/dist/clis/chatwise/status.js +22 -0
  60. package/dist/clis/discord-app/channels.d.ts +1 -0
  61. package/dist/clis/discord-app/channels.js +45 -0
  62. package/dist/clis/discord-app/members.d.ts +1 -0
  63. package/dist/clis/discord-app/members.js +38 -0
  64. package/dist/clis/discord-app/read.d.ts +1 -0
  65. package/dist/clis/discord-app/read.js +45 -0
  66. package/dist/clis/discord-app/search.d.ts +1 -0
  67. package/dist/clis/discord-app/search.js +56 -0
  68. package/dist/clis/discord-app/send.d.ts +1 -0
  69. package/dist/clis/discord-app/send.js +27 -0
  70. package/dist/clis/discord-app/servers.d.ts +1 -0
  71. package/dist/clis/discord-app/servers.js +36 -0
  72. package/dist/clis/discord-app/status.d.ts +1 -0
  73. package/dist/clis/discord-app/status.js +16 -0
  74. package/dist/clis/feishu/new.d.ts +1 -0
  75. package/dist/clis/feishu/new.js +27 -0
  76. package/dist/clis/feishu/read.d.ts +1 -0
  77. package/dist/clis/feishu/read.js +40 -0
  78. package/dist/clis/feishu/search.d.ts +1 -0
  79. package/dist/clis/feishu/search.js +30 -0
  80. package/dist/clis/feishu/send.d.ts +1 -0
  81. package/dist/clis/feishu/send.js +39 -0
  82. package/dist/clis/feishu/status.d.ts +1 -0
  83. package/dist/clis/feishu/status.js +28 -0
  84. package/dist/clis/grok/ask.d.ts +1 -0
  85. package/dist/clis/grok/ask.js +82 -0
  86. package/dist/clis/grok/debug.d.ts +1 -0
  87. package/dist/clis/grok/debug.js +45 -0
  88. package/dist/clis/jimeng/generate.yaml +84 -0
  89. package/dist/clis/jimeng/history.yaml +47 -0
  90. package/dist/clis/linux-do/categories.yaml +41 -0
  91. package/dist/clis/linux-do/category.yaml +49 -0
  92. package/dist/clis/linux-do/hot.yaml +50 -0
  93. package/dist/clis/linux-do/latest.yaml +40 -0
  94. package/dist/clis/linux-do/search.yaml +45 -0
  95. package/dist/clis/linux-do/topic.yaml +38 -0
  96. package/dist/clis/neteasemusic/like.d.ts +1 -0
  97. package/dist/clis/neteasemusic/like.js +25 -0
  98. package/dist/clis/neteasemusic/lyrics.d.ts +1 -0
  99. package/dist/clis/neteasemusic/lyrics.js +47 -0
  100. package/dist/clis/neteasemusic/next.d.ts +1 -0
  101. package/dist/clis/neteasemusic/next.js +26 -0
  102. package/dist/clis/neteasemusic/play.d.ts +1 -0
  103. package/dist/clis/neteasemusic/play.js +26 -0
  104. package/dist/clis/neteasemusic/playing.d.ts +1 -0
  105. package/dist/clis/neteasemusic/playing.js +59 -0
  106. package/dist/clis/neteasemusic/playlist.d.ts +1 -0
  107. package/dist/clis/neteasemusic/playlist.js +46 -0
  108. package/dist/clis/neteasemusic/prev.d.ts +1 -0
  109. package/dist/clis/neteasemusic/prev.js +25 -0
  110. package/dist/clis/neteasemusic/search.d.ts +1 -0
  111. package/dist/clis/neteasemusic/search.js +52 -0
  112. package/dist/clis/neteasemusic/status.d.ts +1 -0
  113. package/dist/clis/neteasemusic/status.js +16 -0
  114. package/dist/clis/neteasemusic/volume.d.ts +1 -0
  115. package/dist/clis/neteasemusic/volume.js +54 -0
  116. package/dist/clis/notion/export.d.ts +1 -0
  117. package/dist/clis/notion/export.js +31 -0
  118. package/dist/clis/notion/favorites.d.ts +1 -0
  119. package/dist/clis/notion/favorites.js +84 -0
  120. package/dist/clis/notion/new.d.ts +1 -0
  121. package/dist/clis/notion/new.js +34 -0
  122. package/dist/clis/notion/read.d.ts +1 -0
  123. package/dist/clis/notion/read.js +30 -0
  124. package/dist/clis/notion/search.d.ts +1 -0
  125. package/dist/clis/notion/search.js +46 -0
  126. package/dist/clis/notion/sidebar.d.ts +1 -0
  127. package/dist/clis/notion/sidebar.js +41 -0
  128. package/dist/clis/notion/status.d.ts +1 -0
  129. package/dist/clis/notion/status.js +16 -0
  130. package/dist/clis/notion/write.d.ts +1 -0
  131. package/dist/clis/notion/write.js +40 -0
  132. package/dist/clis/twitter/download.d.ts +8 -0
  133. package/dist/clis/twitter/download.js +204 -0
  134. package/dist/clis/wechat/chats.d.ts +1 -0
  135. package/dist/clis/wechat/chats.js +28 -0
  136. package/dist/clis/wechat/contacts.d.ts +1 -0
  137. package/dist/clis/wechat/contacts.js +28 -0
  138. package/dist/clis/wechat/read.d.ts +1 -0
  139. package/dist/clis/wechat/read.js +58 -0
  140. package/dist/clis/wechat/search.d.ts +1 -0
  141. package/dist/clis/wechat/search.js +31 -0
  142. package/dist/clis/wechat/send.d.ts +1 -0
  143. package/dist/clis/wechat/send.js +42 -0
  144. package/dist/clis/wechat/status.d.ts +1 -0
  145. package/dist/clis/wechat/status.js +29 -0
  146. package/dist/clis/xiaohongshu/creator-note-detail.d.ts +10 -0
  147. package/dist/clis/xiaohongshu/creator-note-detail.js +88 -0
  148. package/dist/clis/xiaohongshu/creator-notes.d.ts +11 -0
  149. package/dist/clis/xiaohongshu/creator-notes.js +109 -0
  150. package/dist/clis/xiaohongshu/creator-profile.d.ts +10 -0
  151. package/dist/clis/xiaohongshu/creator-profile.js +54 -0
  152. package/dist/clis/xiaohongshu/creator-stats.d.ts +10 -0
  153. package/dist/clis/xiaohongshu/creator-stats.js +74 -0
  154. package/dist/clis/xiaohongshu/download.d.ts +7 -0
  155. package/dist/clis/xiaohongshu/download.js +155 -0
  156. package/dist/clis/xiaohongshu/search.js +1 -1
  157. package/dist/clis/xiaohongshu/user-helpers.d.ts +15 -0
  158. package/dist/clis/xiaohongshu/user-helpers.js +67 -0
  159. package/dist/clis/xiaohongshu/user-helpers.test.d.ts +1 -0
  160. package/dist/clis/xiaohongshu/user-helpers.test.js +81 -0
  161. package/dist/clis/xiaohongshu/user.js +46 -29
  162. package/dist/clis/zhihu/download.d.ts +11 -0
  163. package/dist/clis/zhihu/download.js +186 -0
  164. package/dist/clis/zhihu/download.test.d.ts +1 -0
  165. package/dist/clis/zhihu/download.test.js +10 -0
  166. package/dist/daemon.d.ts +13 -0
  167. package/dist/daemon.js +187 -0
  168. package/dist/doctor.d.ts +27 -61
  169. package/dist/doctor.js +70 -601
  170. package/dist/doctor.test.js +30 -170
  171. package/dist/download/index.d.ts +79 -0
  172. package/dist/download/index.js +325 -0
  173. package/dist/download/progress.d.ts +36 -0
  174. package/dist/download/progress.js +111 -0
  175. package/dist/engine.test.js +15 -0
  176. package/dist/main.js +22 -28
  177. package/dist/pipeline/executor.test.js +1 -0
  178. package/dist/pipeline/registry.js +2 -0
  179. package/dist/pipeline/steps/browser.js +2 -2
  180. package/dist/pipeline/steps/download.d.ts +34 -0
  181. package/dist/pipeline/steps/download.js +251 -0
  182. package/dist/pipeline/steps/intercept.js +1 -2
  183. package/dist/pipeline/template.js +28 -0
  184. package/dist/setup.d.ts +6 -0
  185. package/dist/setup.js +46 -160
  186. package/dist/types.d.ts +6 -0
  187. package/extension/icons/icon-128.png +0 -0
  188. package/extension/icons/icon-16.png +0 -0
  189. package/extension/icons/icon-32.png +0 -0
  190. package/extension/icons/icon-48.png +0 -0
  191. package/extension/manifest.json +31 -0
  192. package/extension/package.json +16 -0
  193. package/extension/src/background.ts +293 -0
  194. package/extension/src/cdp.ts +125 -0
  195. package/extension/src/protocol.ts +57 -0
  196. package/extension/store-assets/screenshot-1280x800.png +0 -0
  197. package/extension/tsconfig.json +15 -0
  198. package/extension/vite.config.ts +18 -0
  199. package/package.json +8 -7
  200. package/scripts/test-site.mjs +70 -0
  201. package/src/browser/daemon-client.ts +113 -0
  202. package/src/browser/discover.ts +18 -216
  203. package/src/browser/errors.ts +30 -100
  204. package/src/browser/index.ts +6 -12
  205. package/src/browser/mcp.ts +78 -278
  206. package/src/browser/page.ts +222 -88
  207. package/src/browser.test.ts +3 -210
  208. package/src/build-manifest.test.ts +28 -0
  209. package/src/build-manifest.ts +147 -57
  210. package/src/clis/bilibili/download.ts +161 -0
  211. package/src/clis/chatgpt/README.md +1 -1
  212. package/src/clis/chatgpt/README.zh-CN.md +1 -1
  213. package/src/clis/chatwise/README.md +38 -0
  214. package/src/clis/chatwise/README.zh-CN.md +38 -0
  215. package/src/clis/chatwise/ask.ts +87 -0
  216. package/src/clis/chatwise/export.ts +51 -0
  217. package/src/clis/chatwise/history.ts +47 -0
  218. package/src/clis/chatwise/model.ts +87 -0
  219. package/src/clis/chatwise/new.ts +21 -0
  220. package/src/clis/chatwise/read.ts +42 -0
  221. package/src/clis/chatwise/screenshot.ts +33 -0
  222. package/src/clis/chatwise/send.ts +50 -0
  223. package/src/clis/chatwise/status.ts +25 -0
  224. package/src/clis/discord-app/README.md +28 -0
  225. package/src/clis/discord-app/README.zh-CN.md +28 -0
  226. package/src/clis/discord-app/channels.ts +48 -0
  227. package/src/clis/discord-app/members.ts +41 -0
  228. package/src/clis/discord-app/read.ts +49 -0
  229. package/src/clis/discord-app/search.ts +64 -0
  230. package/src/clis/discord-app/send.ts +32 -0
  231. package/src/clis/discord-app/servers.ts +39 -0
  232. package/src/clis/discord-app/status.ts +18 -0
  233. package/src/clis/feishu/README.md +20 -0
  234. package/src/clis/feishu/README.zh-CN.md +20 -0
  235. package/src/clis/feishu/new.ts +32 -0
  236. package/src/clis/feishu/read.ts +48 -0
  237. package/src/clis/feishu/search.ts +35 -0
  238. package/src/clis/feishu/send.ts +46 -0
  239. package/src/clis/feishu/status.ts +34 -0
  240. package/src/clis/grok/ask.ts +90 -0
  241. package/src/clis/grok/debug.ts +49 -0
  242. package/src/clis/jimeng/generate.yaml +84 -0
  243. package/src/clis/jimeng/history.yaml +47 -0
  244. package/src/clis/linux-do/categories.yaml +41 -0
  245. package/src/clis/linux-do/category.yaml +49 -0
  246. package/src/clis/linux-do/hot.yaml +50 -0
  247. package/src/clis/linux-do/latest.yaml +40 -0
  248. package/src/clis/linux-do/search.yaml +45 -0
  249. package/src/clis/linux-do/topic.yaml +38 -0
  250. package/src/clis/neteasemusic/README.md +31 -0
  251. package/src/clis/neteasemusic/README.zh-CN.md +31 -0
  252. package/src/clis/neteasemusic/like.ts +28 -0
  253. package/src/clis/neteasemusic/lyrics.ts +53 -0
  254. package/src/clis/neteasemusic/next.ts +30 -0
  255. package/src/clis/neteasemusic/play.ts +30 -0
  256. package/src/clis/neteasemusic/playing.ts +62 -0
  257. package/src/clis/neteasemusic/playlist.ts +51 -0
  258. package/src/clis/neteasemusic/prev.ts +29 -0
  259. package/src/clis/neteasemusic/search.ts +58 -0
  260. package/src/clis/neteasemusic/status.ts +18 -0
  261. package/src/clis/neteasemusic/volume.ts +61 -0
  262. package/src/clis/notion/README.md +29 -0
  263. package/src/clis/notion/README.zh-CN.md +29 -0
  264. package/src/clis/notion/export.ts +36 -0
  265. package/src/clis/notion/favorites.ts +87 -0
  266. package/src/clis/notion/new.ts +39 -0
  267. package/src/clis/notion/read.ts +33 -0
  268. package/src/clis/notion/search.ts +54 -0
  269. package/src/clis/notion/sidebar.ts +44 -0
  270. package/src/clis/notion/status.ts +18 -0
  271. package/src/clis/notion/write.ts +45 -0
  272. package/src/clis/twitter/download.ts +227 -0
  273. package/src/clis/wechat/README.md +28 -0
  274. package/src/clis/wechat/README.zh-CN.md +28 -0
  275. package/src/clis/wechat/chats.ts +33 -0
  276. package/src/clis/wechat/contacts.ts +33 -0
  277. package/src/clis/wechat/read.ts +72 -0
  278. package/src/clis/wechat/search.ts +36 -0
  279. package/src/clis/wechat/send.ts +49 -0
  280. package/src/clis/wechat/status.ts +35 -0
  281. package/src/clis/xiaohongshu/creator-note-detail.ts +95 -0
  282. package/src/clis/xiaohongshu/creator-notes.ts +116 -0
  283. package/src/clis/xiaohongshu/creator-profile.ts +60 -0
  284. package/src/clis/xiaohongshu/creator-stats.ts +81 -0
  285. package/src/clis/xiaohongshu/download.ts +173 -0
  286. package/src/clis/xiaohongshu/search.ts +1 -1
  287. package/src/clis/xiaohongshu/user-helpers.test.ts +106 -0
  288. package/src/clis/xiaohongshu/user-helpers.ts +85 -0
  289. package/src/clis/xiaohongshu/user.ts +52 -32
  290. package/src/clis/zhihu/download.test.ts +12 -0
  291. package/src/clis/zhihu/download.ts +223 -0
  292. package/src/daemon.ts +217 -0
  293. package/src/doctor.test.ts +32 -193
  294. package/src/doctor.ts +74 -668
  295. package/src/download/index.ts +395 -0
  296. package/src/download/progress.ts +125 -0
  297. package/src/engine.test.ts +17 -0
  298. package/src/main.ts +18 -26
  299. package/src/pipeline/executor.test.ts +1 -0
  300. package/src/pipeline/registry.ts +2 -0
  301. package/src/pipeline/steps/browser.ts +2 -2
  302. package/src/pipeline/steps/download.ts +310 -0
  303. package/src/pipeline/steps/intercept.ts +1 -2
  304. package/src/pipeline/template.ts +26 -0
  305. package/src/setup.ts +47 -183
  306. package/src/types.ts +1 -0
  307. package/tests/e2e/browser-auth.test.ts +25 -0
@@ -149,7 +149,12 @@
149
149
  "type": "str",
150
150
  "default": "all",
151
151
  "required": false,
152
- "help": "Filter: all, call, or put"
152
+ "help": "Filter: all, call, or put",
153
+ "choices": [
154
+ "all",
155
+ "call",
156
+ "put"
157
+ ]
153
158
  },
154
159
  {
155
160
  "name": "limit",
@@ -237,7 +242,11 @@
237
242
  "type": "str",
238
243
  "default": "Call",
239
244
  "required": false,
240
- "help": "Option type: Call or Put"
245
+ "help": "Option type: Call or Put",
246
+ "choices": [
247
+ "Call",
248
+ "Put"
249
+ ]
241
250
  },
242
251
  {
243
252
  "name": "limit",
@@ -325,6 +334,44 @@
325
334
  "url"
326
335
  ]
327
336
  },
337
+ {
338
+ "site": "bilibili",
339
+ "name": "download",
340
+ "description": "下载B站视频(需要 yt-dlp)",
341
+ "strategy": "cookie",
342
+ "browser": true,
343
+ "args": [
344
+ {
345
+ "name": "bvid",
346
+ "type": "str",
347
+ "required": true,
348
+ "help": "Video BV ID (e.g., BV1xxx)"
349
+ },
350
+ {
351
+ "name": "output",
352
+ "type": "str",
353
+ "default": "./bilibili-downloads",
354
+ "required": false,
355
+ "help": "Output directory"
356
+ },
357
+ {
358
+ "name": "quality",
359
+ "type": "str",
360
+ "default": "best",
361
+ "required": false,
362
+ "help": "Video quality (best, 1080p, 720p, 480p)"
363
+ }
364
+ ],
365
+ "type": "ts",
366
+ "modulePath": "bilibili/download.js",
367
+ "domain": "www.bilibili.com",
368
+ "columns": [
369
+ "bvid",
370
+ "title",
371
+ "status",
372
+ "size"
373
+ ]
374
+ },
328
375
  {
329
376
  "site": "bilibili",
330
377
  "name": "dynamic",
@@ -905,6 +952,190 @@
905
952
  "Status"
906
953
  ]
907
954
  },
955
+ {
956
+ "site": "chatwise",
957
+ "name": "ask",
958
+ "description": "Send a prompt and wait for the AI response (send + wait + read)",
959
+ "strategy": "ui",
960
+ "browser": true,
961
+ "args": [
962
+ {
963
+ "name": "text",
964
+ "type": "str",
965
+ "required": true,
966
+ "positional": true,
967
+ "help": "Prompt to send"
968
+ },
969
+ {
970
+ "name": "timeout",
971
+ "type": "str",
972
+ "default": "30)",
973
+ "required": false,
974
+ "help": "Max seconds to wait (default: 30)"
975
+ }
976
+ ],
977
+ "type": "ts",
978
+ "modulePath": "chatwise/ask.js",
979
+ "domain": "localhost",
980
+ "columns": [
981
+ "Role",
982
+ "Text"
983
+ ]
984
+ },
985
+ {
986
+ "site": "chatwise",
987
+ "name": "export",
988
+ "description": "Export the current ChatWise conversation to a Markdown file",
989
+ "strategy": "ui",
990
+ "browser": true,
991
+ "args": [
992
+ {
993
+ "name": "output",
994
+ "type": "str",
995
+ "default": "/tmp/chatwise-export.md)",
996
+ "required": false,
997
+ "positional": true,
998
+ "help": "Output file (default: /tmp/chatwise-export.md)"
999
+ }
1000
+ ],
1001
+ "type": "ts",
1002
+ "modulePath": "chatwise/export.js",
1003
+ "domain": "localhost",
1004
+ "columns": [
1005
+ "Status",
1006
+ "File",
1007
+ "Messages"
1008
+ ]
1009
+ },
1010
+ {
1011
+ "site": "chatwise",
1012
+ "name": "history",
1013
+ "description": "List conversation history in ChatWise sidebar",
1014
+ "strategy": "ui",
1015
+ "browser": true,
1016
+ "args": [],
1017
+ "type": "ts",
1018
+ "modulePath": "chatwise/history.js",
1019
+ "domain": "localhost",
1020
+ "columns": [
1021
+ "Index",
1022
+ "Title"
1023
+ ]
1024
+ },
1025
+ {
1026
+ "site": "chatwise",
1027
+ "name": "model",
1028
+ "description": "Get or switch the active AI model in ChatWise",
1029
+ "strategy": "ui",
1030
+ "browser": true,
1031
+ "args": [
1032
+ {
1033
+ "name": "model_name",
1034
+ "type": "str",
1035
+ "required": false,
1036
+ "positional": true,
1037
+ "help": "Model to switch to (e.g. gpt-4, claude-3)"
1038
+ }
1039
+ ],
1040
+ "type": "ts",
1041
+ "modulePath": "chatwise/model.js",
1042
+ "domain": "localhost",
1043
+ "columns": [
1044
+ "Status",
1045
+ "Model"
1046
+ ]
1047
+ },
1048
+ {
1049
+ "site": "chatwise",
1050
+ "name": "new",
1051
+ "description": "Start a new conversation in ChatWise",
1052
+ "strategy": "ui",
1053
+ "browser": true,
1054
+ "args": [],
1055
+ "type": "ts",
1056
+ "modulePath": "chatwise/new.js",
1057
+ "domain": "localhost",
1058
+ "columns": [
1059
+ "Status"
1060
+ ]
1061
+ },
1062
+ {
1063
+ "site": "chatwise",
1064
+ "name": "read",
1065
+ "description": "Read the current ChatWise conversation history",
1066
+ "strategy": "ui",
1067
+ "browser": true,
1068
+ "args": [],
1069
+ "type": "ts",
1070
+ "modulePath": "chatwise/read.js",
1071
+ "domain": "localhost",
1072
+ "columns": [
1073
+ "Content"
1074
+ ]
1075
+ },
1076
+ {
1077
+ "site": "chatwise",
1078
+ "name": "screenshot",
1079
+ "description": "Capture a snapshot of the current ChatWise window (DOM + Accessibility tree)",
1080
+ "strategy": "ui",
1081
+ "browser": true,
1082
+ "args": [
1083
+ {
1084
+ "name": "output",
1085
+ "type": "str",
1086
+ "default": "/tmp/chatwise-snapshot)",
1087
+ "required": false,
1088
+ "positional": true,
1089
+ "help": "Output file path (default: /tmp/chatwise-snapshot)"
1090
+ }
1091
+ ],
1092
+ "type": "ts",
1093
+ "modulePath": "chatwise/screenshot.js",
1094
+ "domain": "localhost",
1095
+ "columns": [
1096
+ "Status",
1097
+ "File"
1098
+ ]
1099
+ },
1100
+ {
1101
+ "site": "chatwise",
1102
+ "name": "send",
1103
+ "description": "Send a message to the active ChatWise conversation",
1104
+ "strategy": "ui",
1105
+ "browser": true,
1106
+ "args": [
1107
+ {
1108
+ "name": "text",
1109
+ "type": "str",
1110
+ "required": true,
1111
+ "positional": true,
1112
+ "help": "Message to send"
1113
+ }
1114
+ ],
1115
+ "type": "ts",
1116
+ "modulePath": "chatwise/send.js",
1117
+ "domain": "localhost",
1118
+ "columns": [
1119
+ "Status",
1120
+ "InjectedText"
1121
+ ]
1122
+ },
1123
+ {
1124
+ "site": "chatwise",
1125
+ "name": "status",
1126
+ "description": "Check active CDP connection to ChatWise Desktop",
1127
+ "strategy": "ui",
1128
+ "browser": true,
1129
+ "args": [],
1130
+ "type": "ts",
1131
+ "modulePath": "chatwise/status.js",
1132
+ "domain": "localhost",
1133
+ "columns": [
1134
+ "Status",
1135
+ "Url",
1136
+ "Title"
1137
+ ]
1138
+ },
908
1139
  {
909
1140
  "site": "codex",
910
1141
  "name": "ask",
@@ -1314,7 +1545,7 @@
1314
1545
  "default": "/tmp/${site",
1315
1546
  "required": false,
1316
1547
  "positional": true,
1317
- "help": ""
1548
+ "help": "Output file (default: /tmp/${site}-export.md)"
1318
1549
  }
1319
1550
  ],
1320
1551
  "type": "ts",
@@ -1420,7 +1651,7 @@
1420
1651
  "default": "/tmp/${site",
1421
1652
  "required": false,
1422
1653
  "positional": true,
1423
- "help": ""
1654
+ "help": "Output file path (default: /tmp/${site}-snapshot.txt)"
1424
1655
  }
1425
1656
  ],
1426
1657
  "type": "ts",
@@ -1471,34 +1702,303 @@
1471
1702
  ]
1472
1703
  },
1473
1704
  {
1474
- "site": "hackernews",
1475
- "name": "top",
1476
- "description": "Hacker News top stories",
1477
- "domain": "news.ycombinator.com",
1478
- "strategy": "public",
1479
- "browser": false,
1705
+ "site": "discord-app",
1706
+ "name": "channels",
1707
+ "description": "List channels in the current Discord server",
1708
+ "strategy": "ui",
1709
+ "browser": true,
1710
+ "args": [],
1711
+ "type": "ts",
1712
+ "modulePath": "discord-app/channels.js",
1713
+ "domain": "localhost",
1714
+ "columns": [
1715
+ "Index",
1716
+ "Channel",
1717
+ "Type"
1718
+ ]
1719
+ },
1720
+ {
1721
+ "site": "discord-app",
1722
+ "name": "members",
1723
+ "description": "List online members in the current Discord channel",
1724
+ "strategy": "ui",
1725
+ "browser": true,
1726
+ "args": [],
1727
+ "type": "ts",
1728
+ "modulePath": "discord-app/members.js",
1729
+ "domain": "localhost",
1730
+ "columns": [
1731
+ "Index",
1732
+ "Name",
1733
+ "Status"
1734
+ ]
1735
+ },
1736
+ {
1737
+ "site": "discord-app",
1738
+ "name": "read",
1739
+ "description": "Read recent messages from the active Discord channel",
1740
+ "strategy": "ui",
1741
+ "browser": true,
1480
1742
  "args": [
1481
1743
  {
1482
- "name": "limit",
1483
- "type": "int",
1484
- "default": 20,
1744
+ "name": "count",
1745
+ "type": "str",
1746
+ "default": "20)",
1485
1747
  "required": false,
1486
- "help": "Number of stories"
1748
+ "help": "Number of messages to read (default: 20)"
1487
1749
  }
1488
1750
  ],
1751
+ "type": "ts",
1752
+ "modulePath": "discord-app/read.js",
1753
+ "domain": "localhost",
1489
1754
  "columns": [
1490
- "rank",
1491
- "title",
1492
- "score",
1493
- "author",
1494
- "comments"
1755
+ "Author",
1756
+ "Time",
1757
+ "Message"
1758
+ ]
1759
+ },
1760
+ {
1761
+ "site": "discord-app",
1762
+ "name": "search",
1763
+ "description": "Search messages in the current Discord server/channel (Cmd+F)",
1764
+ "strategy": "ui",
1765
+ "browser": true,
1766
+ "args": [
1767
+ {
1768
+ "name": "query",
1769
+ "type": "str",
1770
+ "required": true,
1771
+ "positional": true,
1772
+ "help": "Search query"
1773
+ }
1495
1774
  ],
1496
- "pipeline": [
1775
+ "type": "ts",
1776
+ "modulePath": "discord-app/search.js",
1777
+ "domain": "localhost",
1778
+ "columns": [
1779
+ "Index",
1780
+ "Author",
1781
+ "Message"
1782
+ ]
1783
+ },
1784
+ {
1785
+ "site": "discord-app",
1786
+ "name": "send",
1787
+ "description": "Send a message in the active Discord channel",
1788
+ "strategy": "ui",
1789
+ "browser": true,
1790
+ "args": [
1497
1791
  {
1498
- "fetch": {
1499
- "url": "https://hacker-news.firebaseio.com/v0/topstories.json"
1500
- }
1501
- },
1792
+ "name": "text",
1793
+ "type": "str",
1794
+ "required": true,
1795
+ "positional": true,
1796
+ "help": "Message to send"
1797
+ }
1798
+ ],
1799
+ "type": "ts",
1800
+ "modulePath": "discord-app/send.js",
1801
+ "domain": "localhost",
1802
+ "columns": [
1803
+ "Status"
1804
+ ]
1805
+ },
1806
+ {
1807
+ "site": "discord-app",
1808
+ "name": "servers",
1809
+ "description": "List all Discord servers (guilds) in the sidebar",
1810
+ "strategy": "ui",
1811
+ "browser": true,
1812
+ "args": [],
1813
+ "type": "ts",
1814
+ "modulePath": "discord-app/servers.js",
1815
+ "domain": "localhost",
1816
+ "columns": [
1817
+ "Index",
1818
+ "Server"
1819
+ ]
1820
+ },
1821
+ {
1822
+ "site": "discord-app",
1823
+ "name": "status",
1824
+ "description": "Check active CDP connection to Discord Desktop",
1825
+ "strategy": "ui",
1826
+ "browser": true,
1827
+ "args": [],
1828
+ "type": "ts",
1829
+ "modulePath": "discord-app/status.js",
1830
+ "domain": "localhost",
1831
+ "columns": [
1832
+ "Status",
1833
+ "Url",
1834
+ "Title"
1835
+ ]
1836
+ },
1837
+ {
1838
+ "site": "feishu",
1839
+ "name": "new",
1840
+ "description": "Create a new message or document in Feishu",
1841
+ "strategy": "public",
1842
+ "browser": false,
1843
+ "args": [],
1844
+ "type": "ts",
1845
+ "modulePath": "feishu/new.js",
1846
+ "domain": "localhost",
1847
+ "columns": [
1848
+ "Status"
1849
+ ]
1850
+ },
1851
+ {
1852
+ "site": "feishu",
1853
+ "name": "read",
1854
+ "description": "Read the current chat content by selecting all and copying",
1855
+ "strategy": "public",
1856
+ "browser": false,
1857
+ "args": [],
1858
+ "type": "ts",
1859
+ "modulePath": "feishu/read.js",
1860
+ "domain": "localhost",
1861
+ "columns": [
1862
+ "Content"
1863
+ ]
1864
+ },
1865
+ {
1866
+ "site": "feishu",
1867
+ "name": "search",
1868
+ "description": "Open Feishu global search and type a query (Cmd+K)",
1869
+ "strategy": "public",
1870
+ "browser": false,
1871
+ "args": [
1872
+ {
1873
+ "name": "query",
1874
+ "type": "str",
1875
+ "required": true,
1876
+ "positional": true,
1877
+ "help": "Search query"
1878
+ }
1879
+ ],
1880
+ "type": "ts",
1881
+ "modulePath": "feishu/search.js",
1882
+ "domain": "localhost",
1883
+ "columns": [
1884
+ "Status"
1885
+ ]
1886
+ },
1887
+ {
1888
+ "site": "feishu",
1889
+ "name": "send",
1890
+ "description": "Send a message in the active Feishu (Lark) conversation",
1891
+ "strategy": "public",
1892
+ "browser": false,
1893
+ "args": [
1894
+ {
1895
+ "name": "text",
1896
+ "type": "str",
1897
+ "required": true,
1898
+ "positional": true,
1899
+ "help": "Message to send"
1900
+ }
1901
+ ],
1902
+ "type": "ts",
1903
+ "modulePath": "feishu/send.js",
1904
+ "domain": "localhost",
1905
+ "columns": [
1906
+ "Status"
1907
+ ]
1908
+ },
1909
+ {
1910
+ "site": "feishu",
1911
+ "name": "status",
1912
+ "description": "Check if Feishu (Lark) Desktop is running on macOS",
1913
+ "strategy": "public",
1914
+ "browser": false,
1915
+ "args": [],
1916
+ "type": "ts",
1917
+ "modulePath": "feishu/status.js",
1918
+ "domain": "localhost",
1919
+ "columns": [
1920
+ "Status",
1921
+ "Detail"
1922
+ ]
1923
+ },
1924
+ {
1925
+ "site": "grok",
1926
+ "name": "ask",
1927
+ "description": "Send a message to Grok and get response",
1928
+ "strategy": "cookie",
1929
+ "browser": true,
1930
+ "args": [
1931
+ {
1932
+ "name": "prompt",
1933
+ "type": "string",
1934
+ "required": true,
1935
+ "help": ""
1936
+ },
1937
+ {
1938
+ "name": "timeout",
1939
+ "type": "int",
1940
+ "default": 120,
1941
+ "required": false,
1942
+ "help": ""
1943
+ },
1944
+ {
1945
+ "name": "new",
1946
+ "type": "boolean",
1947
+ "default": false,
1948
+ "required": false,
1949
+ "help": ""
1950
+ }
1951
+ ],
1952
+ "type": "ts",
1953
+ "modulePath": "grok/ask.js",
1954
+ "domain": "grok.com",
1955
+ "columns": [
1956
+ "response"
1957
+ ]
1958
+ },
1959
+ {
1960
+ "site": "grok",
1961
+ "name": "debug",
1962
+ "description": "Debug grok page structure",
1963
+ "strategy": "cookie",
1964
+ "browser": true,
1965
+ "args": [],
1966
+ "type": "ts",
1967
+ "modulePath": "grok/debug.js",
1968
+ "domain": "grok.com",
1969
+ "columns": [
1970
+ "data"
1971
+ ]
1972
+ },
1973
+ {
1974
+ "site": "hackernews",
1975
+ "name": "top",
1976
+ "description": "Hacker News top stories",
1977
+ "domain": "news.ycombinator.com",
1978
+ "strategy": "public",
1979
+ "browser": false,
1980
+ "args": [
1981
+ {
1982
+ "name": "limit",
1983
+ "type": "int",
1984
+ "default": 20,
1985
+ "required": false,
1986
+ "help": "Number of stories"
1987
+ }
1988
+ ],
1989
+ "columns": [
1990
+ "rank",
1991
+ "title",
1992
+ "score",
1993
+ "author",
1994
+ "comments"
1995
+ ],
1996
+ "pipeline": [
1997
+ {
1998
+ "fetch": {
1999
+ "url": "https://hacker-news.firebaseio.com/v0/topstories.json"
2000
+ }
2001
+ },
1502
2002
  {
1503
2003
  "limit": 30
1504
2004
  },
@@ -1528,6 +2028,110 @@
1528
2028
  ],
1529
2029
  "type": "yaml"
1530
2030
  },
2031
+ {
2032
+ "site": "jimeng",
2033
+ "name": "generate",
2034
+ "description": "即梦AI 文生图 — 输入 prompt 生成图片",
2035
+ "domain": "jimeng.jianying.com",
2036
+ "strategy": "cookie",
2037
+ "browser": true,
2038
+ "args": [
2039
+ {
2040
+ "name": "prompt",
2041
+ "type": "string",
2042
+ "required": true,
2043
+ "help": "图片描述 prompt"
2044
+ },
2045
+ {
2046
+ "name": "model",
2047
+ "type": "string",
2048
+ "default": "high_aes_general_v50",
2049
+ "required": false,
2050
+ "help": "模型: high_aes_general_v50 (5.0 Lite), high_aes_general_v42 (4.6), high_aes_general_v40 (4.0)"
2051
+ },
2052
+ {
2053
+ "name": "wait",
2054
+ "type": "int",
2055
+ "default": 40,
2056
+ "required": false,
2057
+ "help": "等待生成完成的秒数"
2058
+ }
2059
+ ],
2060
+ "columns": [
2061
+ "status",
2062
+ "prompt",
2063
+ "image_count",
2064
+ "image_urls"
2065
+ ],
2066
+ "pipeline": [
2067
+ {
2068
+ "navigate": "https://jimeng.jianying.com/ai-tool/generate?type=image&workspace=0"
2069
+ },
2070
+ {
2071
+ "wait": 3
2072
+ },
2073
+ {
2074
+ "evaluate": "(async () => {\n const prompt = ${{ args.prompt | json }};\n const waitSec = ${{ args.wait }};\n \n // Step 1: Count existing images before generation\n const beforeImgs = document.querySelectorAll('img[src*=\"dreamina-sign\"], img[src*=\"tb4s082cfz\"]').length;\n \n // Step 2: Clear and set prompt\n const editors = document.querySelectorAll('[contenteditable=\"true\"]');\n const editor = editors[0];\n if (!editor) return [{ status: 'failed', prompt: prompt, image_count: 0, image_urls: 'Editor not found' }];\n \n editor.focus();\n await new Promise(r => setTimeout(r, 200));\n document.execCommand('selectAll');\n await new Promise(r => setTimeout(r, 100));\n document.execCommand('delete');\n await new Promise(r => setTimeout(r, 200));\n document.execCommand('insertText', false, prompt);\n await new Promise(r => setTimeout(r, 500));\n \n // Step 3: Click generate\n const btn = document.querySelector('.lv-btn.lv-btn-primary[class*=\"circle\"]');\n if (!btn) return [{ status: 'failed', prompt: prompt, image_count: 0, image_urls: 'Generate button not found' }];\n btn.click();\n \n // Step 4: Wait for new images to appear\n let newImgs = [];\n for (let i = 0; i < waitSec; i++) {\n await new Promise(r => setTimeout(r, 1000));\n const allImgs = document.querySelectorAll('img[src*=\"dreamina-sign\"], img[src*=\"tb4s082cfz\"]');\n if (allImgs.length > beforeImgs) {\n // New images appeared — generation complete\n newImgs = Array.from(allImgs).slice(0, allImgs.length - beforeImgs);\n break;\n }\n }\n \n if (newImgs.length === 0) {\n return [{ status: 'timeout', prompt: prompt, image_count: 0, image_urls: 'Generation may still be in progress' }];\n }\n \n // Step 5: Extract image URLs (use thumbnail URLs which are accessible)\n const urls = newImgs.map(img => img.src);\n \n return [{ \n status: 'success', \n prompt: prompt.substring(0, 80), \n image_count: urls.length, \n image_urls: urls.join('\\n')\n }];\n})()\n"
2075
+ },
2076
+ {
2077
+ "map": {
2078
+ "status": "${{ item.status }}",
2079
+ "prompt": "${{ item.prompt }}",
2080
+ "image_count": "${{ item.image_count }}",
2081
+ "image_urls": "${{ item.image_urls }}"
2082
+ }
2083
+ }
2084
+ ],
2085
+ "type": "yaml"
2086
+ },
2087
+ {
2088
+ "site": "jimeng",
2089
+ "name": "history",
2090
+ "description": "即梦AI 查看最近生成的作品",
2091
+ "domain": "jimeng.jianying.com",
2092
+ "strategy": "cookie",
2093
+ "browser": true,
2094
+ "args": [
2095
+ {
2096
+ "name": "limit",
2097
+ "type": "int",
2098
+ "default": 5,
2099
+ "required": false,
2100
+ "help": ""
2101
+ }
2102
+ ],
2103
+ "columns": [
2104
+ "prompt",
2105
+ "model",
2106
+ "status",
2107
+ "image_url",
2108
+ "created_at"
2109
+ ],
2110
+ "pipeline": [
2111
+ {
2112
+ "navigate": "https://jimeng.jianying.com/ai-tool/generate?type=image&workspace=0"
2113
+ },
2114
+ {
2115
+ "wait": 3
2116
+ },
2117
+ {
2118
+ "evaluate": "(async () => {\n const limit = ${{ args.limit }};\n const res = await fetch('/mweb/v1/get_history?aid=513695&device_platform=web&region=cn&da_version=3.3.11&web_version=7.5.0&aigc_features=app_lip_sync', {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ cursor: '', count: limit, need_page_item: true, need_aigc_data: true, aigc_mode_list: ['workbench'] })\n });\n const data = await res.json();\n const items = data?.data?.history_list || [];\n return items.slice(0, limit).map(item => {\n const params = item.aigc_image_params?.text2image_params || {};\n const images = item.image?.large_images || [];\n return {\n prompt: params.prompt || item.common_attr?.title || 'N/A',\n model: params.model_config?.model_name || 'unknown',\n status: item.common_attr?.status === 102 ? 'completed' : 'pending',\n image_url: images[0]?.image_url || '',\n created_at: new Date((item.common_attr?.create_time || 0) * 1000).toLocaleString('zh-CN'),\n };\n });\n})()\n"
2119
+ },
2120
+ {
2121
+ "map": {
2122
+ "prompt": "${{ item.prompt }}",
2123
+ "model": "${{ item.model }}",
2124
+ "status": "${{ item.status }}",
2125
+ "image_url": "${{ item.image_url }}",
2126
+ "created_at": "${{ item.created_at }}"
2127
+ }
2128
+ },
2129
+ {
2130
+ "limit": "${{ args.limit }}"
2131
+ }
2132
+ ],
2133
+ "type": "yaml"
2134
+ },
1531
2135
  {
1532
2136
  "site": "linkedin",
1533
2137
  "name": "search",
@@ -1612,6 +2216,624 @@
1612
2216
  "url"
1613
2217
  ]
1614
2218
  },
2219
+ {
2220
+ "site": "linux-do",
2221
+ "name": "categories",
2222
+ "description": "linux.do 分类列表",
2223
+ "domain": "linux.do",
2224
+ "strategy": "cookie",
2225
+ "browser": true,
2226
+ "args": [
2227
+ {
2228
+ "name": "limit",
2229
+ "type": "int",
2230
+ "default": 20,
2231
+ "required": false,
2232
+ "help": "Number of categories"
2233
+ }
2234
+ ],
2235
+ "columns": [
2236
+ "name",
2237
+ "slug",
2238
+ "id",
2239
+ "topics",
2240
+ "description"
2241
+ ],
2242
+ "pipeline": [
2243
+ {
2244
+ "navigate": "https://linux.do"
2245
+ },
2246
+ {
2247
+ "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"
2248
+ },
2249
+ {
2250
+ "map": {
2251
+ "name": "${{ item.name }}",
2252
+ "slug": "${{ item.slug }}",
2253
+ "id": "${{ item.id }}",
2254
+ "topics": "${{ item.topics }}",
2255
+ "description": "${{ item.description }}"
2256
+ }
2257
+ },
2258
+ {
2259
+ "limit": "${{ args.limit }}"
2260
+ }
2261
+ ],
2262
+ "type": "yaml"
2263
+ },
2264
+ {
2265
+ "site": "linux-do",
2266
+ "name": "category",
2267
+ "description": "linux.do 分类内话题",
2268
+ "domain": "linux.do",
2269
+ "strategy": "cookie",
2270
+ "browser": true,
2271
+ "args": [
2272
+ {
2273
+ "name": "slug",
2274
+ "type": "str",
2275
+ "required": true,
2276
+ "help": "Category slug (use 'categories' command to find)"
2277
+ },
2278
+ {
2279
+ "name": "id",
2280
+ "type": "int",
2281
+ "required": true,
2282
+ "help": "Category ID (use 'categories' command to find)"
2283
+ },
2284
+ {
2285
+ "name": "limit",
2286
+ "type": "int",
2287
+ "default": 20,
2288
+ "required": false,
2289
+ "help": "Number of topics"
2290
+ }
2291
+ ],
2292
+ "columns": [
2293
+ "rank",
2294
+ "title",
2295
+ "replies",
2296
+ "views",
2297
+ "likes"
2298
+ ],
2299
+ "pipeline": [
2300
+ {
2301
+ "navigate": "https://linux.do"
2302
+ },
2303
+ {
2304
+ "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"
2305
+ },
2306
+ {
2307
+ "map": {
2308
+ "rank": "${{ index + 1 }}",
2309
+ "title": "${{ item.title }}",
2310
+ "replies": "${{ item.replies }}",
2311
+ "views": "${{ item.views }}",
2312
+ "likes": "${{ item.likes }}"
2313
+ }
2314
+ },
2315
+ {
2316
+ "limit": "${{ args.limit }}"
2317
+ }
2318
+ ],
2319
+ "type": "yaml"
2320
+ },
2321
+ {
2322
+ "site": "linux-do",
2323
+ "name": "hot",
2324
+ "description": "linux.do 热门话题",
2325
+ "domain": "linux.do",
2326
+ "strategy": "cookie",
2327
+ "browser": true,
2328
+ "args": [
2329
+ {
2330
+ "name": "limit",
2331
+ "type": "int",
2332
+ "default": 20,
2333
+ "required": false,
2334
+ "help": "Number of topics"
2335
+ },
2336
+ {
2337
+ "name": "period",
2338
+ "type": "str",
2339
+ "default": "weekly",
2340
+ "required": false,
2341
+ "help": "Time period",
2342
+ "choices": [
2343
+ "all",
2344
+ "daily",
2345
+ "weekly",
2346
+ "monthly",
2347
+ "yearly"
2348
+ ]
2349
+ }
2350
+ ],
2351
+ "columns": [
2352
+ "rank",
2353
+ "title",
2354
+ "replies",
2355
+ "views",
2356
+ "likes",
2357
+ "category"
2358
+ ],
2359
+ "pipeline": [
2360
+ {
2361
+ "navigate": "https://linux.do"
2362
+ },
2363
+ {
2364
+ "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"
2365
+ },
2366
+ {
2367
+ "map": {
2368
+ "rank": "${{ index + 1 }}",
2369
+ "title": "${{ item.title }}",
2370
+ "replies": "${{ item.replies }}",
2371
+ "views": "${{ item.views }}",
2372
+ "likes": "${{ item.likes }}",
2373
+ "category": "${{ item.category }}"
2374
+ }
2375
+ },
2376
+ {
2377
+ "limit": "${{ args.limit }}"
2378
+ }
2379
+ ],
2380
+ "type": "yaml"
2381
+ },
2382
+ {
2383
+ "site": "linux-do",
2384
+ "name": "latest",
2385
+ "description": "linux.do 最新话题",
2386
+ "domain": "linux.do",
2387
+ "strategy": "cookie",
2388
+ "browser": true,
2389
+ "args": [
2390
+ {
2391
+ "name": "limit",
2392
+ "type": "int",
2393
+ "default": 20,
2394
+ "required": false,
2395
+ "help": "Number of topics"
2396
+ }
2397
+ ],
2398
+ "columns": [
2399
+ "rank",
2400
+ "title",
2401
+ "replies",
2402
+ "views",
2403
+ "likes"
2404
+ ],
2405
+ "pipeline": [
2406
+ {
2407
+ "navigate": "https://linux.do"
2408
+ },
2409
+ {
2410
+ "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"
2411
+ },
2412
+ {
2413
+ "map": {
2414
+ "rank": "${{ index + 1 }}",
2415
+ "title": "${{ item.title }}",
2416
+ "replies": "${{ item.replies }}",
2417
+ "views": "${{ item.views }}",
2418
+ "likes": "${{ item.likes }}"
2419
+ }
2420
+ },
2421
+ {
2422
+ "limit": "${{ args.limit }}"
2423
+ }
2424
+ ],
2425
+ "type": "yaml"
2426
+ },
2427
+ {
2428
+ "site": "linux-do",
2429
+ "name": "search",
2430
+ "description": "搜索 linux.do",
2431
+ "domain": "linux.do",
2432
+ "strategy": "cookie",
2433
+ "browser": true,
2434
+ "args": [
2435
+ {
2436
+ "name": "keyword",
2437
+ "type": "str",
2438
+ "required": true,
2439
+ "help": "Search keyword"
2440
+ },
2441
+ {
2442
+ "name": "limit",
2443
+ "type": "int",
2444
+ "default": 20,
2445
+ "required": false,
2446
+ "help": "Number of results"
2447
+ }
2448
+ ],
2449
+ "columns": [
2450
+ "rank",
2451
+ "title",
2452
+ "views",
2453
+ "likes",
2454
+ "replies"
2455
+ ],
2456
+ "pipeline": [
2457
+ {
2458
+ "navigate": "https://linux.do"
2459
+ },
2460
+ {
2461
+ "evaluate": "(async () => {\n const keyword = ${{ args.keyword | 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 }));\n})()\n"
2462
+ },
2463
+ {
2464
+ "map": {
2465
+ "rank": "${{ index + 1 }}",
2466
+ "title": "${{ item.title }}",
2467
+ "views": "${{ item.views }}",
2468
+ "likes": "${{ item.likes }}",
2469
+ "replies": "${{ item.replies }}"
2470
+ }
2471
+ },
2472
+ {
2473
+ "limit": "${{ args.limit }}"
2474
+ }
2475
+ ],
2476
+ "type": "yaml"
2477
+ },
2478
+ {
2479
+ "site": "linux-do",
2480
+ "name": "topic",
2481
+ "description": "linux.do 帖子详情和回复(首页)",
2482
+ "domain": "linux.do",
2483
+ "strategy": "cookie",
2484
+ "browser": true,
2485
+ "args": [
2486
+ {
2487
+ "name": "id",
2488
+ "type": "int",
2489
+ "required": true,
2490
+ "help": "Topic ID"
2491
+ }
2492
+ ],
2493
+ "columns": [
2494
+ "author",
2495
+ "content",
2496
+ "likes",
2497
+ "created_at"
2498
+ ],
2499
+ "pipeline": [
2500
+ {
2501
+ "navigate": "https://linux.do"
2502
+ },
2503
+ {
2504
+ "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"
2505
+ },
2506
+ {
2507
+ "map": {
2508
+ "author": "${{ item.author }}",
2509
+ "content": "${{ item.content }}",
2510
+ "likes": "${{ item.likes }}",
2511
+ "created_at": "${{ item.created_at }}"
2512
+ }
2513
+ }
2514
+ ],
2515
+ "type": "yaml"
2516
+ },
2517
+ {
2518
+ "site": "neteasemusic",
2519
+ "name": "like",
2520
+ "description": "Like/unlike the currently playing song",
2521
+ "strategy": "ui",
2522
+ "browser": true,
2523
+ "args": [],
2524
+ "type": "ts",
2525
+ "modulePath": "neteasemusic/like.js",
2526
+ "domain": "localhost",
2527
+ "columns": [
2528
+ "Status"
2529
+ ]
2530
+ },
2531
+ {
2532
+ "site": "neteasemusic",
2533
+ "name": "lyrics",
2534
+ "description": "Get the lyrics of the currently playing song",
2535
+ "strategy": "ui",
2536
+ "browser": true,
2537
+ "args": [],
2538
+ "type": "ts",
2539
+ "modulePath": "neteasemusic/lyrics.js",
2540
+ "domain": "localhost",
2541
+ "columns": [
2542
+ "Line"
2543
+ ]
2544
+ },
2545
+ {
2546
+ "site": "neteasemusic",
2547
+ "name": "next",
2548
+ "description": "Skip to the next song",
2549
+ "strategy": "ui",
2550
+ "browser": true,
2551
+ "args": [],
2552
+ "type": "ts",
2553
+ "modulePath": "neteasemusic/next.js",
2554
+ "domain": "localhost",
2555
+ "columns": [
2556
+ "Status"
2557
+ ]
2558
+ },
2559
+ {
2560
+ "site": "neteasemusic",
2561
+ "name": "play",
2562
+ "description": "Toggle play/pause for the current song",
2563
+ "strategy": "ui",
2564
+ "browser": true,
2565
+ "args": [],
2566
+ "type": "ts",
2567
+ "modulePath": "neteasemusic/play.js",
2568
+ "domain": "localhost",
2569
+ "columns": [
2570
+ "Status"
2571
+ ]
2572
+ },
2573
+ {
2574
+ "site": "neteasemusic",
2575
+ "name": "playing",
2576
+ "description": "Get the currently playing song info",
2577
+ "strategy": "ui",
2578
+ "browser": true,
2579
+ "args": [],
2580
+ "type": "ts",
2581
+ "modulePath": "neteasemusic/playing.js",
2582
+ "domain": "localhost",
2583
+ "columns": [
2584
+ "Title",
2585
+ "Artist",
2586
+ "Album",
2587
+ "Duration",
2588
+ "Progress"
2589
+ ]
2590
+ },
2591
+ {
2592
+ "site": "neteasemusic",
2593
+ "name": "playlist",
2594
+ "description": "Show the current playback queue / playlist",
2595
+ "strategy": "ui",
2596
+ "browser": true,
2597
+ "args": [],
2598
+ "type": "ts",
2599
+ "modulePath": "neteasemusic/playlist.js",
2600
+ "domain": "localhost",
2601
+ "columns": [
2602
+ "Index",
2603
+ "Title",
2604
+ "Artist"
2605
+ ]
2606
+ },
2607
+ {
2608
+ "site": "neteasemusic",
2609
+ "name": "prev",
2610
+ "description": "Go back to the previous song",
2611
+ "strategy": "ui",
2612
+ "browser": true,
2613
+ "args": [],
2614
+ "type": "ts",
2615
+ "modulePath": "neteasemusic/prev.js",
2616
+ "domain": "localhost",
2617
+ "columns": [
2618
+ "Status"
2619
+ ]
2620
+ },
2621
+ {
2622
+ "site": "neteasemusic",
2623
+ "name": "search",
2624
+ "description": "Search for songs, artists, albums, or playlists",
2625
+ "strategy": "ui",
2626
+ "browser": true,
2627
+ "args": [
2628
+ {
2629
+ "name": "query",
2630
+ "type": "str",
2631
+ "required": true,
2632
+ "positional": true,
2633
+ "help": "Search query"
2634
+ }
2635
+ ],
2636
+ "type": "ts",
2637
+ "modulePath": "neteasemusic/search.js",
2638
+ "domain": "localhost",
2639
+ "columns": [
2640
+ "Index",
2641
+ "Title",
2642
+ "Artist"
2643
+ ]
2644
+ },
2645
+ {
2646
+ "site": "neteasemusic",
2647
+ "name": "status",
2648
+ "description": "Check CDP connection to NeteaseMusic Desktop",
2649
+ "strategy": "ui",
2650
+ "browser": true,
2651
+ "args": [],
2652
+ "type": "ts",
2653
+ "modulePath": "neteasemusic/status.js",
2654
+ "domain": "localhost",
2655
+ "columns": [
2656
+ "Status",
2657
+ "Url",
2658
+ "Title"
2659
+ ]
2660
+ },
2661
+ {
2662
+ "site": "neteasemusic",
2663
+ "name": "volume",
2664
+ "description": "Get or set the volume level (0-100)",
2665
+ "strategy": "ui",
2666
+ "browser": true,
2667
+ "args": [
2668
+ {
2669
+ "name": "level",
2670
+ "type": "str",
2671
+ "required": false,
2672
+ "positional": true,
2673
+ "help": "Volume level 0-100 (omit to read current)"
2674
+ }
2675
+ ],
2676
+ "type": "ts",
2677
+ "modulePath": "neteasemusic/volume.js",
2678
+ "domain": "localhost",
2679
+ "columns": [
2680
+ "Status",
2681
+ "Volume"
2682
+ ]
2683
+ },
2684
+ {
2685
+ "site": "notion",
2686
+ "name": "export",
2687
+ "description": "Export the current Notion page as Markdown",
2688
+ "strategy": "ui",
2689
+ "browser": true,
2690
+ "args": [
2691
+ {
2692
+ "name": "output",
2693
+ "type": "str",
2694
+ "default": "/tmp/notion-export.md)",
2695
+ "required": false,
2696
+ "positional": true,
2697
+ "help": "Output file (default: /tmp/notion-export.md)"
2698
+ }
2699
+ ],
2700
+ "type": "ts",
2701
+ "modulePath": "notion/export.js",
2702
+ "domain": "localhost",
2703
+ "columns": [
2704
+ "Status",
2705
+ "File"
2706
+ ]
2707
+ },
2708
+ {
2709
+ "site": "notion",
2710
+ "name": "favorites",
2711
+ "description": "List pages from the Notion Favorites section in the sidebar",
2712
+ "strategy": "ui",
2713
+ "browser": true,
2714
+ "args": [],
2715
+ "type": "ts",
2716
+ "modulePath": "notion/favorites.js",
2717
+ "domain": "localhost",
2718
+ "columns": [
2719
+ "Index",
2720
+ "Title",
2721
+ "Icon"
2722
+ ]
2723
+ },
2724
+ {
2725
+ "site": "notion",
2726
+ "name": "new",
2727
+ "description": "Create a new page in Notion",
2728
+ "strategy": "ui",
2729
+ "browser": true,
2730
+ "args": [
2731
+ {
2732
+ "name": "title",
2733
+ "type": "str",
2734
+ "required": false,
2735
+ "positional": true,
2736
+ "help": "Page title (optional)"
2737
+ }
2738
+ ],
2739
+ "type": "ts",
2740
+ "modulePath": "notion/new.js",
2741
+ "domain": "localhost",
2742
+ "columns": [
2743
+ "Status"
2744
+ ]
2745
+ },
2746
+ {
2747
+ "site": "notion",
2748
+ "name": "read",
2749
+ "description": "Read the content of the currently open Notion page",
2750
+ "strategy": "ui",
2751
+ "browser": true,
2752
+ "args": [],
2753
+ "type": "ts",
2754
+ "modulePath": "notion/read.js",
2755
+ "domain": "localhost",
2756
+ "columns": [
2757
+ "Title",
2758
+ "Content"
2759
+ ]
2760
+ },
2761
+ {
2762
+ "site": "notion",
2763
+ "name": "search",
2764
+ "description": "Search pages and databases in Notion via Quick Find (Cmd+P)",
2765
+ "strategy": "ui",
2766
+ "browser": true,
2767
+ "args": [
2768
+ {
2769
+ "name": "query",
2770
+ "type": "str",
2771
+ "required": true,
2772
+ "positional": true,
2773
+ "help": "Search query"
2774
+ }
2775
+ ],
2776
+ "type": "ts",
2777
+ "modulePath": "notion/search.js",
2778
+ "domain": "localhost",
2779
+ "columns": [
2780
+ "Index",
2781
+ "Title"
2782
+ ]
2783
+ },
2784
+ {
2785
+ "site": "notion",
2786
+ "name": "sidebar",
2787
+ "description": "List pages and databases from the Notion sidebar",
2788
+ "strategy": "ui",
2789
+ "browser": true,
2790
+ "args": [],
2791
+ "type": "ts",
2792
+ "modulePath": "notion/sidebar.js",
2793
+ "domain": "localhost",
2794
+ "columns": [
2795
+ "Index",
2796
+ "Title"
2797
+ ]
2798
+ },
2799
+ {
2800
+ "site": "notion",
2801
+ "name": "status",
2802
+ "description": "Check active CDP connection to Notion Desktop",
2803
+ "strategy": "ui",
2804
+ "browser": true,
2805
+ "args": [],
2806
+ "type": "ts",
2807
+ "modulePath": "notion/status.js",
2808
+ "domain": "localhost",
2809
+ "columns": [
2810
+ "Status",
2811
+ "Url",
2812
+ "Title"
2813
+ ]
2814
+ },
2815
+ {
2816
+ "site": "notion",
2817
+ "name": "write",
2818
+ "description": "Append text content to the currently open Notion page",
2819
+ "strategy": "ui",
2820
+ "browser": true,
2821
+ "args": [
2822
+ {
2823
+ "name": "text",
2824
+ "type": "str",
2825
+ "required": true,
2826
+ "positional": true,
2827
+ "help": "Text to append to the page"
2828
+ }
2829
+ ],
2830
+ "type": "ts",
2831
+ "modulePath": "notion/write.js",
2832
+ "domain": "localhost",
2833
+ "columns": [
2834
+ "Status"
2835
+ ]
2836
+ },
1615
2837
  {
1616
2838
  "site": "reddit",
1617
2839
  "name": "comment",
@@ -2418,6 +3640,44 @@
2418
3640
  "message"
2419
3641
  ]
2420
3642
  },
3643
+ {
3644
+ "site": "twitter",
3645
+ "name": "download",
3646
+ "description": "下载 Twitter/X 媒体(图片和视频)",
3647
+ "strategy": "cookie",
3648
+ "browser": true,
3649
+ "args": [
3650
+ {
3651
+ "name": "username",
3652
+ "type": "str",
3653
+ "required": false,
3654
+ "help": "Twitter username (downloads from media tab)"
3655
+ },
3656
+ {
3657
+ "name": "limit",
3658
+ "type": "int",
3659
+ "default": 10,
3660
+ "required": false,
3661
+ "help": "Number of tweets to scan"
3662
+ },
3663
+ {
3664
+ "name": "output",
3665
+ "type": "str",
3666
+ "default": "./twitter-downloads",
3667
+ "required": false,
3668
+ "help": "Output directory"
3669
+ }
3670
+ ],
3671
+ "type": "ts",
3672
+ "modulePath": "twitter/download.js",
3673
+ "domain": "x.com",
3674
+ "columns": [
3675
+ "index",
3676
+ "type",
3677
+ "status",
3678
+ "size"
3679
+ ]
3680
+ },
2421
3681
  {
2422
3682
  "site": "twitter",
2423
3683
  "name": "follow",
@@ -2996,6 +4256,107 @@
2996
4256
  ],
2997
4257
  "type": "yaml"
2998
4258
  },
4259
+ {
4260
+ "site": "wechat",
4261
+ "name": "chats",
4262
+ "description": "Open the WeChat chats panel (conversation list)",
4263
+ "strategy": "public",
4264
+ "browser": false,
4265
+ "args": [],
4266
+ "type": "ts",
4267
+ "modulePath": "wechat/chats.js",
4268
+ "domain": "localhost",
4269
+ "columns": [
4270
+ "Status"
4271
+ ]
4272
+ },
4273
+ {
4274
+ "site": "wechat",
4275
+ "name": "contacts",
4276
+ "description": "Open the WeChat contacts panel",
4277
+ "strategy": "public",
4278
+ "browser": false,
4279
+ "args": [],
4280
+ "type": "ts",
4281
+ "modulePath": "wechat/contacts.js",
4282
+ "domain": "localhost",
4283
+ "columns": [
4284
+ "Status"
4285
+ ]
4286
+ },
4287
+ {
4288
+ "site": "wechat",
4289
+ "name": "read",
4290
+ "description": "Read the current chat content by selecting all and copying",
4291
+ "strategy": "public",
4292
+ "browser": false,
4293
+ "args": [],
4294
+ "type": "ts",
4295
+ "modulePath": "wechat/read.js",
4296
+ "domain": "localhost",
4297
+ "columns": [
4298
+ "Content"
4299
+ ]
4300
+ },
4301
+ {
4302
+ "site": "wechat",
4303
+ "name": "search",
4304
+ "description": "Open WeChat search and type a query (find contacts or messages)",
4305
+ "strategy": "public",
4306
+ "browser": false,
4307
+ "args": [
4308
+ {
4309
+ "name": "query",
4310
+ "type": "str",
4311
+ "required": true,
4312
+ "positional": true,
4313
+ "help": "Search query (contact name or keyword)"
4314
+ }
4315
+ ],
4316
+ "type": "ts",
4317
+ "modulePath": "wechat/search.js",
4318
+ "domain": "localhost",
4319
+ "columns": [
4320
+ "Status"
4321
+ ]
4322
+ },
4323
+ {
4324
+ "site": "wechat",
4325
+ "name": "send",
4326
+ "description": "Send a message in the active WeChat conversation via clipboard paste",
4327
+ "strategy": "public",
4328
+ "browser": false,
4329
+ "args": [
4330
+ {
4331
+ "name": "text",
4332
+ "type": "str",
4333
+ "required": true,
4334
+ "positional": true,
4335
+ "help": "Message to send"
4336
+ }
4337
+ ],
4338
+ "type": "ts",
4339
+ "modulePath": "wechat/send.js",
4340
+ "domain": "localhost",
4341
+ "columns": [
4342
+ "Status"
4343
+ ]
4344
+ },
4345
+ {
4346
+ "site": "wechat",
4347
+ "name": "status",
4348
+ "description": "Check if WeChat Desktop is running on macOS",
4349
+ "strategy": "public",
4350
+ "browser": false,
4351
+ "args": [],
4352
+ "type": "ts",
4353
+ "modulePath": "wechat/status.js",
4354
+ "domain": "localhost",
4355
+ "columns": [
4356
+ "Status",
4357
+ "Detail"
4358
+ ]
4359
+ },
2999
4360
  {
3000
4361
  "site": "weibo",
3001
4362
  "name": "hot",
@@ -3023,6 +4384,137 @@
3023
4384
  "url"
3024
4385
  ]
3025
4386
  },
4387
+ {
4388
+ "site": "xiaohongshu",
4389
+ "name": "creator-note-detail",
4390
+ "description": "小红书单篇笔记详细数据 (阅读/互动/点赞/收藏/评论/分享,区分自然流量/推广/视频)",
4391
+ "strategy": "cookie",
4392
+ "browser": true,
4393
+ "args": [
4394
+ {
4395
+ "name": "note_id",
4396
+ "type": "string",
4397
+ "required": true,
4398
+ "help": "Note ID (from note URL or creator-notes command)"
4399
+ }
4400
+ ],
4401
+ "type": "ts",
4402
+ "modulePath": "xiaohongshu/creator-note-detail.js",
4403
+ "domain": "creator.xiaohongshu.com",
4404
+ "columns": [
4405
+ "channel",
4406
+ "reads",
4407
+ "engagement",
4408
+ "likes",
4409
+ "collects",
4410
+ "comments",
4411
+ "shares"
4412
+ ]
4413
+ },
4414
+ {
4415
+ "site": "xiaohongshu",
4416
+ "name": "creator-notes",
4417
+ "description": "小红书创作者笔记列表 + 每篇数据 (标题/日期/观看/点赞/收藏/评论)",
4418
+ "strategy": "cookie",
4419
+ "browser": true,
4420
+ "args": [
4421
+ {
4422
+ "name": "limit",
4423
+ "type": "int",
4424
+ "default": 20,
4425
+ "required": false,
4426
+ "help": "Number of notes to return"
4427
+ }
4428
+ ],
4429
+ "type": "ts",
4430
+ "modulePath": "xiaohongshu/creator-notes.js",
4431
+ "domain": "creator.xiaohongshu.com",
4432
+ "columns": [
4433
+ "rank",
4434
+ "id",
4435
+ "title",
4436
+ "date",
4437
+ "views",
4438
+ "likes",
4439
+ "collects",
4440
+ "comments",
4441
+ "url"
4442
+ ]
4443
+ },
4444
+ {
4445
+ "site": "xiaohongshu",
4446
+ "name": "creator-profile",
4447
+ "description": "小红书创作者账号信息 (粉丝/关注/获赞/成长等级)",
4448
+ "strategy": "cookie",
4449
+ "browser": true,
4450
+ "args": [],
4451
+ "type": "ts",
4452
+ "modulePath": "xiaohongshu/creator-profile.js",
4453
+ "domain": "creator.xiaohongshu.com",
4454
+ "columns": [
4455
+ "field",
4456
+ "value"
4457
+ ]
4458
+ },
4459
+ {
4460
+ "site": "xiaohongshu",
4461
+ "name": "creator-stats",
4462
+ "description": "小红书创作者数据总览 (观看/点赞/收藏/评论/分享/涨粉,含每日趋势)",
4463
+ "strategy": "cookie",
4464
+ "browser": true,
4465
+ "args": [
4466
+ {
4467
+ "name": "period",
4468
+ "type": "string",
4469
+ "default": "seven",
4470
+ "required": false,
4471
+ "help": "Stats period: seven or thirty",
4472
+ "choices": [
4473
+ "seven",
4474
+ "thirty"
4475
+ ]
4476
+ }
4477
+ ],
4478
+ "type": "ts",
4479
+ "modulePath": "xiaohongshu/creator-stats.js",
4480
+ "domain": "creator.xiaohongshu.com",
4481
+ "columns": [
4482
+ "metric",
4483
+ "total",
4484
+ "trend"
4485
+ ]
4486
+ },
4487
+ {
4488
+ "site": "xiaohongshu",
4489
+ "name": "download",
4490
+ "description": "下载小红书笔记中的图片和视频",
4491
+ "strategy": "cookie",
4492
+ "browser": true,
4493
+ "args": [
4494
+ {
4495
+ "name": "note_id",
4496
+ "type": "str",
4497
+ "required": true,
4498
+ "help": "Note ID (from URL)"
4499
+ },
4500
+ {
4501
+ "name": "output",
4502
+ "type": "str",
4503
+ "default": "./xiaohongshu-downloads",
4504
+ "required": false,
4505
+ "help": "Output directory"
4506
+ }
4507
+ ],
4508
+ "type": "ts",
4509
+ "modulePath": "xiaohongshu/download.js",
4510
+ "domain": "www.xiaohongshu.com",
4511
+ "columns": [
4512
+ "index",
4513
+ "type",
4514
+ "status",
4515
+ "size"
4516
+ ]
4517
+ },
3026
4518
  {
3027
4519
  "site": "xiaohongshu",
3028
4520
  "name": "feed",
@@ -3175,30 +4667,50 @@
3175
4667
  "likes"
3176
4668
  ]
3177
4669
  },
4670
+ {
4671
+ "site": "xiaohongshu",
4672
+ "name": "user-helpers",
4673
+ "description": "",
4674
+ "strategy": "cookie",
4675
+ "browser": true,
4676
+ "args": [],
4677
+ "type": "ts",
4678
+ "modulePath": "xiaohongshu/user-helpers.js"
4679
+ },
4680
+ {
4681
+ "site": "xiaohongshu",
4682
+ "name": "user-helpers.test",
4683
+ "description": "",
4684
+ "strategy": "cookie",
4685
+ "browser": true,
4686
+ "args": [],
4687
+ "type": "ts",
4688
+ "modulePath": "xiaohongshu/user-helpers.test.js"
4689
+ },
3178
4690
  {
3179
4691
  "site": "xiaohongshu",
3180
4692
  "name": "user",
3181
- "description": "Get user notes from Xiaohongshu",
3182
- "strategy": "intercept",
4693
+ "description": "Get public notes from a Xiaohongshu user profile",
4694
+ "strategy": "cookie",
3183
4695
  "browser": true,
3184
4696
  "args": [
3185
4697
  {
3186
4698
  "name": "id",
3187
4699
  "type": "string",
3188
4700
  "required": true,
3189
- "help": ""
4701
+ "help": "User id or profile URL"
3190
4702
  },
3191
4703
  {
3192
4704
  "name": "limit",
3193
4705
  "type": "int",
3194
4706
  "default": 15,
3195
4707
  "required": false,
3196
- "help": ""
4708
+ "help": "Number of notes to return"
3197
4709
  }
3198
4710
  ],
3199
4711
  "type": "ts",
3200
4712
  "modulePath": "xiaohongshu/user.js",
3201
- "domain": "xiaohongshu.com",
4713
+ "domain": "www.xiaohongshu.com",
3202
4714
  "columns": [
3203
4715
  "id",
3204
4716
  "title",
@@ -3754,6 +5266,47 @@
3754
5266
  "value"
3755
5267
  ]
3756
5268
  },
5269
+ {
5270
+ "site": "zhihu",
5271
+ "name": "download",
5272
+ "description": "导出知乎文章为 Markdown 格式",
5273
+ "strategy": "cookie",
5274
+ "browser": true,
5275
+ "args": [
5276
+ {
5277
+ "name": "url",
5278
+ "type": "str",
5279
+ "required": true,
5280
+ "help": "Article URL (zhuanlan.zhihu.com/p/xxx)"
5281
+ },
5282
+ {
5283
+ "name": "output",
5284
+ "type": "str",
5285
+ "default": "./zhihu-articles",
5286
+ "required": false,
5287
+ "help": "Output directory"
5288
+ }
5289
+ ],
5290
+ "type": "ts",
5291
+ "modulePath": "zhihu/download.js",
5292
+ "domain": "zhuanlan.zhihu.com",
5293
+ "columns": [
5294
+ "title",
5295
+ "author",
5296
+ "status",
5297
+ "size"
5298
+ ]
5299
+ },
5300
+ {
5301
+ "site": "zhihu",
5302
+ "name": "download.test",
5303
+ "description": "",
5304
+ "strategy": "cookie",
5305
+ "browser": true,
5306
+ "args": [],
5307
+ "type": "ts",
5308
+ "modulePath": "zhihu/download.test.js"
5309
+ },
3757
5310
  {
3758
5311
  "site": "zhihu",
3759
5312
  "name": "hot",