@jackwener/opencli 0.4.0 → 0.4.2

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.
@@ -0,0 +1,1793 @@
1
+ [
2
+ {
3
+ "site": "bbc",
4
+ "name": "news",
5
+ "description": "BBC News headlines (RSS)",
6
+ "strategy": "public",
7
+ "browser": true,
8
+ "args": [
9
+ {
10
+ "name": "limit",
11
+ "type": "int",
12
+ "default": 20,
13
+ "required": false,
14
+ "help": "Number of headlines (max 50)"
15
+ }
16
+ ],
17
+ "type": "ts",
18
+ "modulePath": "bbc/news.js",
19
+ "domain": "www.bbc.com",
20
+ "columns": [
21
+ "rank",
22
+ "title",
23
+ "description",
24
+ "url"
25
+ ]
26
+ },
27
+ {
28
+ "site": "bilibili",
29
+ "name": "dynamic",
30
+ "description": "Get Bilibili user dynamic feed",
31
+ "strategy": "cookie",
32
+ "browser": true,
33
+ "args": [
34
+ {
35
+ "name": "limit",
36
+ "type": "int",
37
+ "default": 15,
38
+ "required": false,
39
+ "help": ""
40
+ }
41
+ ],
42
+ "type": "ts",
43
+ "modulePath": "bilibili/dynamic.js",
44
+ "domain": "www.bilibili.com",
45
+ "columns": [
46
+ "id",
47
+ "author",
48
+ "text",
49
+ "likes",
50
+ "url"
51
+ ]
52
+ },
53
+ {
54
+ "site": "bilibili",
55
+ "name": "favorite",
56
+ "description": "我的默认收藏夹",
57
+ "strategy": "cookie",
58
+ "browser": true,
59
+ "args": [
60
+ {
61
+ "name": "limit",
62
+ "type": "int",
63
+ "default": 20,
64
+ "required": false,
65
+ "help": "Number of results"
66
+ },
67
+ {
68
+ "name": "page",
69
+ "type": "int",
70
+ "default": 1,
71
+ "required": false,
72
+ "help": "Page number"
73
+ }
74
+ ],
75
+ "type": "ts",
76
+ "modulePath": "bilibili/favorite.js",
77
+ "domain": "www.bilibili.com",
78
+ "columns": [
79
+ "rank",
80
+ "title",
81
+ "author",
82
+ "plays",
83
+ "url"
84
+ ]
85
+ },
86
+ {
87
+ "site": "bilibili",
88
+ "name": "feed",
89
+ "description": "关注的人的动态时间线",
90
+ "strategy": "cookie",
91
+ "browser": true,
92
+ "args": [
93
+ {
94
+ "name": "limit",
95
+ "type": "int",
96
+ "default": 20,
97
+ "required": false,
98
+ "help": "Number of results"
99
+ },
100
+ {
101
+ "name": "type",
102
+ "type": "str",
103
+ "default": "all",
104
+ "required": false,
105
+ "help": "Filter: all, video, article"
106
+ }
107
+ ],
108
+ "type": "ts",
109
+ "modulePath": "bilibili/feed.js",
110
+ "domain": "www.bilibili.com",
111
+ "columns": [
112
+ "rank",
113
+ "author",
114
+ "title",
115
+ "type",
116
+ "url"
117
+ ]
118
+ },
119
+ {
120
+ "site": "bilibili",
121
+ "name": "following",
122
+ "description": "获取 Bilibili 用户的关注列表",
123
+ "strategy": "cookie",
124
+ "browser": true,
125
+ "args": [
126
+ {
127
+ "name": "uid",
128
+ "type": "str",
129
+ "required": false,
130
+ "help": "目标用户 ID(默认为当前登录用户)"
131
+ },
132
+ {
133
+ "name": "page",
134
+ "type": "int",
135
+ "default": 1,
136
+ "required": false,
137
+ "help": "页码"
138
+ },
139
+ {
140
+ "name": "limit",
141
+ "type": "int",
142
+ "default": 50,
143
+ "required": false,
144
+ "help": "每页数量 (最大 50)"
145
+ }
146
+ ],
147
+ "type": "ts",
148
+ "modulePath": "bilibili/following.js",
149
+ "columns": [
150
+ "mid",
151
+ "name",
152
+ "sign",
153
+ "following",
154
+ "fans"
155
+ ]
156
+ },
157
+ {
158
+ "site": "bilibili",
159
+ "name": "history",
160
+ "description": "我的观看历史",
161
+ "strategy": "cookie",
162
+ "browser": true,
163
+ "args": [
164
+ {
165
+ "name": "limit",
166
+ "type": "int",
167
+ "default": 20,
168
+ "required": false,
169
+ "help": "Number of results"
170
+ }
171
+ ],
172
+ "type": "ts",
173
+ "modulePath": "bilibili/history.js",
174
+ "domain": "www.bilibili.com",
175
+ "columns": [
176
+ "rank",
177
+ "title",
178
+ "author",
179
+ "progress",
180
+ "url"
181
+ ]
182
+ },
183
+ {
184
+ "site": "bilibili",
185
+ "name": "hot",
186
+ "description": "B站热门视频",
187
+ "domain": "www.bilibili.com",
188
+ "strategy": "cookie",
189
+ "browser": true,
190
+ "args": [
191
+ {
192
+ "name": "limit",
193
+ "type": "int",
194
+ "default": 20,
195
+ "required": false,
196
+ "help": "Number of videos"
197
+ }
198
+ ],
199
+ "columns": [
200
+ "rank",
201
+ "title",
202
+ "author",
203
+ "play",
204
+ "danmaku"
205
+ ],
206
+ "pipeline": [
207
+ {
208
+ "navigate": "https://www.bilibili.com"
209
+ },
210
+ {
211
+ "evaluate": "(async () => {\n const res = await fetch('https://api.bilibili.com/x/web-interface/popular?ps=${{ args.limit }}&pn=1', {\n credentials: 'include'\n });\n const data = await res.json();\n return (data?.data?.list || []).map((item) => ({\n title: item.title,\n author: item.owner?.name,\n play: item.stat?.view,\n danmaku: item.stat?.danmaku,\n }));\n})()\n"
212
+ },
213
+ {
214
+ "map": {
215
+ "rank": "${{ index + 1 }}",
216
+ "title": "${{ item.title }}",
217
+ "author": "${{ item.author }}",
218
+ "play": "${{ item.play }}",
219
+ "danmaku": "${{ item.danmaku }}"
220
+ }
221
+ },
222
+ {
223
+ "limit": "${{ args.limit }}"
224
+ }
225
+ ],
226
+ "type": "yaml"
227
+ },
228
+ {
229
+ "site": "bilibili",
230
+ "name": "me",
231
+ "description": "My Bilibili profile info",
232
+ "strategy": "cookie",
233
+ "browser": true,
234
+ "args": [],
235
+ "type": "ts",
236
+ "modulePath": "bilibili/me.js",
237
+ "domain": "www.bilibili.com",
238
+ "columns": [
239
+ "name",
240
+ "uid",
241
+ "level",
242
+ "coins",
243
+ "followers",
244
+ "following"
245
+ ]
246
+ },
247
+ {
248
+ "site": "bilibili",
249
+ "name": "ranking",
250
+ "description": "Get Bilibili video ranking board",
251
+ "strategy": "cookie",
252
+ "browser": true,
253
+ "args": [
254
+ {
255
+ "name": "limit",
256
+ "type": "int",
257
+ "default": 20,
258
+ "required": false,
259
+ "help": ""
260
+ }
261
+ ],
262
+ "type": "ts",
263
+ "modulePath": "bilibili/ranking.js",
264
+ "domain": "www.bilibili.com",
265
+ "columns": [
266
+ "rank",
267
+ "title",
268
+ "author",
269
+ "score",
270
+ "url"
271
+ ]
272
+ },
273
+ {
274
+ "site": "bilibili",
275
+ "name": "search",
276
+ "description": "Search Bilibili videos or users",
277
+ "strategy": "cookie",
278
+ "browser": true,
279
+ "args": [
280
+ {
281
+ "name": "keyword",
282
+ "type": "str",
283
+ "required": true,
284
+ "help": "Search keyword"
285
+ },
286
+ {
287
+ "name": "type",
288
+ "type": "str",
289
+ "default": "video",
290
+ "required": false,
291
+ "help": "video or user"
292
+ },
293
+ {
294
+ "name": "page",
295
+ "type": "int",
296
+ "default": 1,
297
+ "required": false,
298
+ "help": "Result page"
299
+ },
300
+ {
301
+ "name": "limit",
302
+ "type": "int",
303
+ "default": 20,
304
+ "required": false,
305
+ "help": "Number of results"
306
+ }
307
+ ],
308
+ "type": "ts",
309
+ "modulePath": "bilibili/search.js",
310
+ "domain": "www.bilibili.com",
311
+ "columns": [
312
+ "rank",
313
+ "title",
314
+ "author",
315
+ "score",
316
+ "url"
317
+ ]
318
+ },
319
+ {
320
+ "site": "bilibili",
321
+ "name": "subtitle",
322
+ "description": "获取 Bilibili 视频的字幕",
323
+ "strategy": "cookie",
324
+ "browser": true,
325
+ "args": [
326
+ {
327
+ "name": "bvid",
328
+ "type": "str",
329
+ "required": true,
330
+ "help": ""
331
+ },
332
+ {
333
+ "name": "lang",
334
+ "type": "str",
335
+ "required": false,
336
+ "help": "字幕语言代码 (如 zh-CN, en-US, ai-zh),默认取第一个"
337
+ }
338
+ ],
339
+ "type": "ts",
340
+ "modulePath": "bilibili/subtitle.js",
341
+ "columns": [
342
+ "index",
343
+ "from",
344
+ "to",
345
+ "content"
346
+ ]
347
+ },
348
+ {
349
+ "site": "bilibili",
350
+ "name": "user-videos",
351
+ "description": "查看指定用户的投稿视频",
352
+ "strategy": "cookie",
353
+ "browser": true,
354
+ "args": [
355
+ {
356
+ "name": "uid",
357
+ "type": "str",
358
+ "required": true,
359
+ "help": "User UID or username"
360
+ },
361
+ {
362
+ "name": "limit",
363
+ "type": "int",
364
+ "default": 20,
365
+ "required": false,
366
+ "help": "Number of results"
367
+ },
368
+ {
369
+ "name": "order",
370
+ "type": "str",
371
+ "default": "pubdate",
372
+ "required": false,
373
+ "help": "Sort: pubdate, click, stow"
374
+ },
375
+ {
376
+ "name": "page",
377
+ "type": "int",
378
+ "default": 1,
379
+ "required": false,
380
+ "help": "Page number"
381
+ }
382
+ ],
383
+ "type": "ts",
384
+ "modulePath": "bilibili/user-videos.js",
385
+ "domain": "www.bilibili.com",
386
+ "columns": [
387
+ "rank",
388
+ "title",
389
+ "plays",
390
+ "likes",
391
+ "date",
392
+ "url"
393
+ ]
394
+ },
395
+ {
396
+ "site": "boss",
397
+ "name": "search",
398
+ "description": "BOSS直聘搜索职位",
399
+ "strategy": "cookie",
400
+ "browser": true,
401
+ "args": [
402
+ {
403
+ "name": "query",
404
+ "type": "str",
405
+ "required": true,
406
+ "help": "Search keyword (e.g. AI agent, 前端)"
407
+ },
408
+ {
409
+ "name": "city",
410
+ "type": "str",
411
+ "default": "101010100",
412
+ "required": false,
413
+ "help": "City code (101010100=北京, 101020100=上海, 101210100=杭州, 101280100=广州)"
414
+ },
415
+ {
416
+ "name": "limit",
417
+ "type": "int",
418
+ "default": 15,
419
+ "required": false,
420
+ "help": "Number of results"
421
+ }
422
+ ],
423
+ "type": "ts",
424
+ "modulePath": "boss/search.js",
425
+ "domain": "www.zhipin.com",
426
+ "columns": [
427
+ "name",
428
+ "salary",
429
+ "company",
430
+ "city",
431
+ "experience",
432
+ "degree",
433
+ "boss",
434
+ "url"
435
+ ]
436
+ },
437
+ {
438
+ "site": "ctrip",
439
+ "name": "search",
440
+ "description": "携程旅行搜索",
441
+ "strategy": "cookie",
442
+ "browser": true,
443
+ "args": [
444
+ {
445
+ "name": "query",
446
+ "type": "str",
447
+ "required": true,
448
+ "help": "Search keyword (city or attraction)"
449
+ },
450
+ {
451
+ "name": "limit",
452
+ "type": "int",
453
+ "default": 15,
454
+ "required": false,
455
+ "help": "Number of results"
456
+ }
457
+ ],
458
+ "type": "ts",
459
+ "modulePath": "ctrip/search.js",
460
+ "domain": "www.ctrip.com",
461
+ "columns": [
462
+ "rank",
463
+ "name",
464
+ "type",
465
+ "score",
466
+ "price",
467
+ "url"
468
+ ]
469
+ },
470
+ {
471
+ "site": "hackernews",
472
+ "name": "top",
473
+ "description": "Hacker News top stories",
474
+ "domain": "news.ycombinator.com",
475
+ "strategy": "public",
476
+ "browser": false,
477
+ "args": [
478
+ {
479
+ "name": "limit",
480
+ "type": "int",
481
+ "default": 20,
482
+ "required": false,
483
+ "help": "Number of stories"
484
+ }
485
+ ],
486
+ "columns": [
487
+ "rank",
488
+ "title",
489
+ "score",
490
+ "author",
491
+ "comments"
492
+ ],
493
+ "pipeline": [
494
+ {
495
+ "fetch": {
496
+ "url": "https://hacker-news.firebaseio.com/v0/topstories.json"
497
+ }
498
+ },
499
+ {
500
+ "limit": 30
501
+ },
502
+ {
503
+ "map": {
504
+ "id": "${{ item }}"
505
+ }
506
+ },
507
+ {
508
+ "fetch": {
509
+ "url": "https://hacker-news.firebaseio.com/v0/item/${{ item.id }}.json"
510
+ }
511
+ },
512
+ {
513
+ "map": {
514
+ "rank": "${{ index + 1 }}",
515
+ "title": "${{ item.title }}",
516
+ "score": "${{ item.score }}",
517
+ "author": "${{ item.by }}",
518
+ "comments": "${{ item.descendants }}",
519
+ "url": "${{ item.url }}"
520
+ }
521
+ },
522
+ {
523
+ "limit": "${{ args.limit }}"
524
+ }
525
+ ],
526
+ "type": "yaml"
527
+ },
528
+ {
529
+ "site": "reddit",
530
+ "name": "frontpage",
531
+ "description": "Reddit Frontpage / r/all",
532
+ "domain": "reddit.com",
533
+ "strategy": "cookie",
534
+ "browser": true,
535
+ "args": [
536
+ {
537
+ "name": "limit",
538
+ "type": "int",
539
+ "default": 15,
540
+ "required": false,
541
+ "help": ""
542
+ }
543
+ ],
544
+ "columns": [
545
+ "title",
546
+ "subreddit",
547
+ "author",
548
+ "upvotes",
549
+ "comments",
550
+ "url"
551
+ ],
552
+ "pipeline": [
553
+ {
554
+ "navigate": "https://www.reddit.com"
555
+ },
556
+ {
557
+ "evaluate": "(async () => {\n const res = await fetch('/r/all.json?limit=${{ args.limit }}', { credentials: 'include' });\n const j = await res.json();\n return j?.data?.children || [];\n})()\n"
558
+ },
559
+ {
560
+ "map": {
561
+ "title": "${{ item.data.title }}",
562
+ "subreddit": "${{ item.data.subreddit_name_prefixed }}",
563
+ "author": "${{ item.data.author }}",
564
+ "upvotes": "${{ item.data.score }}",
565
+ "comments": "${{ item.data.num_comments }}",
566
+ "url": "https://www.reddit.com${{ item.data.permalink }}"
567
+ }
568
+ },
569
+ {
570
+ "limit": "${{ args.limit }}"
571
+ }
572
+ ],
573
+ "type": "yaml"
574
+ },
575
+ {
576
+ "site": "reddit",
577
+ "name": "hot",
578
+ "description": "Reddit 热门帖子",
579
+ "domain": "www.reddit.com",
580
+ "strategy": "cookie",
581
+ "browser": true,
582
+ "args": [
583
+ {
584
+ "name": "subreddit",
585
+ "type": "str",
586
+ "default": "",
587
+ "required": false,
588
+ "help": "Subreddit name (e.g. programming). Empty for frontpage"
589
+ },
590
+ {
591
+ "name": "limit",
592
+ "type": "int",
593
+ "default": 20,
594
+ "required": false,
595
+ "help": "Number of posts"
596
+ }
597
+ ],
598
+ "columns": [
599
+ "rank",
600
+ "title",
601
+ "subreddit",
602
+ "score",
603
+ "comments"
604
+ ],
605
+ "pipeline": [
606
+ {
607
+ "navigate": "https://www.reddit.com"
608
+ },
609
+ {
610
+ "evaluate": "(async () => {\n const sub = ${{ args.subreddit | json }};\n const path = sub ? '/r/' + sub + '/hot.json' : '/hot.json';\n const limit = ${{ args.limit }};\n const res = await fetch(path + '?limit=' + limit + '&raw_json=1', {\n credentials: 'include'\n });\n const d = await res.json();\n return (d?.data?.children || []).map(c => ({\n title: c.data.title,\n subreddit: c.data.subreddit_name_prefixed,\n score: c.data.score,\n comments: c.data.num_comments,\n author: c.data.author,\n url: 'https://www.reddit.com' + c.data.permalink,\n }));\n})()\n"
611
+ },
612
+ {
613
+ "map": {
614
+ "rank": "${{ index + 1 }}",
615
+ "title": "${{ item.title }}",
616
+ "subreddit": "${{ item.subreddit }}",
617
+ "score": "${{ item.score }}",
618
+ "comments": "${{ item.comments }}"
619
+ }
620
+ },
621
+ {
622
+ "limit": "${{ args.limit }}"
623
+ }
624
+ ],
625
+ "type": "yaml"
626
+ },
627
+ {
628
+ "site": "reddit",
629
+ "name": "search",
630
+ "description": "Search Reddit Posts",
631
+ "domain": "reddit.com",
632
+ "strategy": "cookie",
633
+ "browser": true,
634
+ "args": [
635
+ {
636
+ "name": "query",
637
+ "type": "string",
638
+ "required": true,
639
+ "help": ""
640
+ },
641
+ {
642
+ "name": "limit",
643
+ "type": "int",
644
+ "default": 15,
645
+ "required": false,
646
+ "help": ""
647
+ }
648
+ ],
649
+ "columns": [
650
+ "title",
651
+ "subreddit",
652
+ "author",
653
+ "upvotes",
654
+ "comments",
655
+ "url"
656
+ ],
657
+ "pipeline": [
658
+ {
659
+ "navigate": "https://www.reddit.com"
660
+ },
661
+ {
662
+ "evaluate": "(async () => {\n const q = encodeURIComponent('${{ args.query }}');\n const res = await fetch('/search.json?q=' + q + '&limit=${{ args.limit }}', { credentials: 'include' });\n const j = await res.json();\n return j?.data?.children || [];\n})()\n"
663
+ },
664
+ {
665
+ "map": {
666
+ "title": "${{ item.data.title }}",
667
+ "subreddit": "${{ item.data.subreddit_name_prefixed }}",
668
+ "author": "${{ item.data.author }}",
669
+ "upvotes": "${{ item.data.score }}",
670
+ "comments": "${{ item.data.num_comments }}",
671
+ "url": "https://www.reddit.com${{ item.data.permalink }}"
672
+ }
673
+ },
674
+ {
675
+ "limit": "${{ args.limit }}"
676
+ }
677
+ ],
678
+ "type": "yaml"
679
+ },
680
+ {
681
+ "site": "reddit",
682
+ "name": "subreddit",
683
+ "description": "Get posts from a specific Subreddit",
684
+ "domain": "reddit.com",
685
+ "strategy": "cookie",
686
+ "browser": true,
687
+ "args": [
688
+ {
689
+ "name": "name",
690
+ "type": "string",
691
+ "required": true,
692
+ "help": ""
693
+ },
694
+ {
695
+ "name": "sort",
696
+ "type": "string",
697
+ "default": "hot",
698
+ "required": false,
699
+ "help": "Sorting method: hot, new, top, rising"
700
+ },
701
+ {
702
+ "name": "limit",
703
+ "type": "int",
704
+ "default": 15,
705
+ "required": false,
706
+ "help": ""
707
+ }
708
+ ],
709
+ "columns": [
710
+ "title",
711
+ "author",
712
+ "upvotes",
713
+ "comments",
714
+ "url"
715
+ ],
716
+ "pipeline": [
717
+ {
718
+ "navigate": "https://www.reddit.com"
719
+ },
720
+ {
721
+ "evaluate": "(async () => {\n let sub = '${{ args.name }}';\n if (sub.startsWith('r/')) sub = sub.slice(2);\n const sort = '${{ args.sort }}';\n const res = await fetch('/r/' + sub + '/' + sort + '.json?limit=${{ args.limit }}', { credentials: 'include' });\n const j = await res.json();\n return j?.data?.children || [];\n})()\n"
722
+ },
723
+ {
724
+ "map": {
725
+ "title": "${{ item.data.title }}",
726
+ "author": "${{ item.data.author }}",
727
+ "upvotes": "${{ item.data.score }}",
728
+ "comments": "${{ item.data.num_comments }}",
729
+ "url": "https://www.reddit.com${{ item.data.permalink }}"
730
+ }
731
+ },
732
+ {
733
+ "limit": "${{ args.limit }}"
734
+ }
735
+ ],
736
+ "type": "yaml"
737
+ },
738
+ {
739
+ "site": "reuters",
740
+ "name": "search",
741
+ "description": "Reuters 路透社新闻搜索",
742
+ "strategy": "cookie",
743
+ "browser": true,
744
+ "args": [
745
+ {
746
+ "name": "query",
747
+ "type": "str",
748
+ "required": true,
749
+ "help": "Search query"
750
+ },
751
+ {
752
+ "name": "limit",
753
+ "type": "int",
754
+ "default": 10,
755
+ "required": false,
756
+ "help": "Number of results (max 40)"
757
+ }
758
+ ],
759
+ "type": "ts",
760
+ "modulePath": "reuters/search.js",
761
+ "domain": "www.reuters.com",
762
+ "columns": [
763
+ "rank",
764
+ "title",
765
+ "date",
766
+ "section",
767
+ "url"
768
+ ]
769
+ },
770
+ {
771
+ "site": "smzdm",
772
+ "name": "search",
773
+ "description": "什么值得买搜索好价",
774
+ "strategy": "cookie",
775
+ "browser": true,
776
+ "args": [
777
+ {
778
+ "name": "keyword",
779
+ "type": "str",
780
+ "required": true,
781
+ "help": "Search keyword"
782
+ },
783
+ {
784
+ "name": "limit",
785
+ "type": "int",
786
+ "default": 20,
787
+ "required": false,
788
+ "help": "Number of results"
789
+ }
790
+ ],
791
+ "type": "ts",
792
+ "modulePath": "smzdm/search.js",
793
+ "domain": "www.smzdm.com",
794
+ "columns": [
795
+ "rank",
796
+ "title",
797
+ "price",
798
+ "mall",
799
+ "comments",
800
+ "url"
801
+ ]
802
+ },
803
+ {
804
+ "site": "twitter",
805
+ "name": "bookmarks",
806
+ "description": "获取 Twitter 书签列表",
807
+ "domain": "x.com",
808
+ "strategy": "cookie",
809
+ "browser": true,
810
+ "args": [
811
+ {
812
+ "name": "limit",
813
+ "type": "int",
814
+ "default": 20,
815
+ "required": false,
816
+ "help": "Number of bookmarks to return (default 20)"
817
+ }
818
+ ],
819
+ "columns": [
820
+ "author",
821
+ "text",
822
+ "likes",
823
+ "url"
824
+ ],
825
+ "pipeline": [
826
+ {
827
+ "navigate": "https://x.com/i/bookmarks"
828
+ },
829
+ {
830
+ "wait": 2
831
+ },
832
+ {
833
+ "evaluate": "(async () => {\n const ct0 = document.cookie.split(';').map(c=>c.trim()).find(c=>c.startsWith('ct0='))?.split('=')[1];\n if (!ct0) throw new Error('No ct0 cookie. Hint: Not logged into x.com.');\n const bearer = decodeURIComponent('AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA');\n const _h = {'Authorization':'Bearer '+bearer, 'X-Csrf-Token':ct0, 'X-Twitter-Auth-Type':'OAuth2Session', 'X-Twitter-Active-User':'yes'};\n\n const count = Math.min(${{ args.limit }}, 100);\n const variables = JSON.stringify({count, includePromotedContent: false});\n const features = JSON.stringify({\n rweb_video_screen_enabled: false, profile_label_improvements_pcf_label_in_post_enabled: true,\n responsive_web_profile_redirect_enabled: false, rweb_tipjar_consumption_enabled: false,\n verified_phone_label_enabled: false, creator_subscriptions_tweet_preview_api_enabled: true,\n responsive_web_graphql_timeline_navigation_enabled: true,\n responsive_web_graphql_skip_user_profile_image_extensions_enabled: false,\n premium_content_api_read_enabled: false, communities_web_enable_tweet_community_results_fetch: true,\n c9s_tweet_anatomy_moderator_badge_enabled: true,\n articles_preview_enabled: true, responsive_web_edit_tweet_api_enabled: true,\n graphql_is_translatable_rweb_tweet_is_translatable_enabled: true,\n view_counts_everywhere_api_enabled: true, longform_notetweets_consumption_enabled: true,\n responsive_web_twitter_article_tweet_consumption_enabled: true,\n tweet_awards_web_tipping_enabled: false,\n content_disclosure_indicator_enabled: true, content_disclosure_ai_generated_indicator_enabled: true,\n freedom_of_speech_not_reach_fetch_enabled: true, standardized_nudges_misinfo: true,\n tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true,\n longform_notetweets_rich_text_read_enabled: true, longform_notetweets_inline_media_enabled: false,\n responsive_web_enhance_cards_enabled: false\n });\n const url = '/i/api/graphql/Fy0QMy4q_aZCpkO0PnyLYw/Bookmarks?variables=' + encodeURIComponent(variables) + '&features=' + encodeURIComponent(features);\n const resp = await fetch(url, {headers: _h, credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + '. Hint: queryId may have changed.');\n const d = await resp.json();\n\n const instructions = d.data?.bookmark_timeline_v2?.timeline?.instructions || d.data?.bookmark_timeline?.timeline?.instructions || [];\n let tweets = [], seen = new Set();\n for (const inst of instructions) {\n for (const entry of (inst.entries || [])) {\n const r = entry.content?.itemContent?.tweet_results?.result;\n if (!r) continue;\n const tw = r.tweet || r;\n const l = tw.legacy || {};\n if (!tw.rest_id || seen.has(tw.rest_id)) continue;\n seen.add(tw.rest_id);\n const u = tw.core?.user_results?.result;\n const nt = tw.note_tweet?.note_tweet_results?.result?.text;\n const screenName = u?.legacy?.screen_name || u?.core?.screen_name;\n tweets.push({\n id: tw.rest_id, \n author: screenName,\n name: u?.legacy?.name || u?.core?.name,\n url: 'https://x.com/' + (screenName || '_') + '/status/' + tw.rest_id,\n text: nt || l.full_text || '',\n likes: l.favorite_count, \n retweets: l.retweet_count,\n created_at: l.created_at\n });\n }\n }\n return tweets;\n})()\n"
834
+ },
835
+ {
836
+ "map": {
837
+ "author": "${{ item.author }}",
838
+ "text": "${{ item.text }}",
839
+ "likes": "${{ item.likes }}",
840
+ "url": "${{ item.url }}"
841
+ }
842
+ },
843
+ {
844
+ "limit": "${{ args.limit }}"
845
+ }
846
+ ],
847
+ "type": "yaml"
848
+ },
849
+ {
850
+ "site": "twitter",
851
+ "name": "profile",
852
+ "description": "Fetch tweets from a user profile",
853
+ "strategy": "intercept",
854
+ "browser": true,
855
+ "args": [
856
+ {
857
+ "name": "username",
858
+ "type": "string",
859
+ "required": true,
860
+ "help": ""
861
+ },
862
+ {
863
+ "name": "limit",
864
+ "type": "int",
865
+ "default": 15,
866
+ "required": false,
867
+ "help": ""
868
+ }
869
+ ],
870
+ "type": "ts",
871
+ "modulePath": "twitter/profile.js",
872
+ "domain": "x.com",
873
+ "columns": [
874
+ "id",
875
+ "text",
876
+ "likes",
877
+ "views",
878
+ "url"
879
+ ]
880
+ },
881
+ {
882
+ "site": "twitter",
883
+ "name": "search",
884
+ "description": "Search Twitter/X for tweets",
885
+ "strategy": "intercept",
886
+ "browser": true,
887
+ "args": [
888
+ {
889
+ "name": "query",
890
+ "type": "string",
891
+ "required": true,
892
+ "help": ""
893
+ },
894
+ {
895
+ "name": "limit",
896
+ "type": "int",
897
+ "default": 15,
898
+ "required": false,
899
+ "help": ""
900
+ }
901
+ ],
902
+ "type": "ts",
903
+ "modulePath": "twitter/search.js",
904
+ "domain": "x.com",
905
+ "columns": [
906
+ "id",
907
+ "author",
908
+ "text",
909
+ "likes",
910
+ "views",
911
+ "url"
912
+ ]
913
+ },
914
+ {
915
+ "site": "twitter",
916
+ "name": "timeline",
917
+ "description": "Twitter Home Timeline",
918
+ "strategy": "cookie",
919
+ "browser": true,
920
+ "args": [
921
+ {
922
+ "name": "limit",
923
+ "type": "int",
924
+ "default": 20,
925
+ "required": false,
926
+ "help": ""
927
+ }
928
+ ],
929
+ "type": "ts",
930
+ "modulePath": "twitter/timeline.js",
931
+ "domain": "x.com",
932
+ "columns": [
933
+ "responseType",
934
+ "first"
935
+ ]
936
+ },
937
+ {
938
+ "site": "twitter",
939
+ "name": "trending",
940
+ "description": "Twitter/X trending topics",
941
+ "domain": "x.com",
942
+ "strategy": "cookie",
943
+ "browser": true,
944
+ "args": [
945
+ {
946
+ "name": "limit",
947
+ "type": "int",
948
+ "default": 20,
949
+ "required": false,
950
+ "help": "Number of trends to show"
951
+ }
952
+ ],
953
+ "columns": [
954
+ "rank",
955
+ "topic",
956
+ "tweets"
957
+ ],
958
+ "pipeline": [
959
+ {
960
+ "navigate": "https://x.com/explore/tabs/trending"
961
+ },
962
+ {
963
+ "evaluate": "(async () => {\n const cookies = document.cookie.split(';').reduce((acc, c) => {\n const [k, v] = c.trim().split('=');\n acc[k] = v;\n return acc;\n }, {});\n const csrfToken = cookies['ct0'] || '';\n const bearerToken = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA';\n const res = await fetch('/i/api/2/guide.json?include_page_configuration=true', {\n credentials: 'include',\n headers: { 'x-twitter-active-user': 'yes', 'x-csrf-token': csrfToken, 'authorization': 'Bearer ' + bearerToken }\n });\n const data = await res.json();\n const trends = data?.timeline?.instructions?.[1]?.addEntries?.entries || [];\n return trends.filter(e => e.content?.timelineModule).flatMap(e => e.content.timelineModule.items || []).map(t => t?.item?.content?.trend).filter(Boolean);\n})()\n"
964
+ },
965
+ {
966
+ "map": {
967
+ "rank": "${{ index + 1 }}",
968
+ "topic": "${{ item.name }}",
969
+ "tweets": "${{ item.tweetCount || 'N/A' }}"
970
+ }
971
+ },
972
+ {
973
+ "limit": "${{ args.limit }}"
974
+ }
975
+ ],
976
+ "type": "yaml"
977
+ },
978
+ {
979
+ "site": "v2ex",
980
+ "name": "hot",
981
+ "description": "V2EX 热门话题",
982
+ "domain": "www.v2ex.com",
983
+ "strategy": "public",
984
+ "browser": false,
985
+ "args": [
986
+ {
987
+ "name": "limit",
988
+ "type": "int",
989
+ "default": 20,
990
+ "required": false,
991
+ "help": "Number of topics"
992
+ }
993
+ ],
994
+ "columns": [
995
+ "rank",
996
+ "title",
997
+ "replies"
998
+ ],
999
+ "pipeline": [
1000
+ {
1001
+ "fetch": {
1002
+ "url": "https://www.v2ex.com/api/topics/hot.json"
1003
+ }
1004
+ },
1005
+ {
1006
+ "map": {
1007
+ "rank": "${{ index + 1 }}",
1008
+ "title": "${{ item.title }}",
1009
+ "replies": "${{ item.replies }}"
1010
+ }
1011
+ },
1012
+ {
1013
+ "limit": "${{ args.limit }}"
1014
+ }
1015
+ ],
1016
+ "type": "yaml"
1017
+ },
1018
+ {
1019
+ "site": "v2ex",
1020
+ "name": "latest",
1021
+ "description": "V2EX 最新话题",
1022
+ "domain": "www.v2ex.com",
1023
+ "strategy": "public",
1024
+ "browser": false,
1025
+ "args": [
1026
+ {
1027
+ "name": "limit",
1028
+ "type": "int",
1029
+ "default": 20,
1030
+ "required": false,
1031
+ "help": "Number of topics"
1032
+ }
1033
+ ],
1034
+ "columns": [
1035
+ "rank",
1036
+ "title",
1037
+ "replies"
1038
+ ],
1039
+ "pipeline": [
1040
+ {
1041
+ "fetch": {
1042
+ "url": "https://www.v2ex.com/api/topics/latest.json"
1043
+ }
1044
+ },
1045
+ {
1046
+ "map": {
1047
+ "rank": "${{ index + 1 }}",
1048
+ "title": "${{ item.title }}",
1049
+ "replies": "${{ item.replies }}"
1050
+ }
1051
+ },
1052
+ {
1053
+ "limit": "${{ args.limit }}"
1054
+ }
1055
+ ],
1056
+ "type": "yaml"
1057
+ },
1058
+ {
1059
+ "site": "v2ex",
1060
+ "name": "topic",
1061
+ "description": "V2EX 主题详情和回复",
1062
+ "domain": "www.v2ex.com",
1063
+ "strategy": "public",
1064
+ "browser": false,
1065
+ "args": [
1066
+ {
1067
+ "name": "id",
1068
+ "type": "str",
1069
+ "required": true,
1070
+ "help": "Topic ID"
1071
+ }
1072
+ ],
1073
+ "columns": [
1074
+ "title",
1075
+ "replies",
1076
+ "url"
1077
+ ],
1078
+ "pipeline": [
1079
+ {
1080
+ "fetch": {
1081
+ "url": "https://www.v2ex.com/api/topics/show.json",
1082
+ "params": {
1083
+ "id": "${{ args.id }}"
1084
+ }
1085
+ }
1086
+ },
1087
+ {
1088
+ "map": {
1089
+ "title": "${{ item.title }}",
1090
+ "replies": "${{ item.replies }}",
1091
+ "url": "${{ item.url }}"
1092
+ }
1093
+ },
1094
+ {
1095
+ "limit": 1
1096
+ }
1097
+ ],
1098
+ "type": "yaml"
1099
+ },
1100
+ {
1101
+ "site": "weibo",
1102
+ "name": "hot",
1103
+ "description": "微博热搜",
1104
+ "strategy": "cookie",
1105
+ "browser": true,
1106
+ "args": [
1107
+ {
1108
+ "name": "limit",
1109
+ "type": "int",
1110
+ "default": 30,
1111
+ "required": false,
1112
+ "help": "Number of items (max 50)"
1113
+ }
1114
+ ],
1115
+ "type": "ts",
1116
+ "modulePath": "weibo/hot.js",
1117
+ "domain": "weibo.com",
1118
+ "columns": [
1119
+ "rank",
1120
+ "word",
1121
+ "hot_value",
1122
+ "category",
1123
+ "label",
1124
+ "url"
1125
+ ]
1126
+ },
1127
+ {
1128
+ "site": "xiaohongshu",
1129
+ "name": "feed",
1130
+ "description": "小红书首页推荐 Feed (via Pinia Store Action)",
1131
+ "domain": "www.xiaohongshu.com",
1132
+ "strategy": "intercept",
1133
+ "browser": true,
1134
+ "args": [
1135
+ {
1136
+ "name": "limit",
1137
+ "type": "int",
1138
+ "default": 20,
1139
+ "required": false,
1140
+ "help": "Number of items to return"
1141
+ }
1142
+ ],
1143
+ "columns": [
1144
+ "title",
1145
+ "author",
1146
+ "likes",
1147
+ "type",
1148
+ "url"
1149
+ ],
1150
+ "pipeline": [
1151
+ {
1152
+ "navigate": "https://www.xiaohongshu.com/explore"
1153
+ },
1154
+ {
1155
+ "wait": 3
1156
+ },
1157
+ {
1158
+ "tap": {
1159
+ "store": "feed",
1160
+ "action": "fetchFeeds",
1161
+ "capture": "homefeed",
1162
+ "select": "data.items",
1163
+ "timeout": 8
1164
+ }
1165
+ },
1166
+ {
1167
+ "map": {
1168
+ "id": "${{ item.id }}",
1169
+ "title": "${{ item.note_card.display_title }}",
1170
+ "type": "${{ item.note_card.type }}",
1171
+ "author": "${{ item.note_card.user.nickname }}",
1172
+ "likes": "${{ item.note_card.interact_info.liked_count }}",
1173
+ "url": "https://www.xiaohongshu.com/explore/${{ item.id }}"
1174
+ }
1175
+ },
1176
+ {
1177
+ "limit": "${{ args.limit | default(20) }}"
1178
+ }
1179
+ ],
1180
+ "type": "yaml"
1181
+ },
1182
+ {
1183
+ "site": "xiaohongshu",
1184
+ "name": "notifications",
1185
+ "description": "小红书通知 (mentions/likes/connections)",
1186
+ "domain": "www.xiaohongshu.com",
1187
+ "strategy": "intercept",
1188
+ "browser": true,
1189
+ "args": [
1190
+ {
1191
+ "name": "type",
1192
+ "type": "str",
1193
+ "default": "mentions",
1194
+ "required": false,
1195
+ "help": "Notification type: mentions, likes, or connections"
1196
+ },
1197
+ {
1198
+ "name": "limit",
1199
+ "type": "int",
1200
+ "default": 20,
1201
+ "required": false,
1202
+ "help": "Number of notifications to return"
1203
+ }
1204
+ ],
1205
+ "columns": [
1206
+ "rank",
1207
+ "user",
1208
+ "action",
1209
+ "content",
1210
+ "note",
1211
+ "time"
1212
+ ],
1213
+ "pipeline": [
1214
+ {
1215
+ "navigate": "https://www.xiaohongshu.com/notification"
1216
+ },
1217
+ {
1218
+ "wait": 3
1219
+ },
1220
+ {
1221
+ "tap": {
1222
+ "store": "notification",
1223
+ "action": "getNotification",
1224
+ "args": [
1225
+ "${{ args.type | default('mentions') }}"
1226
+ ],
1227
+ "capture": "/you/",
1228
+ "select": "data.message_list",
1229
+ "timeout": 8
1230
+ }
1231
+ },
1232
+ {
1233
+ "map": {
1234
+ "rank": "${{ index + 1 }}",
1235
+ "user": "${{ item.user_info.nickname }}",
1236
+ "action": "${{ item.title }}",
1237
+ "content": "${{ item.comment_info.content }}",
1238
+ "note": "${{ item.item_info.content }}",
1239
+ "time": "${{ item.time }}"
1240
+ }
1241
+ },
1242
+ {
1243
+ "limit": "${{ args.limit | default(20) }}"
1244
+ }
1245
+ ],
1246
+ "type": "yaml"
1247
+ },
1248
+ {
1249
+ "site": "xiaohongshu",
1250
+ "name": "search",
1251
+ "description": "搜索小红书笔记",
1252
+ "strategy": "cookie",
1253
+ "browser": true,
1254
+ "args": [
1255
+ {
1256
+ "name": "keyword",
1257
+ "type": "str",
1258
+ "required": true,
1259
+ "help": "Search keyword"
1260
+ },
1261
+ {
1262
+ "name": "limit",
1263
+ "type": "int",
1264
+ "default": 20,
1265
+ "required": false,
1266
+ "help": "Number of results"
1267
+ }
1268
+ ],
1269
+ "type": "ts",
1270
+ "modulePath": "xiaohongshu/search.js",
1271
+ "domain": "www.xiaohongshu.com",
1272
+ "columns": [
1273
+ "rank",
1274
+ "title",
1275
+ "author",
1276
+ "likes"
1277
+ ]
1278
+ },
1279
+ {
1280
+ "site": "xiaohongshu",
1281
+ "name": "user",
1282
+ "description": "Get user notes from Xiaohongshu",
1283
+ "strategy": "intercept",
1284
+ "browser": true,
1285
+ "args": [
1286
+ {
1287
+ "name": "id",
1288
+ "type": "string",
1289
+ "required": true,
1290
+ "help": ""
1291
+ },
1292
+ {
1293
+ "name": "limit",
1294
+ "type": "int",
1295
+ "default": 15,
1296
+ "required": false,
1297
+ "help": ""
1298
+ }
1299
+ ],
1300
+ "type": "ts",
1301
+ "modulePath": "xiaohongshu/user.js",
1302
+ "domain": "xiaohongshu.com",
1303
+ "columns": [
1304
+ "id",
1305
+ "title",
1306
+ "type",
1307
+ "likes",
1308
+ "url"
1309
+ ]
1310
+ },
1311
+ {
1312
+ "site": "xueqiu",
1313
+ "name": "feed",
1314
+ "description": "获取雪球首页时间线(关注用户的动态)",
1315
+ "domain": "xueqiu.com",
1316
+ "strategy": "cookie",
1317
+ "browser": true,
1318
+ "args": [
1319
+ {
1320
+ "name": "page",
1321
+ "type": "int",
1322
+ "default": 1,
1323
+ "required": false,
1324
+ "help": "页码,默认 1"
1325
+ },
1326
+ {
1327
+ "name": "limit",
1328
+ "type": "int",
1329
+ "default": 20,
1330
+ "required": false,
1331
+ "help": "每页数量,默认 20"
1332
+ }
1333
+ ],
1334
+ "columns": [
1335
+ "author",
1336
+ "text",
1337
+ "likes",
1338
+ "replies",
1339
+ "url"
1340
+ ],
1341
+ "pipeline": [
1342
+ {
1343
+ "navigate": "https://xueqiu.com"
1344
+ },
1345
+ {
1346
+ "evaluate": "(async () => {\n const page = ${{ args.page }};\n const count = ${{ args.limit }};\n const resp = await fetch(`https://xueqiu.com/v4/statuses/home_timeline.json?page=${page}&count=${count}`, {credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + ' Hint: Not logged in?');\n const d = await resp.json();\n \n const strip = (html) => (html || '').replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').trim();\n const list = d.home_timeline || d.list || [];\n return list.map(item => {\n const user = item.user || {};\n return {\n id: item.id,\n text: strip(item.description).substring(0, 200),\n url: 'https://xueqiu.com/' + user.id + '/' + item.id,\n author: user.screen_name,\n likes: item.fav_count,\n retweets: item.retweet_count,\n replies: item.reply_count,\n created_at: item.created_at ? new Date(item.created_at).toISOString() : null\n };\n });\n})()\n"
1347
+ },
1348
+ {
1349
+ "map": {
1350
+ "author": "${{ item.author }}",
1351
+ "text": "${{ item.text }}",
1352
+ "likes": "${{ item.likes }}",
1353
+ "replies": "${{ item.replies }}",
1354
+ "url": "${{ item.url }}"
1355
+ }
1356
+ },
1357
+ {
1358
+ "limit": "${{ args.limit }}"
1359
+ }
1360
+ ],
1361
+ "type": "yaml"
1362
+ },
1363
+ {
1364
+ "site": "xueqiu",
1365
+ "name": "hot-stock",
1366
+ "description": "获取雪球热门股票榜",
1367
+ "domain": "xueqiu.com",
1368
+ "strategy": "cookie",
1369
+ "browser": true,
1370
+ "args": [
1371
+ {
1372
+ "name": "limit",
1373
+ "type": "int",
1374
+ "default": 20,
1375
+ "required": false,
1376
+ "help": "返回数量,默认 20,最大 50"
1377
+ },
1378
+ {
1379
+ "name": "type",
1380
+ "type": "str",
1381
+ "default": "10",
1382
+ "required": false,
1383
+ "help": "榜单类型 10=人气榜(默认) 12=关注榜"
1384
+ }
1385
+ ],
1386
+ "columns": [
1387
+ "rank",
1388
+ "symbol",
1389
+ "name",
1390
+ "price",
1391
+ "changePercent",
1392
+ "heat"
1393
+ ],
1394
+ "pipeline": [
1395
+ {
1396
+ "navigate": "https://xueqiu.com"
1397
+ },
1398
+ {
1399
+ "evaluate": "(async () => {\n const count = ${{ args.limit }};\n const type = ${{ args.type | json }};\n const resp = await fetch(`https://stock.xueqiu.com/v5/stock/hot_stock/list.json?size=${count}&type=${type}`, {credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + ' Hint: Not logged in?');\n const d = await resp.json();\n if (!d.data || !d.data.items) throw new Error('获取失败');\n return d.data.items.map((s, i) => ({\n rank: i + 1,\n symbol: s.symbol,\n name: s.name,\n price: s.current,\n changePercent: s.percent != null ? s.percent.toFixed(2) + '%' : null,\n heat: s.value,\n rank_change: s.rank_change,\n url: 'https://xueqiu.com/S/' + s.symbol\n }));\n})()\n"
1400
+ },
1401
+ {
1402
+ "map": {
1403
+ "rank": "${{ item.rank }}",
1404
+ "symbol": "${{ item.symbol }}",
1405
+ "name": "${{ item.name }}",
1406
+ "price": "${{ item.price }}",
1407
+ "changePercent": "${{ item.changePercent }}",
1408
+ "heat": "${{ item.heat }}"
1409
+ }
1410
+ },
1411
+ {
1412
+ "limit": "${{ args.limit }}"
1413
+ }
1414
+ ],
1415
+ "type": "yaml"
1416
+ },
1417
+ {
1418
+ "site": "xueqiu",
1419
+ "name": "hot",
1420
+ "description": "获取雪球热门动态",
1421
+ "domain": "xueqiu.com",
1422
+ "strategy": "cookie",
1423
+ "browser": true,
1424
+ "args": [
1425
+ {
1426
+ "name": "limit",
1427
+ "type": "int",
1428
+ "default": 20,
1429
+ "required": false,
1430
+ "help": "返回数量,默认 20,最大 50"
1431
+ }
1432
+ ],
1433
+ "columns": [
1434
+ "rank",
1435
+ "author",
1436
+ "text",
1437
+ "likes",
1438
+ "url"
1439
+ ],
1440
+ "pipeline": [
1441
+ {
1442
+ "navigate": "https://xueqiu.com"
1443
+ },
1444
+ {
1445
+ "evaluate": "(async () => {\n const resp = await fetch('https://xueqiu.com/statuses/hot/listV3.json?source=hot&page=1', {credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + ' Hint: Not logged in?');\n const d = await resp.json();\n const list = d.list || [];\n \n const strip = (html) => (html || '').replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').trim();\n return list.map((item, i) => {\n const user = item.user || {};\n return {\n rank: i + 1,\n text: strip(item.description).substring(0, 200),\n url: 'https://xueqiu.com/' + user.id + '/' + item.id,\n author: user.screen_name,\n likes: item.fav_count,\n retweets: item.retweet_count,\n replies: item.reply_count\n };\n });\n})()\n"
1446
+ },
1447
+ {
1448
+ "map": {
1449
+ "rank": "${{ item.rank }}",
1450
+ "author": "${{ item.author }}",
1451
+ "text": "${{ item.text }}",
1452
+ "likes": "${{ item.likes }}",
1453
+ "url": "${{ item.url }}"
1454
+ }
1455
+ },
1456
+ {
1457
+ "limit": "${{ args.limit }}"
1458
+ }
1459
+ ],
1460
+ "type": "yaml"
1461
+ },
1462
+ {
1463
+ "site": "xueqiu",
1464
+ "name": "search",
1465
+ "description": "搜索雪球股票(代码或名称)",
1466
+ "domain": "xueqiu.com",
1467
+ "strategy": "cookie",
1468
+ "browser": true,
1469
+ "args": [
1470
+ {
1471
+ "name": "query",
1472
+ "type": "str",
1473
+ "required": false,
1474
+ "help": "搜索关键词,如 茅台、AAPL、腾讯"
1475
+ },
1476
+ {
1477
+ "name": "limit",
1478
+ "type": "int",
1479
+ "default": 10,
1480
+ "required": false,
1481
+ "help": "返回数量,默认 10"
1482
+ }
1483
+ ],
1484
+ "columns": [
1485
+ "symbol",
1486
+ "name",
1487
+ "exchange",
1488
+ "price",
1489
+ "changePercent"
1490
+ ],
1491
+ "pipeline": [
1492
+ {
1493
+ "navigate": "https://xueqiu.com"
1494
+ },
1495
+ {
1496
+ "evaluate": "(async () => {\n const query = ${{ args.query | json }};\n const count = ${{ args.limit }};\n if (!query) throw new Error('Missing argument: query');\n const resp = await fetch(`https://xueqiu.com/stock/search.json?code=${encodeURIComponent(query)}&size=${count}`, {credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + ' Hint: Not logged in?');\n const d = await resp.json();\n return (d.stocks || []).map(s => {\n let symbol = '';\n if (s.exchange === 'SH' || s.exchange === 'SZ' || s.exchange === 'BJ') {\n symbol = s.code.startsWith(s.exchange) ? s.code : s.exchange + s.code;\n } else {\n symbol = s.code;\n }\n return {\n symbol: symbol,\n name: s.name,\n exchange: s.exchange,\n price: s.current,\n changePercent: s.percentage != null ? s.percentage.toFixed(2) + '%' : null,\n url: 'https://xueqiu.com/S/' + symbol\n };\n });\n})()\n"
1497
+ },
1498
+ {
1499
+ "map": {
1500
+ "symbol": "${{ item.symbol }}",
1501
+ "name": "${{ item.name }}",
1502
+ "exchange": "${{ item.exchange }}",
1503
+ "price": "${{ item.price }}",
1504
+ "changePercent": "${{ item.changePercent }}"
1505
+ }
1506
+ },
1507
+ {
1508
+ "limit": "${{ args.limit }}"
1509
+ }
1510
+ ],
1511
+ "type": "yaml"
1512
+ },
1513
+ {
1514
+ "site": "xueqiu",
1515
+ "name": "stock",
1516
+ "description": "获取雪球股票实时行情",
1517
+ "domain": "xueqiu.com",
1518
+ "strategy": "cookie",
1519
+ "browser": true,
1520
+ "args": [
1521
+ {
1522
+ "name": "symbol",
1523
+ "type": "str",
1524
+ "required": false,
1525
+ "help": "股票代码,如 SH600519、SZ000858、AAPL、00700"
1526
+ }
1527
+ ],
1528
+ "columns": [
1529
+ "name",
1530
+ "symbol",
1531
+ "price",
1532
+ "changePercent",
1533
+ "marketCap"
1534
+ ],
1535
+ "pipeline": [
1536
+ {
1537
+ "navigate": "https://xueqiu.com"
1538
+ },
1539
+ {
1540
+ "evaluate": "(async () => {\n const symbol = (${{ args.symbol | json }} || '').toUpperCase();\n if (!symbol) throw new Error('Missing argument: symbol');\n const resp = await fetch(`https://stock.xueqiu.com/v5/stock/batch/quote.json?symbol=${encodeURIComponent(symbol)}`, {credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + ' Hint: Not logged in?');\n const d = await resp.json();\n if (!d.data || !d.data.items || d.data.items.length === 0) throw new Error('未找到股票: ' + symbol);\n \n function fmtAmount(v) {\n if (v == null) return null;\n if (Math.abs(v) >= 1e12) return (v / 1e12).toFixed(2) + '万亿';\n if (Math.abs(v) >= 1e8) return (v / 1e8).toFixed(2) + '亿';\n if (Math.abs(v) >= 1e4) return (v / 1e4).toFixed(2) + '万';\n return v.toString();\n }\n \n const item = d.data.items[0];\n const q = item.quote || {};\n const m = item.market || {};\n \n return [{\n name: q.name,\n symbol: q.symbol,\n exchange: q.exchange,\n currency: q.currency,\n price: q.current,\n change: q.chg,\n changePercent: q.percent != null ? q.percent.toFixed(2) + '%' : null,\n open: q.open,\n high: q.high,\n low: q.low,\n prevClose: q.last_close,\n amplitude: q.amplitude != null ? q.amplitude.toFixed(2) + '%' : null,\n volume: q.volume,\n amount: fmtAmount(q.amount),\n turnover_rate: q.turnover_rate != null ? q.turnover_rate.toFixed(2) + '%' : null,\n marketCap: fmtAmount(q.market_capital),\n floatMarketCap: fmtAmount(q.float_market_capital),\n ytdPercent: q.current_year_percent != null ? q.current_year_percent.toFixed(2) + '%' : null,\n market_status: m.status || null,\n time: q.timestamp ? new Date(q.timestamp).toISOString() : null,\n url: 'https://xueqiu.com/S/' + q.symbol\n }];\n})()\n"
1541
+ },
1542
+ {
1543
+ "map": {
1544
+ "name": "${{ item.name }}",
1545
+ "symbol": "${{ item.symbol }}",
1546
+ "price": "${{ item.price }}",
1547
+ "changePercent": "${{ item.changePercent }}",
1548
+ "marketCap": "${{ item.marketCap }}"
1549
+ }
1550
+ }
1551
+ ],
1552
+ "type": "yaml"
1553
+ },
1554
+ {
1555
+ "site": "xueqiu",
1556
+ "name": "watchlist",
1557
+ "description": "获取雪球自选股列表",
1558
+ "domain": "xueqiu.com",
1559
+ "strategy": "cookie",
1560
+ "browser": true,
1561
+ "args": [
1562
+ {
1563
+ "name": "category",
1564
+ "type": "str",
1565
+ "default": "1",
1566
+ "required": false,
1567
+ "help": "分类:1=自选(默认) 2=持仓 3=关注"
1568
+ },
1569
+ {
1570
+ "name": "limit",
1571
+ "type": "int",
1572
+ "default": 100,
1573
+ "required": false,
1574
+ "help": "默认 100"
1575
+ }
1576
+ ],
1577
+ "columns": [
1578
+ "symbol",
1579
+ "name",
1580
+ "price",
1581
+ "changePercent"
1582
+ ],
1583
+ "pipeline": [
1584
+ {
1585
+ "navigate": "https://xueqiu.com"
1586
+ },
1587
+ {
1588
+ "evaluate": "(async () => {\n const category = parseInt(${{ args.category | json }}) || 1;\n const resp = await fetch(`https://stock.xueqiu.com/v5/stock/portfolio/stock/list.json?size=100&category=${category}&pid=-1`, {credentials: 'include'});\n if (!resp.ok) throw new Error('HTTP ' + resp.status + ' Hint: Not logged in?');\n const d = await resp.json();\n if (!d.data || !d.data.stocks) throw new Error('获取失败,可能未登录');\n \n return d.data.stocks.map(s => ({\n symbol: s.symbol,\n name: s.name,\n price: s.current,\n change: s.chg,\n changePercent: s.percent != null ? s.percent.toFixed(2) + '%' : null,\n volume: s.volume,\n url: 'https://xueqiu.com/S/' + s.symbol\n }));\n})()\n"
1589
+ },
1590
+ {
1591
+ "map": {
1592
+ "symbol": "${{ item.symbol }}",
1593
+ "name": "${{ item.name }}",
1594
+ "price": "${{ item.price }}",
1595
+ "changePercent": "${{ item.changePercent }}"
1596
+ }
1597
+ },
1598
+ {
1599
+ "limit": "${{ args.limit }}"
1600
+ }
1601
+ ],
1602
+ "type": "yaml"
1603
+ },
1604
+ {
1605
+ "site": "yahoo-finance",
1606
+ "name": "quote",
1607
+ "description": "Yahoo Finance 股票行情",
1608
+ "strategy": "cookie",
1609
+ "browser": true,
1610
+ "args": [
1611
+ {
1612
+ "name": "symbol",
1613
+ "type": "str",
1614
+ "required": true,
1615
+ "help": "Stock ticker (e.g. AAPL, MSFT, TSLA)"
1616
+ }
1617
+ ],
1618
+ "type": "ts",
1619
+ "modulePath": "yahoo-finance/quote.js",
1620
+ "domain": "finance.yahoo.com",
1621
+ "columns": [
1622
+ "symbol",
1623
+ "name",
1624
+ "price",
1625
+ "change",
1626
+ "changePercent",
1627
+ "open",
1628
+ "high",
1629
+ "low",
1630
+ "volume",
1631
+ "marketCap"
1632
+ ]
1633
+ },
1634
+ {
1635
+ "site": "youtube",
1636
+ "name": "search",
1637
+ "description": "Search YouTube videos",
1638
+ "strategy": "cookie",
1639
+ "browser": true,
1640
+ "args": [
1641
+ {
1642
+ "name": "query",
1643
+ "type": "str",
1644
+ "required": true,
1645
+ "help": "Search query"
1646
+ },
1647
+ {
1648
+ "name": "limit",
1649
+ "type": "int",
1650
+ "default": 20,
1651
+ "required": false,
1652
+ "help": "Max results (max 50)"
1653
+ }
1654
+ ],
1655
+ "type": "ts",
1656
+ "modulePath": "youtube/search.js",
1657
+ "domain": "www.youtube.com",
1658
+ "columns": [
1659
+ "rank",
1660
+ "title",
1661
+ "channel",
1662
+ "views",
1663
+ "duration",
1664
+ "url"
1665
+ ]
1666
+ },
1667
+ {
1668
+ "site": "zhihu",
1669
+ "name": "hot",
1670
+ "description": "知乎热榜",
1671
+ "domain": "www.zhihu.com",
1672
+ "strategy": "cookie",
1673
+ "browser": true,
1674
+ "args": [
1675
+ {
1676
+ "name": "limit",
1677
+ "type": "int",
1678
+ "default": 20,
1679
+ "required": false,
1680
+ "help": "Number of items to return"
1681
+ }
1682
+ ],
1683
+ "columns": [
1684
+ "rank",
1685
+ "title",
1686
+ "heat",
1687
+ "answers"
1688
+ ],
1689
+ "pipeline": [
1690
+ {
1691
+ "navigate": "https://www.zhihu.com"
1692
+ },
1693
+ {
1694
+ "evaluate": "(async () => {\n const res = await fetch('https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50', {\n credentials: 'include'\n });\n const text = await res.text();\n const d = JSON.parse(\n text.replace(/(\"id\"\\s*:\\s*)(\\d{16,})/g, '$1\"$2\"')\n );\n return (d?.data || []).map((item) => {\n const t = item.target || {};\n const questionId = t.id == null ? '' : String(t.id);\n return {\n title: t.title,\n url: 'https://www.zhihu.com/question/' + questionId,\n answer_count: t.answer_count,\n follower_count: t.follower_count,\n heat: item.detail_text || '',\n };\n });\n})()\n"
1695
+ },
1696
+ {
1697
+ "map": {
1698
+ "rank": "${{ index + 1 }}",
1699
+ "title": "${{ item.title }}",
1700
+ "heat": "${{ item.heat }}",
1701
+ "answers": "${{ item.answer_count }}",
1702
+ "url": "${{ item.url }}"
1703
+ }
1704
+ },
1705
+ {
1706
+ "limit": "${{ args.limit }}"
1707
+ }
1708
+ ],
1709
+ "type": "yaml"
1710
+ },
1711
+ {
1712
+ "site": "zhihu",
1713
+ "name": "question",
1714
+ "description": "知乎问题详情和回答",
1715
+ "strategy": "cookie",
1716
+ "browser": true,
1717
+ "args": [
1718
+ {
1719
+ "name": "id",
1720
+ "type": "str",
1721
+ "required": true,
1722
+ "help": "Question ID (numeric)"
1723
+ },
1724
+ {
1725
+ "name": "limit",
1726
+ "type": "int",
1727
+ "default": 5,
1728
+ "required": false,
1729
+ "help": "Number of answers"
1730
+ }
1731
+ ],
1732
+ "type": "ts",
1733
+ "modulePath": "zhihu/question.js",
1734
+ "domain": "www.zhihu.com",
1735
+ "columns": [
1736
+ "rank",
1737
+ "author",
1738
+ "votes",
1739
+ "content"
1740
+ ]
1741
+ },
1742
+ {
1743
+ "site": "zhihu",
1744
+ "name": "search",
1745
+ "description": "知乎搜索",
1746
+ "domain": "www.zhihu.com",
1747
+ "strategy": "cookie",
1748
+ "browser": true,
1749
+ "args": [
1750
+ {
1751
+ "name": "keyword",
1752
+ "type": "str",
1753
+ "required": true,
1754
+ "help": "Search keyword"
1755
+ },
1756
+ {
1757
+ "name": "limit",
1758
+ "type": "int",
1759
+ "default": 10,
1760
+ "required": false,
1761
+ "help": "Number of results"
1762
+ }
1763
+ ],
1764
+ "columns": [
1765
+ "rank",
1766
+ "title",
1767
+ "type",
1768
+ "author",
1769
+ "votes"
1770
+ ],
1771
+ "pipeline": [
1772
+ {
1773
+ "navigate": "https://www.zhihu.com"
1774
+ },
1775
+ {
1776
+ "evaluate": "(async () => {\n const strip = (html) => (html || '').replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/<em>/g, '').replace(/<\\/em>/g, '').trim();\n const keyword = ${{ args.keyword | json }};\n const limit = ${{ args.limit }};\n const res = await fetch('https://www.zhihu.com/api/v4/search_v3?q=' + encodeURIComponent(keyword) + '&t=general&offset=0&limit=' + limit, {\n credentials: 'include'\n });\n const d = await res.json();\n return (d?.data || [])\n .filter(item => item.type === 'search_result')\n .map(item => {\n const obj = item.object || {};\n const q = obj.question || {};\n return {\n type: obj.type,\n title: strip(obj.title || q.name || ''),\n excerpt: strip(obj.excerpt || '').substring(0, 100),\n author: obj.author?.name || '',\n votes: obj.voteup_count || 0,\n url: obj.type === 'answer'\n ? 'https://www.zhihu.com/question/' + q.id + '/answer/' + obj.id\n : obj.type === 'article'\n ? 'https://zhuanlan.zhihu.com/p/' + obj.id\n : 'https://www.zhihu.com/question/' + obj.id,\n };\n });\n})()\n"
1777
+ },
1778
+ {
1779
+ "map": {
1780
+ "rank": "${{ index + 1 }}",
1781
+ "title": "${{ item.title }}",
1782
+ "type": "${{ item.type }}",
1783
+ "author": "${{ item.author }}",
1784
+ "votes": "${{ item.votes }}"
1785
+ }
1786
+ },
1787
+ {
1788
+ "limit": "${{ args.limit }}"
1789
+ }
1790
+ ],
1791
+ "type": "yaml"
1792
+ }
1793
+ ]