@agentrhq/webcmd 0.1.2 → 0.2.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.
- package/README.md +183 -218
- package/cli-manifest.json +16247 -34913
- package/clis/_atlassian/shared.js +1 -1
- package/clis/booking/search.js +4 -4
- package/clis/chatgpt/ask.js +2 -2
- package/clis/chatgpt/utils.js +41 -42
- package/clis/chatgpt/utils.test.js +23 -23
- package/clis/chatgpt-app/ax.js +5 -5
- package/clis/chatgpt-app/ax.test.js +8 -8
- package/clis/chatgpt-app/new.js +2 -2
- package/clis/codex/sidebar.js +1 -1
- package/clis/codex/sidebar.test.js +12 -12
- package/clis/coingecko/top.js +3 -3
- package/clis/dblp/dblp.test.js +1 -1
- package/clis/discord-app/search.js +1 -1
- package/clis/discord-app/utils.js +6 -6
- package/clis/facebook/__fixtures__/notifications-page.html +6 -6
- package/clis/facebook/add-friend.js +2 -2
- package/clis/facebook/feed.js +18 -18
- package/clis/facebook/friends.js +4 -4
- package/clis/facebook/groups.js +3 -3
- package/clis/facebook/join-group.js +2 -2
- package/clis/facebook/marketplace-inbox.js +3 -3
- package/clis/facebook/marketplace-listings.js +1 -1
- package/clis/facebook/notifications.js +14 -15
- package/clis/facebook/notifications.test.js +28 -29
- package/clis/gemini/ask.test.js +12 -12
- package/clis/gemini/deep-research-result.js +2 -2
- package/clis/gemini/deep-research-result.test.js +2 -2
- package/clis/gemini/deep-research.js +2 -2
- package/clis/gemini/deep-research.test.js +1 -1
- package/clis/gemini/models.js +11 -11
- package/clis/gemini/models.test.js +1 -1
- package/clis/gemini/reply-state.test.js +89 -89
- package/clis/gemini/utils.js +41 -41
- package/clis/gemini/utils.test.js +30 -30
- package/clis/geogebra/utils.js +1 -1
- package/clis/google-scholar/search.js +3 -3
- package/clis/grok/delete.js +1 -1
- package/clis/grok/export-all.js +2 -2
- package/clis/grok/export.js +2 -2
- package/clis/grok/pin.js +3 -3
- package/clis/grok/utils.js +12 -12
- package/clis/grok/utils.test.js +2 -2
- package/clis/indeed/indeed.test.js +3 -3
- package/clis/indeed/utils.js +1 -1
- package/clis/instagram/post.js +19 -19
- package/clis/instagram/post.test.js +2 -2
- package/clis/instagram/reel.js +6 -6
- package/clis/linkedin/connect.js +3 -3
- package/clis/linkedin/people-search.js +4 -4
- package/clis/linkedin/profile-experience.js +6 -6
- package/clis/linkedin/profile-experience.test.js +10 -10
- package/clis/linkedin/profile-read.js +1 -1
- package/clis/linkedin/safe-send.js +1 -1
- package/clis/linkedin/search.js +1 -1
- package/clis/linkedin/shared.js +2 -2
- package/clis/linkedin/timeline.js +5 -5
- package/clis/manus/manus.test.js +2 -2
- package/clis/medium/feed.js +3 -3
- package/clis/medium/search.js +3 -3
- package/clis/medium/user.js +3 -3
- package/clis/notebooklm/auth.js +2 -2
- package/clis/notebooklm/note-list.test.js +4 -4
- package/clis/notebooklm/notes-get.test.js +8 -8
- package/clis/notebooklm/source-fulltext.test.js +11 -11
- package/clis/notebooklm/utils.js +28 -28
- package/clis/notebooklm/utils.test.js +10 -10
- package/clis/pixiv/search.test.js +3 -3
- package/clis/qoder/quest.js +2 -2
- package/clis/reddit/home.js +2 -2
- package/clis/reddit/hot.js +1 -1
- package/clis/reddit/read.js +2 -2
- package/clis/reddit/read.test.js +1 -1
- package/clis/reddit/reply.js +2 -2
- package/clis/reddit/whoami.js +2 -2
- package/clis/reuters/article-detail.js +1 -1
- package/clis/reuters/search.js +1 -1
- package/clis/slock/attachment-upload.test.js +1 -1
- package/clis/slock/task-convert.js +1 -1
- package/clis/substack/feed.js +3 -3
- package/clis/substack/publication.js +3 -3
- package/clis/substack/search.js +4 -4
- package/clis/tiktok/comment.js +2 -2
- package/clis/tiktok/follow.js +4 -4
- package/clis/tiktok/like.js +1 -1
- package/clis/tiktok/save.js +1 -1
- package/clis/tiktok/unfollow.js +4 -4
- package/clis/tiktok/unlike.js +1 -1
- package/clis/tiktok/unsave.js +2 -2
- package/clis/tiktok/write-refactor.test.js +5 -5
- package/clis/twitter/accept.js +3 -3
- package/clis/twitter/followers.js +1 -1
- package/clis/twitter/list-remove-core.js +2 -2
- package/clis/twitter/list-tweets.test.js +3 -3
- package/clis/twitter/lists.js +6 -6
- package/clis/twitter/lists.test.js +2 -2
- package/clis/twitter/reply-dm.js +1 -1
- package/clis/twitter/shared.test.js +4 -5
- package/clis/twitter/trending.js +1 -1
- package/clis/twitter/utils.js +1 -1
- package/clis/web/read.js +1 -1
- package/clis/web/read.test.js +2 -2
- package/clis/yahoo-finance/quote.js +1 -1
- package/clis/youtube/history.js +4 -4
- package/clis/youtube/transcript-group.js +1 -1
- package/clis/youtube/transcript-group.test.js +5 -5
- package/clis/youtube/transcript.js +5 -5
- package/clis/youtube/video.js +4 -4
- package/clis/youtube/video.test.js +6 -6
- package/dist/src/browser/analyze.test.js +13 -13
- package/dist/src/browser/bridge-readiness.d.ts +1 -1
- package/dist/src/browser/daemon-client.d.ts +1 -0
- package/dist/src/browser/daemon-client.js +102 -50
- package/dist/src/browser/daemon-client.test.js +104 -19
- package/dist/src/browser/errors.js +11 -0
- package/dist/src/browser/protocol.d.ts +2 -0
- package/dist/src/browser.test.js +2 -2
- package/dist/src/cli-argv-preprocess.d.ts +2 -2
- package/dist/src/cli-argv-preprocess.js +2 -2
- package/dist/src/cli-argv-preprocess.test.js +35 -35
- package/dist/src/cli.js +2 -2
- package/dist/src/cli.test.js +57 -57
- package/dist/src/commanderAdapter.test.js +19 -19
- package/dist/src/convention-audit.js +1 -1
- package/dist/src/daemon/server.js +28 -23
- package/dist/src/daemon/server.test.js +52 -0
- package/dist/src/daemon-utils.d.ts +1 -0
- package/dist/src/daemon-utils.js +9 -0
- package/dist/src/daemon.test.js +10 -1
- package/dist/src/doctor.js +7 -1
- package/dist/src/doctor.test.js +8 -1
- package/dist/src/download/article-download.d.ts +3 -3
- package/dist/src/download/article-download.js +7 -7
- package/dist/src/download/article-download.test.js +6 -6
- package/dist/src/download/index.js +1 -1
- package/dist/src/download/index.test.js +1 -2
- package/dist/src/download/media-download.d.ts +1 -1
- package/dist/src/download/media-download.js +1 -1
- package/dist/src/electron-apps.js +0 -8
- package/dist/src/electron-apps.test.js +2 -11
- package/dist/src/errors.test.js +9 -9
- package/dist/src/execution.js +2 -0
- package/dist/src/execution.test.js +12 -0
- package/dist/src/external-clis.yaml +0 -37
- package/dist/src/external.d.ts +1 -1
- package/dist/src/external.test.js +2 -17
- package/dist/src/generate-release-notes-cli.test.js +140 -0
- package/dist/src/help.d.ts +3 -3
- package/dist/src/help.test.js +8 -8
- package/dist/src/main.js +1 -1
- package/dist/src/manifest-types.d.ts +1 -1
- package/dist/src/node-network.test.js +2 -2
- package/dist/src/output.js +1 -1
- package/dist/src/pipeline/steps/download.test.js +3 -3
- package/dist/src/registry.test.js +2 -2
- package/dist/src/release-notes.d.ts +38 -0
- package/dist/src/release-notes.js +99 -0
- package/dist/src/release-notes.test.js +61 -0
- package/dist/src/serialization.test.js +7 -7
- package/dist/src/snapshotFormatter.js +3 -5
- package/dist/src/snapshotFormatter.test.d.ts +1 -1
- package/dist/src/snapshotFormatter.test.js +50 -50
- package/dist/src/tui.js +1 -1
- package/package.json +4 -1
- package/scripts/generate-release-notes.ts +234 -0
- package/scripts/postinstall.js +1 -1
- package/scripts/silent-column-drop-baseline.json +0 -498
- package/scripts/typed-error-lint-baseline.json +0 -464
- package/skills/webcmd-adapter-author/SKILL.md +216 -213
- package/skills/webcmd-adapter-author/references/adapter-template.md +206 -399
- package/skills/webcmd-adapter-author/references/api-discovery.md +111 -220
- package/skills/webcmd-adapter-author/references/coverage-matrix.md +34 -68
- package/skills/webcmd-adapter-author/references/field-conventions.md +84 -167
- package/skills/webcmd-adapter-author/references/field-decode-playbook.md +60 -146
- package/skills/webcmd-adapter-author/references/jsdom-fixture-pattern.md +111 -178
- package/skills/webcmd-adapter-author/references/output-design.md +47 -125
- package/skills/webcmd-adapter-author/references/site-memory.md +116 -166
- package/skills/webcmd-adapter-author/references/site-recon.md +74 -78
- package/skills/webcmd-adapter-author/references/strategy-selection.md +80 -124
- package/skills/webcmd-adapter-author/references/success-rate-pitfalls.md +80 -105
- package/skills/webcmd-adapter-author/references/typed-errors.md +87 -178
- package/skills/webcmd-autofix/SKILL.md +136 -143
- package/skills/webcmd-sitemap-author/SKILL.md +58 -67
- package/skills/webcmd-sitemap-author/references/sitemap-schema.md +354 -494
- package/skills/webcmd-usage/SKILL.md +106 -97
- package/clis/12306/auth.js +0 -59
- package/clis/12306/me.js +0 -73
- package/clis/12306/orders.js +0 -96
- package/clis/12306/passengers.js +0 -90
- package/clis/12306/price.js +0 -166
- package/clis/12306/stations.js +0 -66
- package/clis/12306/train.js +0 -91
- package/clis/12306/trains.js +0 -166
- package/clis/12306/utils.js +0 -272
- package/clis/12306/utils.test.js +0 -424
- package/clis/1688/assets.js +0 -205
- package/clis/1688/assets.test.js +0 -39
- package/clis/1688/auth.js +0 -46
- package/clis/1688/download.js +0 -77
- package/clis/1688/download.test.js +0 -31
- package/clis/1688/item.js +0 -188
- package/clis/1688/item.test.js +0 -67
- package/clis/1688/search.js +0 -310
- package/clis/1688/search.test.js +0 -75
- package/clis/1688/shared.js +0 -557
- package/clis/1688/shared.test.js +0 -57
- package/clis/1688/store.js +0 -227
- package/clis/1688/store.test.js +0 -62
- package/clis/1point3acres/auth.js +0 -52
- package/clis/1point3acres/digest.js +0 -35
- package/clis/1point3acres/forum.js +0 -51
- package/clis/1point3acres/forums.js +0 -44
- package/clis/1point3acres/hot.js +0 -35
- package/clis/1point3acres/latest.js +0 -35
- package/clis/1point3acres/notifications.js +0 -64
- package/clis/1point3acres/search.js +0 -71
- package/clis/1point3acres/thread.js +0 -117
- package/clis/1point3acres/user.js +0 -77
- package/clis/1point3acres/utils.js +0 -247
- package/clis/36kr/article.js +0 -66
- package/clis/36kr/article.test.js +0 -46
- package/clis/36kr/hot.js +0 -87
- package/clis/36kr/hot.test.js +0 -15
- package/clis/36kr/news.js +0 -52
- package/clis/36kr/news.test.js +0 -85
- package/clis/36kr/search.js +0 -79
- package/clis/51job/company.js +0 -126
- package/clis/51job/detail.js +0 -109
- package/clis/51job/hot.js +0 -56
- package/clis/51job/search.js +0 -80
- package/clis/51job/utils.js +0 -302
- package/clis/51job/utils.test.js +0 -69
- package/clis/aibase/news.js +0 -110
- package/clis/aibase/news.test.js +0 -59
- package/clis/autohome/__fixtures__/catalog.html +0 -11
- package/clis/autohome/__fixtures__/koubei.json +0 -116
- package/clis/autohome/autohome.test.js +0 -115
- package/clis/autohome/brand.js +0 -108
- package/clis/autohome/score.js +0 -103
- package/clis/autohome/utils.js +0 -157
- package/clis/baidu-scholar/search.js +0 -87
- package/clis/baidu-scholar/search.test.js +0 -23
- package/clis/bilibili/auth.js +0 -36
- package/clis/bilibili/comment.js +0 -107
- package/clis/bilibili/comment.test.js +0 -153
- package/clis/bilibili/comments.js +0 -136
- package/clis/bilibili/comments.test.js +0 -142
- package/clis/bilibili/download.js +0 -178
- package/clis/bilibili/download.test.js +0 -173
- package/clis/bilibili/dynamic.js +0 -34
- package/clis/bilibili/dynamic.test.js +0 -68
- package/clis/bilibili/favorite.js +0 -47
- package/clis/bilibili/feed.js +0 -220
- package/clis/bilibili/follow.js +0 -140
- package/clis/bilibili/follow.test.js +0 -203
- package/clis/bilibili/following.js +0 -44
- package/clis/bilibili/history.js +0 -45
- package/clis/bilibili/hot.js +0 -40
- package/clis/bilibili/hot.test.js +0 -17
- package/clis/bilibili/me.js +0 -13
- package/clis/bilibili/ranking.js +0 -25
- package/clis/bilibili/search.js +0 -24
- package/clis/bilibili/subtitle.js +0 -141
- package/clis/bilibili/subtitle.test.js +0 -240
- package/clis/bilibili/summary.js +0 -167
- package/clis/bilibili/summary.test.js +0 -210
- package/clis/bilibili/unfollow.js +0 -121
- package/clis/bilibili/user-videos.js +0 -39
- package/clis/bilibili/utils.js +0 -273
- package/clis/bilibili/utils.test.js +0 -97
- package/clis/bilibili/video.js +0 -155
- package/clis/bilibili/video.test.js +0 -308
- package/clis/boss/auth.js +0 -47
- package/clis/boss/batchgreet.js +0 -61
- package/clis/boss/chatlist.js +0 -116
- package/clis/boss/chatlist.test.js +0 -211
- package/clis/boss/chatmsg.js +0 -117
- package/clis/boss/chatmsg.test.js +0 -230
- package/clis/boss/detail.js +0 -63
- package/clis/boss/exchange.js +0 -46
- package/clis/boss/greet.js +0 -49
- package/clis/boss/invite.js +0 -64
- package/clis/boss/joblist.js +0 -31
- package/clis/boss/mark.js +0 -70
- package/clis/boss/recommend.js +0 -45
- package/clis/boss/resume.js +0 -150
- package/clis/boss/search.js +0 -197
- package/clis/boss/search.test.js +0 -78
- package/clis/boss/send.js +0 -44
- package/clis/boss/stats.js +0 -66
- package/clis/boss/utils.js +0 -468
- package/clis/boss/utils.test.js +0 -34
- package/clis/chaoxing/assignments.js +0 -76
- package/clis/chaoxing/auth.js +0 -54
- package/clis/chaoxing/exams.js +0 -75
- package/clis/chaoxing/utils.js +0 -223
- package/clis/chaoxing/utils.test.js +0 -45
- package/clis/cnki/search.js +0 -61
- package/clis/cnki/search.test.js +0 -18
- package/clis/ctrip/auth.js +0 -50
- package/clis/ctrip/ctrip.test.js +0 -719
- package/clis/ctrip/flight.js +0 -136
- package/clis/ctrip/hotel-search.js +0 -132
- package/clis/ctrip/hotel-suggest.js +0 -45
- package/clis/ctrip/search.js +0 -41
- package/clis/ctrip/utils.js +0 -473
- package/clis/deepseek/ask.js +0 -158
- package/clis/deepseek/ask.test.js +0 -399
- package/clis/deepseek/auth.js +0 -54
- package/clis/deepseek/detail.js +0 -46
- package/clis/deepseek/detail.test.js +0 -81
- package/clis/deepseek/history.js +0 -27
- package/clis/deepseek/new.js +0 -33
- package/clis/deepseek/read.js +0 -25
- package/clis/deepseek/send.js +0 -140
- package/clis/deepseek/send.test.js +0 -107
- package/clis/deepseek/status.js +0 -26
- package/clis/deepseek/utils.js +0 -487
- package/clis/deepseek/utils.test.js +0 -370
- package/clis/dianping/__fixtures__/search.html +0 -168
- package/clis/dianping/__fixtures__/shop.html +0 -6
- package/clis/dianping/auth.js +0 -49
- package/clis/dianping/cityResolver.js +0 -185
- package/clis/dianping/dianping.test.js +0 -578
- package/clis/dianping/search.js +0 -157
- package/clis/dianping/shop.js +0 -173
- package/clis/dianping/utils.js +0 -157
- package/clis/dongchedi/__fixtures__/search.json +0 -60
- package/clis/dongchedi/__fixtures__/series-detail.json +0 -911
- package/clis/dongchedi/__fixtures__/series-score.json +0 -1396
- package/clis/dongchedi/dongchedi.test.js +0 -191
- package/clis/dongchedi/koubei.js +0 -85
- package/clis/dongchedi/models.js +0 -91
- package/clis/dongchedi/score.js +0 -83
- package/clis/dongchedi/search.js +0 -83
- package/clis/dongchedi/series.js +0 -87
- package/clis/dongchedi/specs.js +0 -115
- package/clis/dongchedi/utils.js +0 -180
- package/clis/douban/auth.js +0 -50
- package/clis/douban/book-hot.js +0 -15
- package/clis/douban/download.js +0 -68
- package/clis/douban/download.test.js +0 -170
- package/clis/douban/marks.js +0 -116
- package/clis/douban/movie-hot.js +0 -15
- package/clis/douban/movie-hot.test.js +0 -14
- package/clis/douban/photos.js +0 -35
- package/clis/douban/reviews.js +0 -107
- package/clis/douban/search.js +0 -18
- package/clis/douban/search.test.js +0 -11
- package/clis/douban/subject.js +0 -46
- package/clis/douban/subject.test.js +0 -11
- package/clis/douban/top250.js +0 -68
- package/clis/douban/utils.js +0 -657
- package/clis/douban/utils.test.js +0 -488
- package/clis/doubao/ask.js +0 -40
- package/clis/doubao/auth.js +0 -66
- package/clis/doubao/detail.js +0 -35
- package/clis/doubao/detail.test.js +0 -42
- package/clis/doubao/history.js +0 -30
- package/clis/doubao/history.test.js +0 -37
- package/clis/doubao/meeting-summary.js +0 -41
- package/clis/doubao/meeting-transcript.js +0 -38
- package/clis/doubao/new.js +0 -22
- package/clis/doubao/read.js +0 -21
- package/clis/doubao/send.js +0 -24
- package/clis/doubao/status.js +0 -26
- package/clis/doubao/utils.js +0 -1156
- package/clis/doubao/utils.test.js +0 -396
- package/clis/doubao-app/ask.js +0 -54
- package/clis/doubao-app/dump.js +0 -25
- package/clis/doubao-app/new.js +0 -21
- package/clis/doubao-app/read.js +0 -19
- package/clis/doubao-app/screenshot.js +0 -19
- package/clis/doubao-app/send.js +0 -28
- package/clis/doubao-app/status.js +0 -17
- package/clis/doubao-app/utils.js +0 -110
- package/clis/douyin/_shared/browser-fetch.js +0 -66
- package/clis/douyin/_shared/browser-fetch.test.js +0 -64
- package/clis/douyin/_shared/creation-id.js +0 -5
- package/clis/douyin/_shared/creation-id.test.js +0 -22
- package/clis/douyin/_shared/evaluate-result.js +0 -16
- package/clis/douyin/_shared/imagex-upload.js +0 -53
- package/clis/douyin/_shared/imagex-upload.test.js +0 -87
- package/clis/douyin/_shared/public-api.js +0 -29
- package/clis/douyin/_shared/sts2.js +0 -21
- package/clis/douyin/_shared/sts2.test.js +0 -27
- package/clis/douyin/_shared/text-extra.js +0 -15
- package/clis/douyin/_shared/text-extra.test.js +0 -37
- package/clis/douyin/_shared/timing.js +0 -22
- package/clis/douyin/_shared/timing.test.js +0 -28
- package/clis/douyin/_shared/tos-upload-short-read.test.js +0 -83
- package/clis/douyin/_shared/tos-upload.js +0 -331
- package/clis/douyin/_shared/tos-upload.test.js +0 -229
- package/clis/douyin/_shared/transcode.js +0 -45
- package/clis/douyin/_shared/transcode.test.js +0 -91
- package/clis/douyin/_shared/vod-upload.js +0 -212
- package/clis/douyin/_shared/vod-upload.test.js +0 -38
- package/clis/douyin/activities.js +0 -23
- package/clis/douyin/activities.test.js +0 -55
- package/clis/douyin/auth.js +0 -39
- package/clis/douyin/collections.js +0 -23
- package/clis/douyin/collections.test.js +0 -45
- package/clis/douyin/delete.js +0 -152
- package/clis/douyin/delete.test.js +0 -100
- package/clis/douyin/draft.js +0 -355
- package/clis/douyin/draft.test.js +0 -335
- package/clis/douyin/drafts.js +0 -24
- package/clis/douyin/drafts.test.js +0 -11
- package/clis/douyin/hashtag.js +0 -114
- package/clis/douyin/hashtag.test.js +0 -171
- package/clis/douyin/location.js +0 -25
- package/clis/douyin/location.test.js +0 -23
- package/clis/douyin/profile.js +0 -29
- package/clis/douyin/profile.test.js +0 -46
- package/clis/douyin/publish-upload-id.test.js +0 -206
- package/clis/douyin/publish.js +0 -341
- package/clis/douyin/publish.test.js +0 -38
- package/clis/douyin/search.js +0 -308
- package/clis/douyin/search.test.js +0 -307
- package/clis/douyin/stats.js +0 -28
- package/clis/douyin/stats.test.js +0 -22
- package/clis/douyin/update.js +0 -32
- package/clis/douyin/update.test.js +0 -11
- package/clis/douyin/user-videos.js +0 -82
- package/clis/douyin/user-videos.test.js +0 -151
- package/clis/douyin/videos.js +0 -52
- package/clis/douyin/videos.test.js +0 -54
- package/clis/eastmoney/_secid.js +0 -78
- package/clis/eastmoney/announcement.js +0 -53
- package/clis/eastmoney/convertible.js +0 -74
- package/clis/eastmoney/etf.js +0 -66
- package/clis/eastmoney/holders.js +0 -79
- package/clis/eastmoney/hot-rank.js +0 -51
- package/clis/eastmoney/hot-rank.test.js +0 -59
- package/clis/eastmoney/index-board.js +0 -97
- package/clis/eastmoney/kline.js +0 -88
- package/clis/eastmoney/kuaixun.js +0 -55
- package/clis/eastmoney/longhu.js +0 -68
- package/clis/eastmoney/money-flow.js +0 -79
- package/clis/eastmoney/northbound.js +0 -58
- package/clis/eastmoney/quote.js +0 -108
- package/clis/eastmoney/rank.js +0 -95
- package/clis/eastmoney/sectors.js +0 -77
- package/clis/flomo/auth.js +0 -55
- package/clis/flomo/memos.js +0 -228
- package/clis/flomo/memos.test.js +0 -144
- package/clis/gitee/auth.js +0 -41
- package/clis/gitee/index.js +0 -3
- package/clis/gitee/search.js +0 -137
- package/clis/gitee/search.test.js +0 -65
- package/clis/gitee/trending.js +0 -568
- package/clis/gitee/user.js +0 -200
- package/clis/gitee/user.test.js +0 -63
- package/clis/gov-law/commands.test.js +0 -39
- package/clis/gov-law/recent.js +0 -22
- package/clis/gov-law/search.js +0 -41
- package/clis/gov-law/shared.js +0 -51
- package/clis/gov-policy/__fixtures__/recent.html +0 -16
- package/clis/gov-policy/__fixtures__/search.html +0 -41
- package/clis/gov-policy/gov-policy.test.js +0 -224
- package/clis/gov-policy/recent.js +0 -90
- package/clis/gov-policy/search.js +0 -91
- package/clis/gov-policy/utils.js +0 -54
- package/clis/guazi/__fixtures__/detail.html +0 -7
- package/clis/guazi/__fixtures__/list.html +0 -5
- package/clis/guazi/browse.js +0 -95
- package/clis/guazi/car.js +0 -110
- package/clis/guazi/guazi.test.js +0 -126
- package/clis/guazi/utils.js +0 -133
- package/clis/huodongxing/events.js +0 -322
- package/clis/huodongxing/events.test.js +0 -296
- package/clis/hupu/__fixtures__/hot-home.html +0 -64
- package/clis/hupu/auth.js +0 -47
- package/clis/hupu/detail.js +0 -72
- package/clis/hupu/hot.js +0 -163
- package/clis/hupu/hot.test.js +0 -224
- package/clis/hupu/like.js +0 -76
- package/clis/hupu/mentions.js +0 -160
- package/clis/hupu/reply.js +0 -72
- package/clis/hupu/search.js +0 -60
- package/clis/hupu/unlike.js +0 -76
- package/clis/hupu/utils.js +0 -319
- package/clis/jd/add-cart.js +0 -72
- package/clis/jd/auth.js +0 -46
- package/clis/jd/cart.js +0 -80
- package/clis/jd/commands.test.js +0 -41
- package/clis/jd/detail.js +0 -63
- package/clis/jd/item.js +0 -730
- package/clis/jd/item.test.js +0 -354
- package/clis/jd/item.test.ts +0 -517
- package/clis/jd/reviews.js +0 -55
- package/clis/jd/search.js +0 -66
- package/clis/jianyu/auth.js +0 -62
- package/clis/jianyu/detail.js +0 -21
- package/clis/jianyu/search.js +0 -634
- package/clis/jianyu/search.test.js +0 -153
- package/clis/jianyu/shared/china-bid-search.js +0 -165
- package/clis/jianyu/shared/procurement-contract.js +0 -324
- package/clis/jianyu/shared/procurement-contract.test.js +0 -72
- package/clis/jianyu/shared/procurement-detail.js +0 -107
- package/clis/jianyu/shared/procurement-detail.test.js +0 -84
- package/clis/jike/auth.js +0 -48
- package/clis/jike/comment.js +0 -107
- package/clis/jike/create.js +0 -106
- package/clis/jike/feed.js +0 -68
- package/clis/jike/like.js +0 -61
- package/clis/jike/notifications.js +0 -169
- package/clis/jike/post.js +0 -72
- package/clis/jike/read.test.js +0 -86
- package/clis/jike/repost.js +0 -103
- package/clis/jike/search.js +0 -68
- package/clis/jike/topic.js +0 -65
- package/clis/jike/user.js +0 -65
- package/clis/jike/utils.js +0 -25
- package/clis/jimeng/auth.js +0 -46
- package/clis/jimeng/generate.js +0 -84
- package/clis/jimeng/history.js +0 -48
- package/clis/jimeng/new.js +0 -44
- package/clis/jimeng/workspaces.js +0 -42
- package/clis/juejin/hot.js +0 -37
- package/clis/juejin/juejin.test.js +0 -241
- package/clis/juejin/recommend.js +0 -61
- package/clis/juejin/utils.js +0 -199
- package/clis/ke/auth.js +0 -46
- package/clis/ke/chengjiao.js +0 -78
- package/clis/ke/ershoufang.js +0 -101
- package/clis/ke/utils.js +0 -104
- package/clis/ke/xiaoqu.js +0 -78
- package/clis/ke/zufang.js +0 -95
- package/clis/kimi/_utils.js +0 -110
- package/clis/kimi/audit-extras.js +0 -268
- package/clis/kimi/auth.js +0 -57
- package/clis/kimi/chat.js +0 -470
- package/clis/kimi/kimi.test.js +0 -187
- package/clis/kimi/storage.js +0 -169
- package/clis/kimi/ui.js +0 -314
- package/clis/kimi/usage.js +0 -144
- package/clis/linux-do/auth.js +0 -55
- package/clis/linux-do/categories.js +0 -50
- package/clis/linux-do/feed.js +0 -395
- package/clis/linux-do/feed.test.js +0 -153
- package/clis/linux-do/search.js +0 -29
- package/clis/linux-do/tags.js +0 -28
- package/clis/linux-do/topic-content.js +0 -155
- package/clis/linux-do/topic-content.test.js +0 -59
- package/clis/linux-do/topic.js +0 -53
- package/clis/linux-do/user-posts.js +0 -57
- package/clis/linux-do/user-topics.js +0 -37
- package/clis/maimai/auth.js +0 -47
- package/clis/maimai/search-talents.js +0 -192
- package/clis/maimai/search-talents.test.js +0 -29
- package/clis/mubu/doc.js +0 -41
- package/clis/mubu/docs.js +0 -44
- package/clis/mubu/notes.js +0 -245
- package/clis/mubu/recent.js +0 -28
- package/clis/mubu/search.js +0 -63
- package/clis/mubu/utils.js +0 -304
- package/clis/nowcoder/auth.js +0 -65
- package/clis/nowcoder/companies.js +0 -24
- package/clis/nowcoder/creators.js +0 -28
- package/clis/nowcoder/detail.js +0 -62
- package/clis/nowcoder/experience.js +0 -37
- package/clis/nowcoder/hot.js +0 -25
- package/clis/nowcoder/jobs.js +0 -22
- package/clis/nowcoder/notifications.js +0 -30
- package/clis/nowcoder/papers.js +0 -41
- package/clis/nowcoder/practice.js +0 -38
- package/clis/nowcoder/recommend.js +0 -31
- package/clis/nowcoder/referral.js +0 -40
- package/clis/nowcoder/salary.js +0 -41
- package/clis/nowcoder/search.js +0 -50
- package/clis/nowcoder/suggest.js +0 -34
- package/clis/nowcoder/topics.js +0 -28
- package/clis/nowcoder/trending.js +0 -26
- package/clis/ones/common.js +0 -144
- package/clis/ones/enrich-tasks.js +0 -37
- package/clis/ones/login.js +0 -81
- package/clis/ones/logout.js +0 -18
- package/clis/ones/me.js +0 -31
- package/clis/ones/my-tasks.js +0 -121
- package/clis/ones/resolve-labels.js +0 -64
- package/clis/ones/task-helpers.js +0 -212
- package/clis/ones/task-helpers.test.js +0 -12
- package/clis/ones/task.js +0 -67
- package/clis/ones/tasks.js +0 -80
- package/clis/ones/token-info.js +0 -43
- package/clis/ones/worklog.js +0 -268
- package/clis/ones/worklog.test.js +0 -20
- package/clis/powerchina/auth.js +0 -52
- package/clis/powerchina/search.js +0 -251
- package/clis/powerchina/search.test.js +0 -93
- package/clis/quark/auth.js +0 -47
- package/clis/quark/ls.js +0 -64
- package/clis/quark/mkdir.js +0 -37
- package/clis/quark/mv.js +0 -54
- package/clis/quark/rename.js +0 -27
- package/clis/quark/rm.js +0 -25
- package/clis/quark/save.js +0 -81
- package/clis/quark/share-tree.js +0 -46
- package/clis/quark/utils.js +0 -146
- package/clis/quark/utils.test.js +0 -58
- package/clis/qwen/ask.js +0 -104
- package/clis/qwen/ask.test.js +0 -36
- package/clis/qwen/auth.js +0 -56
- package/clis/qwen/detail.js +0 -62
- package/clis/qwen/history.js +0 -61
- package/clis/qwen/image.js +0 -179
- package/clis/qwen/new.js +0 -23
- package/clis/qwen/read.js +0 -41
- package/clis/qwen/send.js +0 -55
- package/clis/qwen/status.js +0 -37
- package/clis/qwen/utils.js +0 -461
- package/clis/qwen/utils.test.js +0 -128
- package/clis/rednote/auth.js +0 -52
- package/clis/rednote/comments.js +0 -85
- package/clis/rednote/download.js +0 -59
- package/clis/rednote/feed.js +0 -27
- package/clis/rednote/navigation.test.js +0 -26
- package/clis/rednote/note.js +0 -68
- package/clis/rednote/notifications.js +0 -139
- package/clis/rednote/rednote.test.js +0 -240
- package/clis/rednote/search.js +0 -107
- package/clis/rednote/user.js +0 -55
- package/clis/sinablog/article.js +0 -15
- package/clis/sinablog/hot.js +0 -15
- package/clis/sinablog/search.js +0 -52
- package/clis/sinablog/user.js +0 -16
- package/clis/sinablog/utils.js +0 -186
- package/clis/sinafinance/news.js +0 -62
- package/clis/sinafinance/rolling-news.js +0 -41
- package/clis/sinafinance/stock-rank.js +0 -66
- package/clis/sinafinance/stock.js +0 -121
- package/clis/sinafinance/stock.test.js +0 -59
- package/clis/smzdm/search.js +0 -149
- package/clis/smzdm/search.test.js +0 -114
- package/clis/taobao/add-cart.js +0 -150
- package/clis/taobao/auth.js +0 -58
- package/clis/taobao/cart.js +0 -96
- package/clis/taobao/commands.test.js +0 -41
- package/clis/taobao/detail.js +0 -71
- package/clis/taobao/reviews.js +0 -77
- package/clis/taobao/search.js +0 -97
- package/clis/tdx/hot-rank.js +0 -48
- package/clis/tdx/hot-rank.test.js +0 -59
- package/clis/ths/hot-rank.js +0 -50
- package/clis/ths/hot-rank.test.js +0 -64
- package/clis/tieba/commands.test.js +0 -79
- package/clis/tieba/hot.js +0 -48
- package/clis/tieba/posts.js +0 -86
- package/clis/tieba/read.js +0 -141
- package/clis/tieba/search.js +0 -109
- package/clis/tieba/utils.js +0 -240
- package/clis/tieba/utils.test.js +0 -290
- package/clis/toutiao/articles.js +0 -55
- package/clis/toutiao/auth.js +0 -70
- package/clis/toutiao/hot.js +0 -63
- package/clis/toutiao/toutiao.test.js +0 -378
- package/clis/toutiao/utils.js +0 -161
- package/clis/trae-cn/activity.js +0 -22
- package/clis/trae-cn/approve.js +0 -52
- package/clis/trae-cn/ask.js +0 -99
- package/clis/trae-cn/dump.js +0 -5
- package/clis/trae-cn/export.js +0 -40
- package/clis/trae-cn/model.js +0 -22
- package/clis/trae-cn/new.js +0 -63
- package/clis/trae-cn/read.js +0 -23
- package/clis/trae-cn/screenshot.js +0 -5
- package/clis/trae-cn/select-model.js +0 -25
- package/clis/trae-cn/send.js +0 -23
- package/clis/trae-cn/setup.js +0 -75
- package/clis/trae-cn/status.js +0 -27
- package/clis/trae-cn/targets.js +0 -96
- package/clis/trae-cn/trae-cn.test.js +0 -412
- package/clis/trae-cn/utils.js +0 -750
- package/clis/trae-cn/watch.js +0 -119
- package/clis/uisdc/news.js +0 -105
- package/clis/uisdc/news.test.js +0 -66
- package/clis/v2ex/auth.js +0 -44
- package/clis/v2ex/daily.js +0 -99
- package/clis/v2ex/hot.js +0 -26
- package/clis/v2ex/latest.js +0 -26
- package/clis/v2ex/me.js +0 -100
- package/clis/v2ex/member.js +0 -28
- package/clis/v2ex/node.js +0 -39
- package/clis/v2ex/nodes.js +0 -26
- package/clis/v2ex/notifications.js +0 -72
- package/clis/v2ex/replies.js +0 -27
- package/clis/v2ex/topic.js +0 -31
- package/clis/v2ex/user.js +0 -34
- package/clis/wanfang/search.js +0 -66
- package/clis/wanfang/search.test.js +0 -23
- package/clis/wechat-channels/auth.js +0 -62
- package/clis/wechat-channels/publish.js +0 -732
- package/clis/wechat-channels/publish.test.js +0 -144
- package/clis/weibo/auth.js +0 -53
- package/clis/weibo/comments.js +0 -53
- package/clis/weibo/delete.js +0 -172
- package/clis/weibo/delete.test.js +0 -94
- package/clis/weibo/envelope.test.js +0 -85
- package/clis/weibo/favorites.js +0 -170
- package/clis/weibo/favorites.test.js +0 -114
- package/clis/weibo/feed.js +0 -69
- package/clis/weibo/hot.js +0 -39
- package/clis/weibo/me.js +0 -75
- package/clis/weibo/post.js +0 -75
- package/clis/weibo/publish.js +0 -306
- package/clis/weibo/publish.test.js +0 -192
- package/clis/weibo/search.js +0 -80
- package/clis/weibo/user-posts.js +0 -234
- package/clis/weibo/user-posts.test.js +0 -92
- package/clis/weibo/user.js +0 -63
- package/clis/weibo/utils.js +0 -59
- package/clis/weibo/utils.test.js +0 -36
- package/clis/weixin/create-draft.js +0 -226
- package/clis/weixin/download.js +0 -371
- package/clis/weixin/download.test.js +0 -106
- package/clis/weixin/drafts.js +0 -66
- package/clis/weixin/drafts.test.js +0 -69
- package/clis/weixin/search.js +0 -157
- package/clis/weixin/search.test.js +0 -227
- package/clis/weread/ai-outline.js +0 -171
- package/clis/weread/ai-outline.test.js +0 -83
- package/clis/weread/auth.js +0 -59
- package/clis/weread/book-search.js +0 -438
- package/clis/weread/book-search.test.js +0 -242
- package/clis/weread/book.js +0 -233
- package/clis/weread/commands.test.js +0 -398
- package/clis/weread/highlights.js +0 -24
- package/clis/weread/notebooks.js +0 -22
- package/clis/weread/notes.js +0 -30
- package/clis/weread/private-api-regression.test.js +0 -369
- package/clis/weread/ranking.js +0 -29
- package/clis/weread/search-regression.test.js +0 -494
- package/clis/weread/search.js +0 -186
- package/clis/weread/shelf.js +0 -66
- package/clis/weread/utils.js +0 -321
- package/clis/weread/utils.test.js +0 -128
- package/clis/weread-official/book.js +0 -135
- package/clis/weread-official/commands.test.js +0 -385
- package/clis/weread-official/discover.js +0 -107
- package/clis/weread-official/list-apis.js +0 -95
- package/clis/weread-official/notes.js +0 -171
- package/clis/weread-official/readdata.js +0 -158
- package/clis/weread-official/review.js +0 -93
- package/clis/weread-official/search.js +0 -106
- package/clis/weread-official/shelf.js +0 -97
- package/clis/weread-official/utils.js +0 -293
- package/clis/weread-official/utils.test.js +0 -242
- package/clis/xianyu/auth.js +0 -68
- package/clis/xianyu/chat.js +0 -74
- package/clis/xianyu/chat.test.js +0 -84
- package/clis/xianyu/im.js +0 -322
- package/clis/xianyu/im.test.js +0 -253
- package/clis/xianyu/inbox.js +0 -96
- package/clis/xianyu/item.js +0 -153
- package/clis/xianyu/item.test.js +0 -56
- package/clis/xianyu/messages.js +0 -91
- package/clis/xianyu/publish.js +0 -485
- package/clis/xianyu/publish.test.js +0 -220
- package/clis/xianyu/reply.js +0 -82
- package/clis/xianyu/search.js +0 -262
- package/clis/xianyu/search.test.js +0 -104
- package/clis/xianyu/utils.js +0 -8
- package/clis/xiaoe/auth.js +0 -55
- package/clis/xiaoe/catalog.js +0 -227
- package/clis/xiaoe/content.js +0 -175
- package/clis/xiaoe/courses.js +0 -127
- package/clis/xiaoe/detail.js +0 -36
- package/clis/xiaoe/play-url.js +0 -121
- package/clis/xiaoe/xiaoe.test.js +0 -486
- package/clis/xiaohongshu/ask.js +0 -426
- package/clis/xiaohongshu/ask.test.js +0 -271
- package/clis/xiaohongshu/auth.js +0 -53
- package/clis/xiaohongshu/collection-helpers.js +0 -283
- package/clis/xiaohongshu/collection-helpers.test.js +0 -125
- package/clis/xiaohongshu/comments.js +0 -228
- package/clis/xiaohongshu/comments.test.js +0 -320
- package/clis/xiaohongshu/creator-note-detail.js +0 -482
- package/clis/xiaohongshu/creator-note-detail.test.js +0 -451
- package/clis/xiaohongshu/creator-notes-summary.js +0 -98
- package/clis/xiaohongshu/creator-notes-summary.test.js +0 -94
- package/clis/xiaohongshu/creator-notes.js +0 -479
- package/clis/xiaohongshu/creator-notes.test.js +0 -281
- package/clis/xiaohongshu/creator-profile.js +0 -55
- package/clis/xiaohongshu/creator-stats.js +0 -76
- package/clis/xiaohongshu/creator-stats.test.js +0 -24
- package/clis/xiaohongshu/delete-note.js +0 -260
- package/clis/xiaohongshu/delete-note.test.js +0 -172
- package/clis/xiaohongshu/download.js +0 -249
- package/clis/xiaohongshu/download.test.js +0 -339
- package/clis/xiaohongshu/draft-clear.js +0 -91
- package/clis/xiaohongshu/draft-delete.js +0 -103
- package/clis/xiaohongshu/draft-open.js +0 -43
- package/clis/xiaohongshu/draft-utils.js +0 -142
- package/clis/xiaohongshu/drafts.js +0 -28
- package/clis/xiaohongshu/drafts.test.js +0 -172
- package/clis/xiaohongshu/feed.js +0 -163
- package/clis/xiaohongshu/feed.test.js +0 -126
- package/clis/xiaohongshu/follow.js +0 -226
- package/clis/xiaohongshu/follow.test.js +0 -211
- package/clis/xiaohongshu/liked.js +0 -29
- package/clis/xiaohongshu/liked.test.js +0 -82
- package/clis/xiaohongshu/navigation.test.js +0 -38
- package/clis/xiaohongshu/note-helpers.js +0 -69
- package/clis/xiaohongshu/note.js +0 -104
- package/clis/xiaohongshu/note.test.js +0 -249
- package/clis/xiaohongshu/notifications.js +0 -46
- package/clis/xiaohongshu/publish.js +0 -1423
- package/clis/xiaohongshu/publish.test.js +0 -1141
- package/clis/xiaohongshu/saved.js +0 -29
- package/clis/xiaohongshu/saved.test.js +0 -143
- package/clis/xiaohongshu/search.js +0 -330
- package/clis/xiaohongshu/search.test.js +0 -325
- package/clis/xiaohongshu/unfollow.js +0 -285
- package/clis/xiaohongshu/user-helpers.js +0 -78
- package/clis/xiaohongshu/user-helpers.test.js +0 -160
- package/clis/xiaohongshu/user.js +0 -140
- package/clis/xiaohongshu/user.test.js +0 -141
- package/clis/xiaoyuzhou/auth.js +0 -303
- package/clis/xiaoyuzhou/auth.test.js +0 -124
- package/clis/xiaoyuzhou/download.js +0 -54
- package/clis/xiaoyuzhou/download.test.js +0 -135
- package/clis/xiaoyuzhou/episode.js +0 -34
- package/clis/xiaoyuzhou/podcast-episodes.js +0 -41
- package/clis/xiaoyuzhou/podcast-episodes.test.js +0 -78
- package/clis/xiaoyuzhou/podcast.js +0 -33
- package/clis/xiaoyuzhou/transcript.js +0 -77
- package/clis/xiaoyuzhou/transcript.test.js +0 -195
- package/clis/xiaoyuzhou/utils.js +0 -15
- package/clis/xiaoyuzhou/utils.test.js +0 -39
- package/clis/xueqiu/auth.js +0 -63
- package/clis/xueqiu/comments.js +0 -355
- package/clis/xueqiu/comments.test.js +0 -696
- package/clis/xueqiu/danjuan-utils.js +0 -126
- package/clis/xueqiu/danjuan-utils.test.js +0 -41
- package/clis/xueqiu/earnings-date.js +0 -45
- package/clis/xueqiu/feed.js +0 -39
- package/clis/xueqiu/fund-holdings.js +0 -29
- package/clis/xueqiu/fund-snapshot.js +0 -26
- package/clis/xueqiu/groups.js +0 -23
- package/clis/xueqiu/hot-stock.js +0 -32
- package/clis/xueqiu/hot.js +0 -37
- package/clis/xueqiu/kline.js +0 -44
- package/clis/xueqiu/search.js +0 -37
- package/clis/xueqiu/stock.js +0 -65
- package/clis/xueqiu/utils.js +0 -48
- package/clis/xueqiu/utils.test.js +0 -26
- package/clis/xueqiu/watchlist.js +0 -37
- package/clis/youdao/note.js +0 -258
- package/clis/youdao/note.test.js +0 -99
- package/clis/yuanbao/ask.js +0 -362
- package/clis/yuanbao/ask.test.js +0 -124
- package/clis/yuanbao/auth.js +0 -59
- package/clis/yuanbao/detail.js +0 -65
- package/clis/yuanbao/history.js +0 -51
- package/clis/yuanbao/new.js +0 -72
- package/clis/yuanbao/new.test.js +0 -30
- package/clis/yuanbao/read.js +0 -38
- package/clis/yuanbao/send.js +0 -57
- package/clis/yuanbao/shared.js +0 -341
- package/clis/yuanbao/shared.test.js +0 -80
- package/clis/yuanbao/status.js +0 -44
- package/clis/zhihu/answer-comments.js +0 -280
- package/clis/zhihu/answer-comments.test.js +0 -287
- package/clis/zhihu/answer-detail.js +0 -216
- package/clis/zhihu/answer-detail.test.js +0 -338
- package/clis/zhihu/answer.js +0 -54
- package/clis/zhihu/answer.test.js +0 -54
- package/clis/zhihu/auth.js +0 -59
- package/clis/zhihu/collection.js +0 -199
- package/clis/zhihu/collection.test.js +0 -337
- package/clis/zhihu/collections.js +0 -128
- package/clis/zhihu/collections.test.js +0 -182
- package/clis/zhihu/comment.js +0 -55
- package/clis/zhihu/comment.test.js +0 -50
- package/clis/zhihu/download.js +0 -80
- package/clis/zhihu/download.test.js +0 -12
- package/clis/zhihu/favorite.js +0 -87
- package/clis/zhihu/favorite.test.js +0 -59
- package/clis/zhihu/follow.js +0 -50
- package/clis/zhihu/follow.test.js +0 -42
- package/clis/zhihu/followers.js +0 -40
- package/clis/zhihu/followers.test.js +0 -42
- package/clis/zhihu/following.js +0 -40
- package/clis/zhihu/following.test.js +0 -44
- package/clis/zhihu/hot.js +0 -44
- package/clis/zhihu/like.js +0 -47
- package/clis/zhihu/like.test.js +0 -41
- package/clis/zhihu/paginate.js +0 -128
- package/clis/zhihu/pins.js +0 -41
- package/clis/zhihu/pins.test.js +0 -44
- package/clis/zhihu/question.js +0 -113
- package/clis/zhihu/question.test.js +0 -251
- package/clis/zhihu/recommend.js +0 -103
- package/clis/zhihu/recommend.test.js +0 -143
- package/clis/zhihu/search.js +0 -206
- package/clis/zhihu/search.test.js +0 -198
- package/clis/zhihu/target.js +0 -91
- package/clis/zhihu/target.test.js +0 -77
- package/clis/zhihu/text.js +0 -29
- package/clis/zhihu/text.test.js +0 -24
- package/clis/zhihu/user-answers.js +0 -41
- package/clis/zhihu/user-answers.test.js +0 -69
- package/clis/zhihu/user-arg.js +0 -34
- package/clis/zhihu/user-articles.js +0 -40
- package/clis/zhihu/user-articles.test.js +0 -44
- package/clis/zhihu/user.js +0 -59
- package/clis/zhihu/user.test.js +0 -73
- package/clis/zhihu/write-shared.js +0 -228
- package/clis/zhihu/write-shared.test.js +0 -176
- package/clis/zsxq/auth.js +0 -68
- package/clis/zsxq/dynamics.js +0 -48
- package/clis/zsxq/groups.js +0 -33
- package/clis/zsxq/search.js +0 -44
- package/clis/zsxq/search.test.js +0 -24
- package/clis/zsxq/topic.js +0 -50
- package/clis/zsxq/topic.test.js +0 -30
- package/clis/zsxq/topics.js +0 -26
- package/clis/zsxq/topics.test.js +0 -24
- package/clis/zsxq/utils.js +0 -233
- package/clis/zsxq/utils.test.js +0 -31
- package/dist/src/weixin-download.test.js +0 -45
- package/skills/webcmd-adapter-author/references/site-memory/bilibili.md +0 -70
- package/skills/webcmd-adapter-author/references/site-memory/eastmoney.md +0 -70
- package/skills/webcmd-adapter-author/references/site-memory/tonghuashun.md +0 -51
- package/skills/webcmd-adapter-author/references/site-memory/xueqiu.md +0 -58
- /package/{clis/douyin/_shared/types.js → dist/src/generate-release-notes-cli.test.d.ts} +0 -0
- /package/dist/src/{weixin-download.test.d.ts → release-notes.test.d.ts} +0 -0
|
@@ -1,471 +1,278 @@
|
|
|
1
1
|
# Adapter Template
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use this after recon, endpoint verification, field decoding, output design, and strategy-note writing are complete.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Create The File
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
For private iteration:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```bash
|
|
10
|
+
webcmd browser init <site>/<name> --strategy <strategy>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Write the working file at:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
~/.webcmd/clis/<site>/<name>.js
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Copy it to the repo only when preparing a PR:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
clis/<site>/<name>.js
|
|
23
|
+
```
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
## Minimal Registry Shape
|
|
12
26
|
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
Adapters register commands with `cli` and `Strategy` from `@agentrhq/webcmd/registry`.
|
|
28
|
+
|
|
29
|
+
```js
|
|
15
30
|
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
16
|
-
import { CliError } from '@agentrhq/webcmd/errors';
|
|
17
|
-
|
|
18
|
-
const SORTS = {
|
|
19
|
-
change: { fid: 'f3', order: 'desc' },
|
|
20
|
-
drop: { fid: 'f3', order: 'asc' },
|
|
21
|
-
turnover: { fid: 'f6', order: 'desc' },
|
|
22
|
-
price: { fid: 'f2', order: 'desc' },
|
|
23
|
-
premium: { fid: 'f237', order: 'desc' },
|
|
24
|
-
value: { fid: 'f236', order: 'desc' },
|
|
25
|
-
ytm: { fid: 'f239', order: 'desc' },
|
|
26
|
-
};
|
|
27
31
|
|
|
28
32
|
cli({
|
|
29
|
-
site: '
|
|
30
|
-
name: '
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
site: 'hackernews',
|
|
34
|
+
name: 'top',
|
|
35
|
+
access: 'read',
|
|
36
|
+
description: 'Hacker News top stories',
|
|
37
|
+
domain: 'news.ycombinator.com',
|
|
33
38
|
strategy: Strategy.PUBLIC,
|
|
34
39
|
browser: false,
|
|
35
40
|
args: [
|
|
36
|
-
{ name: '
|
|
37
|
-
|
|
41
|
+
{ name: 'limit', type: 'int', default: 20, help: 'Number of rows' },
|
|
42
|
+
],
|
|
43
|
+
columns: ['rank', 'title', 'url', 'score', 'author', 'commentCount'],
|
|
44
|
+
pipeline: [
|
|
45
|
+
{ navigate: 'https://news.ycombinator.com/' },
|
|
46
|
+
{
|
|
47
|
+
evaluate: `(async () => {
|
|
48
|
+
const rows = [...document.querySelectorAll('.athing')].slice(0, \${{ args.limit }});
|
|
49
|
+
return rows.map((row, index) => {
|
|
50
|
+
const subtext = row.nextElementSibling;
|
|
51
|
+
const titleLink = row.querySelector('.titleline a');
|
|
52
|
+
return {
|
|
53
|
+
rank: index + 1,
|
|
54
|
+
title: titleLink?.textContent?.trim() || '',
|
|
55
|
+
url: titleLink?.href || '',
|
|
56
|
+
score: Number((subtext?.querySelector('.score')?.textContent || '').match(/\\d+/)?.[0] || 0),
|
|
57
|
+
author: subtext?.querySelector('.hnuser')?.textContent?.trim() || '',
|
|
58
|
+
commentCount: Number((subtext?.textContent || '').match(/(\\d+)\\s+comments?/)?.[1] || 0),
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
})()`,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
map: {
|
|
65
|
+
rank: '${{ item.rank }}',
|
|
66
|
+
title: '${{ item.title }}',
|
|
67
|
+
url: '${{ item.url }}',
|
|
68
|
+
score: '${{ item.score }}',
|
|
69
|
+
author: '${{ item.author }}',
|
|
70
|
+
commentCount: '${{ item.commentCount }}',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{ limit: '${{ args.limit }}' },
|
|
38
74
|
],
|
|
39
|
-
columns: ['rank', 'bondCode', 'bondName', 'bondPrice', 'bondChangePct',
|
|
40
|
-
'stockCode', 'stockName', 'stockPrice', 'stockChangePct',
|
|
41
|
-
'convPrice', 'convValue', 'convPremiumPct', 'remainingYears', 'ytm', 'listDate'],
|
|
42
|
-
func: async (args) => {
|
|
43
|
-
const sortKey = String(args.sort ?? 'turnover').toLowerCase();
|
|
44
|
-
const sort = SORTS[sortKey];
|
|
45
|
-
if (!sort) throw new CliError('INVALID_ARGUMENT', `Unknown sort "${sortKey}". Valid: ${Object.keys(SORTS).join(', ')}`);
|
|
46
|
-
const limit = Math.max(1, Math.min(Number(args.limit) || 20, 100));
|
|
47
|
-
|
|
48
|
-
const url = new URL('https://push2.eastmoney.com/api/qt/clist/get');
|
|
49
|
-
url.searchParams.set('pn', '1');
|
|
50
|
-
url.searchParams.set('pz', String(limit));
|
|
51
|
-
url.searchParams.set('po', sort.order === 'desc' ? '1' : '0');
|
|
52
|
-
url.searchParams.set('np', '1');
|
|
53
|
-
url.searchParams.set('fltt', '2');
|
|
54
|
-
url.searchParams.set('invt', '2');
|
|
55
|
-
url.searchParams.set('fid', sort.fid);
|
|
56
|
-
url.searchParams.set('fs', 'b:MK0354');
|
|
57
|
-
url.searchParams.set('fields', 'f12,f14,f2,f3,f6,f229,f230,f232,f234,f235,f236,f237,f238,f239,f243');
|
|
58
|
-
url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');
|
|
59
|
-
|
|
60
|
-
const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
|
|
61
|
-
if (!resp.ok) throw new CliError('HTTP_ERROR', `convertible failed: HTTP ${resp.status}`);
|
|
62
|
-
const data = await resp.json();
|
|
63
|
-
const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
|
|
64
|
-
if (diff.length === 0) throw new CliError('NO_DATA', 'eastmoney returned no convertible data');
|
|
65
|
-
|
|
66
|
-
return diff.slice(0, limit).map((it, i) => ({
|
|
67
|
-
rank: i + 1,
|
|
68
|
-
bondCode: it.f12,
|
|
69
|
-
bondName: it.f14,
|
|
70
|
-
bondPrice: it.f2,
|
|
71
|
-
bondChangePct: it.f3,
|
|
72
|
-
stockCode: it.f232,
|
|
73
|
-
stockName: it.f234,
|
|
74
|
-
stockPrice: it.f229,
|
|
75
|
-
stockChangePct: it.f230,
|
|
76
|
-
convPrice: it.f235,
|
|
77
|
-
convValue: it.f236,
|
|
78
|
-
convPremiumPct: it.f237,
|
|
79
|
-
remainingYears: it.f238,
|
|
80
|
-
ytm: it.f239,
|
|
81
|
-
listDate: String(it.f243 ?? ''),
|
|
82
|
-
}));
|
|
83
|
-
},
|
|
84
75
|
});
|
|
85
76
|
```
|
|
86
77
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
## 三段解剖
|
|
78
|
+
Treat this as shape guidance, not a universal solution. Prefer the closest existing adapter for the same site or source type.
|
|
90
79
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```javascript
|
|
94
|
-
cli({
|
|
95
|
-
site: 'eastmoney', // 第一级命名空间,目录名一致
|
|
96
|
-
name: 'convertible', // 第二级,CLI 上的子命令
|
|
97
|
-
description: '...', // 一句话,出现在 `webcmd list` 和 `webcmd <site> -h`
|
|
98
|
-
domain: 'push2.eastmoney.com', // 主要请求域名(诊断面板用)
|
|
99
|
-
strategy: Strategy.PUBLIC, // PUBLIC / COOKIE / INTERCEPT / UI
|
|
100
|
-
browser: false, // PUBLIC 几乎总是 false;COOKIE/INTERCEPT/UI 一律 true
|
|
101
|
-
...
|
|
102
|
-
});
|
|
103
|
-
```
|
|
80
|
+
## Imports
|
|
104
81
|
|
|
105
|
-
|
|
82
|
+
Allowed imports:
|
|
106
83
|
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
84
|
+
```js
|
|
85
|
+
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
86
|
+
import {
|
|
87
|
+
ArgumentError,
|
|
88
|
+
AuthRequiredError,
|
|
89
|
+
CommandExecutionError,
|
|
90
|
+
EmptyResultError,
|
|
91
|
+
TimeoutError,
|
|
92
|
+
} from '@agentrhq/webcmd/errors';
|
|
113
93
|
```
|
|
114
94
|
|
|
115
|
-
|
|
95
|
+
Rules:
|
|
116
96
|
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
- 列名 camelCase,跟 `cli({...})` 其他 adapter 保持统一
|
|
121
|
-
- **中间解析对象 key 不能跟 columns 任一项重叠** —— 否则 `silent-column-drop` audit 会把它当 row 候选误判。`{pid, html, start}` 这类中间结构改成 `{postId, body, offset}`,最后在 push row 时再 destructure aliasing 回 column 命名。背景:PR #1329 R1 codex-mini0 catch 的([before](https://github.com/agentrhq/webcmd/blob/384bcd6fdd93f3075bd2c835e82689c42bfe4b2f/clis/1point3acres/thread.js#L50-L63) → [after](../../../clis/1point3acres/thread.js#L50-L65))
|
|
97
|
+
- Do not add third-party dependencies.
|
|
98
|
+
- Do not import private repo internals unless an established neighboring adapter already does so.
|
|
99
|
+
- Keep helpers local unless there is real duplication in the same site directory.
|
|
122
100
|
|
|
123
|
-
|
|
101
|
+
## Required Fields
|
|
124
102
|
|
|
125
|
-
|
|
126
|
-
|
|
103
|
+
| Field | Rule |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `site` | Directory/site id. Keep lowercase and stable. |
|
|
106
|
+
| `name` | Command id. Keep lowercase and stable. |
|
|
107
|
+
| `access` | Usually `read`; use write-like access only for commands that mutate state. |
|
|
108
|
+
| `description` | One clear sentence. |
|
|
109
|
+
| `domain` | Primary domain for auth and help output. |
|
|
110
|
+
| `strategy` | Use a registry enum such as `Strategy.PUBLIC` or `Strategy.COOKIE`; align it with the strategy note. |
|
|
111
|
+
| `browser` | `false` for plain Node-side adapters; `true` when the adapter needs the page, cookie jar, or browser runtime. |
|
|
112
|
+
| `args` | Include type, default, and help for every external parameter. |
|
|
113
|
+
| `columns` | Must exactly match row keys, including order. |
|
|
114
|
+
| `pipeline` or `func` | Use the style already established by nearby adapters. |
|
|
127
115
|
|
|
128
|
-
|
|
129
|
-
// 1. 解析参数 — 越界一律抛,不要 silent clamp
|
|
130
|
-
const n = Number(args.limit ?? 20);
|
|
131
|
-
if (!Number.isInteger(n) || n <= 0) throw new ArgumentError('limit must be a positive integer');
|
|
132
|
-
if (n > 100) throw new ArgumentError('limit must be <= 100');
|
|
133
|
-
const limit = n;
|
|
134
|
-
|
|
135
|
-
// 2. 构造 URL / 请求
|
|
136
|
-
const url = new URL(...);
|
|
137
|
-
url.searchParams.set(...);
|
|
138
|
-
|
|
139
|
-
// 3. 发请求 — fetch 抛 / HTTP 非 2xx 都归 CommandExecutionError
|
|
140
|
-
let resp;
|
|
141
|
-
try {
|
|
142
|
-
resp = await fetch(url, { headers: { /* ... */ } });
|
|
143
|
-
} catch (error) {
|
|
144
|
-
throw new CommandExecutionError(`request failed: ${error?.message || error}`);
|
|
145
|
-
}
|
|
146
|
-
if (!resp.ok) throw new CommandExecutionError(`request failed: HTTP ${resp.status}`);
|
|
147
|
-
|
|
148
|
-
// 4. 解析 + 业务校验 — 业务空 → EmptyResultError,不要 sentinel row 也不要 return []
|
|
149
|
-
const data = await resp.json();
|
|
150
|
-
const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
|
|
151
|
-
if (diff.length === 0) throw new EmptyResultError('site command', 'API returned no rows');
|
|
152
|
-
|
|
153
|
-
// 5. map 到 columns 同名 keys
|
|
154
|
-
return diff.slice(0, limit).map((it, i) => ({
|
|
155
|
-
rank: i + 1,
|
|
156
|
-
bondCode: it.f12,
|
|
157
|
-
// ...
|
|
158
|
-
}));
|
|
159
|
-
},
|
|
160
|
-
```
|
|
116
|
+
## Strategy Enum Examples
|
|
161
117
|
|
|
162
|
-
|
|
118
|
+
The strategy note uses discovery names such as `PUBLIC_API` and `COOKIE_API`. The adapter declaration records the runtime choice with `Strategy` enum values.
|
|
163
119
|
|
|
164
|
-
|
|
120
|
+
Use `Strategy.PUBLIC` when an anonymous, stable endpoint can be fetched directly from Node:
|
|
165
121
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
122
|
+
```js
|
|
123
|
+
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
124
|
+
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
169
125
|
|
|
170
|
-
|
|
126
|
+
cli({
|
|
127
|
+
site: 'example',
|
|
128
|
+
name: 'public-list',
|
|
129
|
+
access: 'read',
|
|
130
|
+
description: 'Example public listing',
|
|
131
|
+
domain: 'api.example.com',
|
|
132
|
+
strategy: Strategy.PUBLIC,
|
|
133
|
+
browser: false,
|
|
134
|
+
args: [{ name: 'limit', type: 'int', default: 20, help: 'Number of rows' }],
|
|
135
|
+
columns: ['index', 'title', 'url'],
|
|
136
|
+
func: async (args) => {
|
|
137
|
+
const limit = Number(args.limit ?? 20);
|
|
138
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
139
|
+
throw new ArgumentError('limit must be a positive integer');
|
|
140
|
+
}
|
|
171
141
|
|
|
172
|
-
|
|
142
|
+
const resp = await fetch(`https://api.example.com/items?limit=${limit}`, {
|
|
143
|
+
headers: { 'User-Agent': 'Mozilla/5.0' },
|
|
144
|
+
});
|
|
145
|
+
if (!resp.ok) throw new CommandExecutionError(`example request failed: HTTP ${resp.status}`);
|
|
173
146
|
|
|
174
|
-
|
|
147
|
+
const data = await resp.json();
|
|
148
|
+
const items = Array.isArray(data?.items) ? data.items : [];
|
|
149
|
+
if (!items.length) throw new EmptyResultError('example public-list', 'API returned no rows');
|
|
175
150
|
|
|
176
|
-
|
|
151
|
+
return items.map((item, index) => ({
|
|
152
|
+
index: index + 1,
|
|
153
|
+
title: item.title,
|
|
154
|
+
url: item.url,
|
|
155
|
+
}));
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
```
|
|
177
159
|
|
|
178
|
-
|
|
179
|
-
2. 拿 HTML 走 Node 端 `fetch` + 手动解码,**不要塞进 `page.evaluate` 里**。
|
|
180
|
-
3. Declaration 加 `browser: true`;不需要真的打开目标页时 `navigateBefore: false`。
|
|
160
|
+
Use `Strategy.COOKIE` when the endpoint or HTML page needs the user's existing browser session. Read cookies with `page.getCookies()` and pass them to Node-side `fetch`; do not rely on `document.cookie` for HttpOnly auth cookies.
|
|
181
161
|
|
|
182
|
-
```
|
|
162
|
+
```js
|
|
183
163
|
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
184
164
|
import { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
185
165
|
|
|
186
166
|
const BASE = 'https://www.example.com';
|
|
187
167
|
const HOST = 'www.example.com';
|
|
188
|
-
const ROOT = '.example.com';
|
|
189
|
-
|
|
190
|
-
async function
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
for (const c of cookies || []) {
|
|
196
|
-
if (!seen.has(c.name)) seen.set(c.name, c.value);
|
|
197
|
-
}
|
|
198
|
-
} catch { /* try next domain */ }
|
|
168
|
+
const ROOT = '.example.com';
|
|
169
|
+
|
|
170
|
+
async function cookieHeader(page) {
|
|
171
|
+
const seen = new Map();
|
|
172
|
+
for (const opts of [{ domain: HOST }, { domain: ROOT }]) {
|
|
173
|
+
for (const cookie of await page.getCookies(opts).catch(() => [])) {
|
|
174
|
+
if (!seen.has(cookie.name)) seen.set(cookie.name, cookie.value);
|
|
199
175
|
}
|
|
200
|
-
|
|
176
|
+
}
|
|
177
|
+
return [...seen].map(([name, value]) => `${name}=${value}`).join('; ');
|
|
201
178
|
}
|
|
202
179
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
'Accept-Language': 'zh-CN,zh;q=0.9',
|
|
210
|
-
Referer: `${BASE}/`,
|
|
211
|
-
...(cookie ? { Cookie: cookie } : {}),
|
|
212
|
-
...headers,
|
|
213
|
-
},
|
|
214
|
-
redirect: 'follow',
|
|
215
|
-
});
|
|
216
|
-
} catch (error) {
|
|
217
|
-
throw new CommandExecutionError(`example request failed: ${error?.message || error}`);
|
|
218
|
-
}
|
|
219
|
-
if (!resp.ok) throw new CommandExecutionError(`example request failed: HTTP ${resp.status}`);
|
|
220
|
-
const buf = await resp.arrayBuffer();
|
|
221
|
-
return new TextDecoder(encoding).decode(buf);
|
|
180
|
+
function parseRowsFromHtml(html) {
|
|
181
|
+
return [...html.matchAll(/<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>/g)].map((match, index) => ({
|
|
182
|
+
index: index + 1,
|
|
183
|
+
title: match[2].trim(),
|
|
184
|
+
time: '',
|
|
185
|
+
}));
|
|
222
186
|
}
|
|
223
187
|
|
|
224
188
|
cli({
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const html = await fetchHtml(`${BASE}/inbox`, { cookie, encoding: 'gbk' });
|
|
241
|
-
|
|
242
|
-
if (/请登录|需要登录|<title>Login/i.test(html)) {
|
|
243
|
-
throw new AuthRequiredError(HOST);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// parse html → rows
|
|
247
|
-
if (!rows.length) throw new EmptyResultError('example me', 'inbox is empty');
|
|
248
|
-
return rows.slice(0, limit);
|
|
249
|
-
},
|
|
250
|
-
});
|
|
251
|
-
```
|
|
189
|
+
site: 'example',
|
|
190
|
+
name: 'private-list',
|
|
191
|
+
access: 'read',
|
|
192
|
+
description: 'Example private listing',
|
|
193
|
+
domain: HOST,
|
|
194
|
+
strategy: Strategy.COOKIE,
|
|
195
|
+
browser: true,
|
|
196
|
+
navigateBefore: false,
|
|
197
|
+
args: [{ name: 'limit', type: 'int', default: 20, help: 'Number of rows' }],
|
|
198
|
+
columns: ['index', 'title', 'time'],
|
|
199
|
+
func: async (page, args) => {
|
|
200
|
+
const limit = Number(args.limit ?? 20);
|
|
201
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
202
|
+
throw new ArgumentError('limit must be a positive integer');
|
|
203
|
+
}
|
|
252
204
|
|
|
253
|
-
|
|
205
|
+
const cookie = await cookieHeader(page);
|
|
206
|
+
const resp = await fetch(`${BASE}/inbox`, {
|
|
207
|
+
headers: {
|
|
208
|
+
'User-Agent': 'Mozilla/5.0',
|
|
209
|
+
Referer: `${BASE}/`,
|
|
210
|
+
...(cookie ? { Cookie: cookie } : {}),
|
|
211
|
+
},
|
|
212
|
+
redirect: 'follow',
|
|
213
|
+
});
|
|
214
|
+
if (!resp.ok) throw new CommandExecutionError(`example request failed: HTTP ${resp.status}`);
|
|
254
215
|
|
|
255
|
-
|
|
216
|
+
const html = await resp.text();
|
|
217
|
+
if (/login required|sign in/i.test(html)) throw new AuthRequiredError(HOST);
|
|
256
218
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
body: { page: 1, size: limit },
|
|
219
|
+
const rows = parseRowsFromHtml(html).slice(0, limit);
|
|
220
|
+
if (!rows.length) throw new EmptyResultError('example private-list', 'page returned no rows');
|
|
221
|
+
return rows;
|
|
222
|
+
},
|
|
262
223
|
});
|
|
263
224
|
```
|
|
264
225
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
### 页面内 DOM 逻辑用 `page.evaluate(fn, ...args)`
|
|
268
|
-
|
|
269
|
-
新 adapter 优先写函数形式,外部变量通过参数传入:
|
|
270
|
-
|
|
271
|
-
```javascript
|
|
272
|
-
const href = await page.evaluate((selector) => {
|
|
273
|
-
const link = document.querySelector(selector);
|
|
274
|
-
return link ? link.getAttribute('href') : null;
|
|
275
|
-
}, 'a[data-testid="profile"]');
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
`fn` 在浏览器页面上下文执行,不能读取 Node 侧闭包变量;参数必须能被 `JSON.stringify` 序列化。字符串形式 `page.evaluate('document.title')` 仍可用于简单表达式和既有代码,但不要再写依赖隐式 auto-IIFE 的模板字符串函数。
|
|
279
|
-
|
|
280
|
-
### HTML 不走 browser fetch
|
|
281
|
-
|
|
282
|
-
三个坑,踩一个就重写:
|
|
283
|
-
|
|
284
|
-
- **HttpOnly cookie 看不见**:绝大多数登录站点把 auth cookie 标 `HttpOnly`,`document.cookie` 永远读不到它,只能通过 CDP 的 cookie jar 拿(`page.getCookies`)。塞到 `page.evaluate` 里就等于回到 `document.cookie` 那条路,必挂。
|
|
285
|
-
- **`navigateBefore: false` 时当前 tab 不在目标站**:页面 origin 可能是 `about:blank` 或上一条命令留下的别处,从那儿发 fetch 到目标域就是 cross-origin,浏览器 CORS 一挡就是 "Failed to fetch"。
|
|
286
|
-
- **非 UTF-8 编码解码麻烦**:GBK / Big5 / Shift-JIS 的站(Discuz / phpBB 老版 / 日站)在 `page.evaluate` 里用 `response.text()` 拿到的是乱码,`TextDecoder('gbk').decode(buf)` 的写法只在 Node 侧干净。
|
|
287
|
-
|
|
288
|
-
**规则**:JSON 型浏览器接口用 `page.fetchJson()`;HTML 型 COOKIE adapter 一律 Node 侧 `fetch`,浏览器只当 cookie jar 用。
|
|
289
|
-
|
|
290
|
-
### Selector 稳定性 — 不要 select 用户可见文本
|
|
291
|
-
|
|
292
|
-
issue #1474 触发:同一个发送按钮在英文 Chrome 是 `aria-label="Submit"`,在中文 Chrome(`chrome://settings/languages` 设中文)变 `aria-label="提交"`,CSS 选择器 `button[aria-label="Submit"]` 在中文环境下直接 0 匹配,silent empty result。
|
|
293
|
-
|
|
294
|
-
根因不是 i18n bug,是**选择器的 anchor 选错了**。把页面 DOM 属性按 "locale-stable vs locale-dependent" 分两类:
|
|
295
|
-
|
|
296
|
-
| 类 | 例子 | locale 切换会变吗 | 用作 primary selector? |
|
|
297
|
-
|----|------|----------------|---------------------|
|
|
298
|
-
| **locale-stable 标识** | `data-testid`、`data-*`、稳定 `id` / `class` | 通常不变(开发者内部 ID) | ✅ 首选,但要先确认不是 hash / A-B test |
|
|
299
|
-
| **semantic / scope anchor** | `role`、结构关系、邻近稳定容器 | 不按 locale 翻译,但常常不唯一 | ⚠️ 只作 scope/filter;不要单独用 `button[role="button"]` |
|
|
300
|
-
| **locale-dependent 文本** | `aria-label`、`title`、`placeholder`、`alt`、`textContent` | 变(被 i18n 框架翻译) | ❌ 仅当 stable 选择器全都不存在时的兜底 |
|
|
301
|
-
|
|
302
|
-
ChatGPT 的 web 端就是反例驱动的:有些 controls 暴露稳定 `data-testid`,有些 surfaces 只暴露 `aria-label` / `placeholder`。这种站必须先用 stable selector,再用多语言 fallback list:
|
|
303
|
-
|
|
304
|
-
```javascript
|
|
305
|
-
// clis/chatgpt/utils.js(简化活例)
|
|
306
|
-
const COMPOSER_SELECTORS = [
|
|
307
|
-
'#prompt-textarea',
|
|
308
|
-
'[data-testid="composer"] [contenteditable="true"]',
|
|
309
|
-
'[aria-label="Chat with ChatGPT"]', // en
|
|
310
|
-
'[aria-label="与 ChatGPT 聊天"]', // zh-CN
|
|
311
|
-
'[placeholder="Ask anything"]',
|
|
312
|
-
'[placeholder="有问题,尽管问"]', // zh-CN
|
|
313
|
-
];
|
|
314
|
-
const SEND_BUTTON_SELECTORS = [
|
|
315
|
-
'button[data-testid="send-button"]:not([disabled])',
|
|
316
|
-
'button[aria-label="Send prompt"]:not([disabled])',
|
|
317
|
-
'button[aria-label="发送提示"]:not([disabled])',
|
|
318
|
-
];
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
写 fallback list 的纪律:
|
|
322
|
-
|
|
323
|
-
1. **stable selector 放最前**(`#prompt-textarea` / `[data-testid="send-button"]`),locale-dependent 的放后面当兜底
|
|
324
|
-
2. **`role` 只能当 semantic / scope filter**:`dialog [role="textbox"]` 可以;裸 `button` / `[role="button"]` 不够,因为同页可能有多个按钮
|
|
325
|
-
3. **每种 locale 至少列一条**(en + zh-CN 是底线;扩到 ja / ko / ar 看站点用户分布)
|
|
326
|
-
4. **commit 前 grep `aria-label=` / `placeholder=` / `title=` 看是不是漏了 fallback locale**——见 success-rate-pitfalls.md §11
|
|
327
|
-
5. **失败要 typed fail-fast**:找不到 control 应该 `CommandExecutionError` / send-failed,不要返回空 rows 或假成功
|
|
328
|
-
6. **不要给 framework 加 `--i18n "zh:提交,ja:送信"` 这种 flag** —— 等于把 fallback list 从 adapter 挪到 CLI,多一层 indirection 还要维护翻译字典。这是 over-engineering,已经在评审时被否
|
|
329
|
-
|
|
330
|
-
为什么不在 daemon 端固定 Chrome locale?因为 webcmd **不启动 Chrome**——daemon 是连用户已经在跑的 Chrome(CDP via extension),用户可能就是中文 UI / 中文资料检索需求。强制 en-US 会破坏用户的正当工作流。
|
|
331
|
-
|
|
332
|
-
### Cookie 域的双查
|
|
333
|
-
|
|
334
|
-
```javascript
|
|
335
|
-
for (const opts of [{ domain: HOST }, { domain: ROOT }]) { ... }
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
不是所有站都这么玄学,但下面这几类踩坑最多:
|
|
339
|
-
|
|
340
|
-
| 站点类型 | 坑 |
|
|
341
|
-
|---------|----|
|
|
342
|
-
| Discuz!X / phpBB / vBulletin 论坛 | Auth cookie 设在 `.<root>.com`,HttpOnly;业务页在 `www.<root>.com`。只查 `www.` 会漏 |
|
|
343
|
-
| 多子域账户体系(`account.x.com` vs `api.x.com`) | 登录时写在 account 域,API 域读取时拿不到 |
|
|
344
|
-
| 新版 Chrome SameSite=Lax 默认 | 某些 cookie 查 `url:` 才给返,查 `domain:` 不给 |
|
|
345
|
-
|
|
346
|
-
双查成本很低,不确定就两个都查,用 Map 去重第一次出现的 name。
|
|
347
|
-
|
|
348
|
-
### 空态抛 `EmptyResultError`,**不**塞 sentinel 行
|
|
349
|
-
|
|
350
|
-
历史上这里写的是"返回一行说明 row 比 `return []` 安全"。**这条已经反过来了**——见 PR #1329 R3 的 four anti-pattern fixes。现在的契约:
|
|
351
|
-
|
|
352
|
-
```javascript
|
|
353
|
-
import { EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
354
|
-
|
|
355
|
-
// ❌ 老写法:sentinel 行污染 row 合同,让 listing→detail round-trip 拿到 tid='' 白跑
|
|
356
|
-
if (/暂时没有提醒内容/.test(html)) {
|
|
357
|
-
return [{ index: 0, from: '', summary: '暂时没有提醒内容', time: '', threadUrl: '' }];
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// ✅ 新写法:empty 是合法状态,但不是 row。exit code 66 让 agent 直接 branch
|
|
361
|
-
if (/暂时没有提醒内容/.test(html)) {
|
|
362
|
-
throw new EmptyResultError('1point3acres notifications', '暂时没有提醒内容');
|
|
363
|
-
}
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
更多反例和详细 routing 见 [`typed-errors.md` §3](./typed-errors.md)。
|
|
367
|
-
|
|
368
|
-
---
|
|
369
|
-
|
|
370
|
-
## 同类型 adapter 对照
|
|
371
|
-
|
|
372
|
-
| 类型 | 代表 | 参考 |
|
|
373
|
-
|------|------|-----|
|
|
374
|
-
| clist 分页排行 | `convertible.js` / `rank.js` / `etf.js` / `sectors.js` | 都共享 `fs` + `fid` + `po` 结构 |
|
|
375
|
-
| ulist 批量报价 | `quote.js` | `secids` 逗号拼接 |
|
|
376
|
-
| K 线历史 | `kline.js` | `fields1 / fields2` 控列,CSV 解析 |
|
|
377
|
-
| 报表(datacenter-web) | `longhu.js` / `holders.js` | `reportName` 驱动 |
|
|
378
|
-
| 7x24 新闻 | `kuaixun.js` | `np-listapi` 栏目 id |
|
|
379
|
-
| 公司公告 | `announcement.js` | `np-anotice-stock` |
|
|
380
|
-
| 指数/北上 | `index-board.js` / `northbound.js` | push2 专用端点 |
|
|
381
|
-
|
|
382
|
-
新写一条时,选最像的那类,复制后改 `name` / URL / fields / column 映射三处。
|
|
383
|
-
|
|
384
|
-
---
|
|
226
|
+
## Parameter Safety
|
|
385
227
|
|
|
386
|
-
|
|
228
|
+
- Validate user-facing numbers before use.
|
|
229
|
+
- Throw `ArgumentError` for invalid external parameters.
|
|
230
|
+
- Do not silently clamp with `Math.max` / `Math.min` unless the user explicitly requested clamping and the output says so.
|
|
231
|
+
- Do not let a failed selector or missing field become a valid empty result.
|
|
387
232
|
|
|
388
|
-
|
|
233
|
+
## Row Safety
|
|
389
234
|
|
|
390
|
-
|
|
235
|
+
Before mapping rows:
|
|
391
236
|
|
|
392
|
-
|
|
237
|
+
- Confirm the response contains the expected shape.
|
|
238
|
+
- Throw `EmptyResultError` only when the site truly reports no results.
|
|
239
|
+
- Throw `CommandExecutionError` when the response shape is wrong, parsing fails, or an endpoint returns HTML instead of expected data.
|
|
240
|
+
- Use `AuthRequiredError` when login is required or session expired.
|
|
241
|
+
- Use `TimeoutError` when the page or endpoint did not settle in time.
|
|
393
242
|
|
|
394
|
-
|
|
243
|
+
## Column Alignment Checklist
|
|
395
244
|
|
|
396
|
-
|
|
397
|
-
- **数组形态** `["123", "--limit", "3"]` → 原样 append 到命令后,**positional 主语型** adapter 必须用这个
|
|
245
|
+
Before verify:
|
|
398
246
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
{ name: 'tid', type: 'string', required: true, positional: true },
|
|
408
|
-
{ name: 'limit', type: 'int', default: 20 },
|
|
409
|
-
],
|
|
410
|
-
// ...
|
|
411
|
-
});
|
|
247
|
+
```text
|
|
248
|
+
[ ] columns array and row keys match exactly
|
|
249
|
+
[ ] no intermediate object key overlaps a column accidentally
|
|
250
|
+
[ ] values use documented units
|
|
251
|
+
[ ] percentage scale is consistent
|
|
252
|
+
[ ] dates are ISO or clearly documented
|
|
253
|
+
[ ] URLs are absolute when users need to click them
|
|
254
|
+
[ ] one row was compared with the visible page
|
|
412
255
|
```
|
|
413
256
|
|
|
414
|
-
|
|
257
|
+
## Verify
|
|
415
258
|
|
|
416
|
-
|
|
417
|
-
{
|
|
418
|
-
"args": ["1234567", "--limit", "3"],
|
|
419
|
-
"expect": { "rowCount": { "min": 1, "max": 3 }, "...": "..." }
|
|
420
|
-
}
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
**不要写成** `{ "tid": "1234567", "limit": 3 }`——这会被展开成 `--tid 1234567 --limit 3`,commander 把 `--tid` 当未知 flag 报错,或者 adapter 根本不认。
|
|
424
|
-
|
|
425
|
-
### 种子 → 手改
|
|
426
|
-
|
|
427
|
-
named-flag adapter(`hot` / `latest` 类)可以直接让工具生成种子:
|
|
259
|
+
Run:
|
|
428
260
|
|
|
429
261
|
```bash
|
|
430
|
-
|
|
431
|
-
webcmd browser verify 1point3acres/hot --write-fixture
|
|
432
|
-
|
|
433
|
-
# 2. 手改 ~/.webcmd/sites/1point3acres/verify/hot.json
|
|
434
|
-
# - patterns: 加 URL / 日期 / ID 正则
|
|
435
|
-
# - notEmpty: 加核心字段(title / author / url)
|
|
436
|
-
# - rowCount: 收紧到业务合理区间
|
|
437
|
-
|
|
438
|
-
# 3. 再跑 verify,fixture 吃得动就 OK
|
|
439
|
-
webcmd browser verify 1point3acres/hot
|
|
262
|
+
webcmd browser verify <site>/<name> --trace retain-on-failure
|
|
440
263
|
```
|
|
441
264
|
|
|
442
|
-
|
|
265
|
+
After the first passing run, write a fixture:
|
|
443
266
|
|
|
444
267
|
```bash
|
|
445
|
-
|
|
446
|
-
webcmd 1point3acres thread 1173710 --limit 2 --format json | head
|
|
447
|
-
|
|
448
|
-
# 2. 照着响应手写 ~/.webcmd/sites/1point3acres/verify/thread.json
|
|
449
|
-
# (args 一定用数组: ["1173710", "--limit", "2"])
|
|
450
|
-
|
|
451
|
-
# 3. 跑 verify 核对
|
|
452
|
-
webcmd browser verify 1point3acres/thread
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
机器生成的种子只有 rowCount.min=1 / columns / types,挡不住字段值错位。**patterns + notEmpty 无论哪种情形都是肉写的**。
|
|
456
|
-
|
|
457
|
-
---
|
|
458
|
-
|
|
459
|
-
## 私人 adapter vs repo 贡献
|
|
460
|
-
|
|
461
|
-
```
|
|
462
|
-
~/.webcmd/clis/<site>/<name>.js # 私人
|
|
463
|
-
clis/<site>/<name>.js # repo 贡献
|
|
268
|
+
webcmd browser verify <site>/<name> --write-fixture
|
|
464
269
|
```
|
|
465
270
|
|
|
466
|
-
|
|
271
|
+
Then tighten the fixture manually:
|
|
467
272
|
|
|
468
|
-
-
|
|
469
|
-
-
|
|
273
|
+
- Add `notEmpty` for essential columns.
|
|
274
|
+
- Add `patterns` for URL, ID, date, or slug formats.
|
|
275
|
+
- Set realistic `rowCount`.
|
|
276
|
+
- Keep `types` narrow.
|
|
470
277
|
|
|
471
|
-
|
|
278
|
+
Run verify again and confirm the fixture matches.
|