@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
package/clis/boss/utils.js
DELETED
|
@@ -1,468 +0,0 @@
|
|
|
1
|
-
import { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
2
|
-
|
|
3
|
-
// ── Constants ───────────────────────────────────────────────────────────────
|
|
4
|
-
const BOSS_DOMAIN = 'www.zhipin.com';
|
|
5
|
-
const CHAT_URL = `https://${BOSS_DOMAIN}/web/chat/index`;
|
|
6
|
-
const COOKIE_EXPIRED_CODES = new Set([7, 37]);
|
|
7
|
-
const COOKIE_EXPIRED_MSG = 'Cookie 已过期!请在当前 Chrome 浏览器中重新登录 BOSS 直聘。';
|
|
8
|
-
const RECRUITER_ONLY_MSG = '该命令仅支持招聘端(BOSS 端)账号,请使用招聘者账号登录后重试。';
|
|
9
|
-
const DEFAULT_TIMEOUT = 15_000;
|
|
10
|
-
// ── Core helpers ────────────────────────────────────────────────────────────
|
|
11
|
-
/**
|
|
12
|
-
* Assert that page is available (non-null).
|
|
13
|
-
*/
|
|
14
|
-
export function requirePage(page) {
|
|
15
|
-
if (!page)
|
|
16
|
-
throw new CommandExecutionError('Browser page required');
|
|
17
|
-
}
|
|
18
|
-
export function readPositiveInteger(raw, name, fallback, max) {
|
|
19
|
-
const value = raw === undefined || raw === null || raw === '' ? fallback : Number(raw);
|
|
20
|
-
if (!Number.isInteger(value) || value < 1) {
|
|
21
|
-
throw new ArgumentError(`boss ${name} must be a positive integer`);
|
|
22
|
-
}
|
|
23
|
-
if (max !== undefined && value > max) {
|
|
24
|
-
throw new ArgumentError(`boss ${name} must be <= ${max}`);
|
|
25
|
-
}
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
28
|
-
export function readRequiredString(raw, name) {
|
|
29
|
-
const value = String(raw ?? '').trim();
|
|
30
|
-
if (!value) {
|
|
31
|
-
throw new ArgumentError(`boss ${name} cannot be empty`);
|
|
32
|
-
}
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Navigate to BOSS chat page and wait for it to settle.
|
|
37
|
-
* This establishes the cookie context needed for subsequent API calls.
|
|
38
|
-
*/
|
|
39
|
-
export async function navigateToChat(page, waitSeconds = 2) {
|
|
40
|
-
await page.goto(CHAT_URL);
|
|
41
|
-
await page.wait({ time: waitSeconds });
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Navigate to a custom BOSS page (for search/detail that use different pages).
|
|
45
|
-
*/
|
|
46
|
-
export async function navigateTo(page, url, waitSeconds = 1) {
|
|
47
|
-
await page.goto(url);
|
|
48
|
-
await page.wait({ time: waitSeconds });
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Check if an API response indicates cookie expiry and throw a clear error.
|
|
52
|
-
* Call this after every BOSS API response with a non-zero code.
|
|
53
|
-
*/
|
|
54
|
-
export function checkAuth(data) {
|
|
55
|
-
if (COOKIE_EXPIRED_CODES.has(data.code)) {
|
|
56
|
-
throw new AuthRequiredError(BOSS_DOMAIN, COOKIE_EXPIRED_MSG);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Map BOSS code=24 ("请切换身份后再试") to a typed AuthRequiredError.
|
|
61
|
-
* Recruiter-only commands (recommend, joblist, stats, resume, mark,
|
|
62
|
-
* exchange, invite, greet, batchgreet) have no geek-side equivalent;
|
|
63
|
-
* surfacing this as a generic COMMAND_EXEC hides what the user must do.
|
|
64
|
-
* chatlist / chatmsg avoid this path by using `allowNonZero: true` and
|
|
65
|
-
* branching to the geek-side fetch when they see code 24.
|
|
66
|
-
*/
|
|
67
|
-
function checkRecruiterSide(data) {
|
|
68
|
-
if (data.code === IDENTITY_MISMATCH_CODE) {
|
|
69
|
-
throw new AuthRequiredError(BOSS_DOMAIN, RECRUITER_ONLY_MSG);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Throw if the API response is not code 0.
|
|
74
|
-
* Checks for cookie expiry first, then identity mismatch, then throws
|
|
75
|
-
* with the provided message.
|
|
76
|
-
*/
|
|
77
|
-
export function assertOk(data, errorPrefix) {
|
|
78
|
-
if (!data || typeof data !== 'object') {
|
|
79
|
-
throw new CommandExecutionError(`${errorPrefix ? `${errorPrefix}: ` : ''}Boss API returned malformed response`);
|
|
80
|
-
}
|
|
81
|
-
if (data.code === 0)
|
|
82
|
-
return;
|
|
83
|
-
checkAuth(data);
|
|
84
|
-
checkRecruiterSide(data);
|
|
85
|
-
const prefix = errorPrefix ? `${errorPrefix}: ` : '';
|
|
86
|
-
throw new CommandExecutionError(`${prefix}${data.message || 'Unknown error'} (code=${data.code})`);
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Make a credentialed XHR request via page.evaluate().
|
|
90
|
-
*
|
|
91
|
-
* This is the single XHR template — no more copy-pasting the same 15-line
|
|
92
|
-
* XMLHttpRequest boilerplate across every adapter.
|
|
93
|
-
*
|
|
94
|
-
* @returns Parsed JSON response
|
|
95
|
-
* @throws On network error, timeout, JSON parse failure, or cookie expiry
|
|
96
|
-
*/
|
|
97
|
-
export async function bossFetch(page, url, opts = {}) {
|
|
98
|
-
const method = opts.method ?? 'GET';
|
|
99
|
-
const timeout = opts.timeout ?? DEFAULT_TIMEOUT;
|
|
100
|
-
const body = opts.body ?? null;
|
|
101
|
-
// Build the evaluate script. We use JSON.stringify for safe interpolation.
|
|
102
|
-
const script = `
|
|
103
|
-
async () => {
|
|
104
|
-
return new Promise((resolve, reject) => {
|
|
105
|
-
const xhr = new XMLHttpRequest();
|
|
106
|
-
xhr.open(${JSON.stringify(method)}, ${JSON.stringify(url)}, true);
|
|
107
|
-
xhr.withCredentials = true;
|
|
108
|
-
xhr.timeout = ${timeout};
|
|
109
|
-
xhr.setRequestHeader('Accept', 'application/json');
|
|
110
|
-
${method === 'POST' ? `xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');` : ''}
|
|
111
|
-
xhr.onload = () => {
|
|
112
|
-
try { resolve(JSON.parse(xhr.responseText)); }
|
|
113
|
-
catch(e) { reject(new Error('JSON parse failed: ' + xhr.responseText.substring(0, 200))); }
|
|
114
|
-
};
|
|
115
|
-
xhr.onerror = () => reject(new Error('Network Error'));
|
|
116
|
-
xhr.ontimeout = () => reject(new Error('Timeout'));
|
|
117
|
-
xhr.send(${body ? JSON.stringify(body) : 'null'});
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
`;
|
|
121
|
-
let data;
|
|
122
|
-
try {
|
|
123
|
-
data = await page.evaluate(script);
|
|
124
|
-
} catch (error) {
|
|
125
|
-
if (error instanceof AuthRequiredError || error instanceof CommandExecutionError) {
|
|
126
|
-
throw error;
|
|
127
|
-
}
|
|
128
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
129
|
-
throw new CommandExecutionError(`Boss API request failed: ${message}`);
|
|
130
|
-
}
|
|
131
|
-
if (!data || typeof data !== 'object') {
|
|
132
|
-
throw new CommandExecutionError('Boss API returned malformed response');
|
|
133
|
-
}
|
|
134
|
-
// Auto-check auth unless caller opts out
|
|
135
|
-
if (!opts.allowNonZero && data.code !== 0) {
|
|
136
|
-
assertOk(data);
|
|
137
|
-
}
|
|
138
|
-
return data;
|
|
139
|
-
}
|
|
140
|
-
// ── Convenience helpers ─────────────────────────────────────────────────────
|
|
141
|
-
/**
|
|
142
|
-
* Fetch the boss friend (chat) list.
|
|
143
|
-
*/
|
|
144
|
-
export async function fetchFriendList(page, opts = {}) {
|
|
145
|
-
const pageNum = opts.pageNum ?? 1;
|
|
146
|
-
const jobId = opts.jobId ?? '0';
|
|
147
|
-
const url = `https://${BOSS_DOMAIN}/wapi/zprelation/friend/getBossFriendListV2.json?page=${pageNum}&status=0&jobId=${jobId}`;
|
|
148
|
-
const data = await bossFetch(page, url, { allowNonZero: opts.allowNonZero });
|
|
149
|
-
if (opts.allowNonZero && data.code !== 0) return data;
|
|
150
|
-
const list = data.zpData?.friendList;
|
|
151
|
-
if (!Array.isArray(list)) {
|
|
152
|
-
throw new CommandExecutionError('Boss friend list response did not include zpData.friendList');
|
|
153
|
-
}
|
|
154
|
-
return list;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Fetch the recommended candidates (greetRecSortList).
|
|
158
|
-
*/
|
|
159
|
-
export async function fetchRecommendList(page) {
|
|
160
|
-
const url = `https://${BOSS_DOMAIN}/wapi/zprelation/friend/greetRecSortList`;
|
|
161
|
-
const data = await bossFetch(page, url);
|
|
162
|
-
const list = data.zpData?.friendList;
|
|
163
|
-
if (!Array.isArray(list)) {
|
|
164
|
-
throw new CommandExecutionError('Boss recommend response did not include zpData.friendList');
|
|
165
|
-
}
|
|
166
|
-
return list;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Find a friend by encryptUid, searching through friend list and optionally greet list.
|
|
170
|
-
* Returns null if not found.
|
|
171
|
-
*/
|
|
172
|
-
export async function findFriendByUid(page, encryptUid, opts = {}) {
|
|
173
|
-
const maxPages = opts.maxPages ?? 1;
|
|
174
|
-
const checkGreetList = opts.checkGreetList ?? false;
|
|
175
|
-
// Search friend list pages
|
|
176
|
-
for (let p = 1; p <= maxPages; p++) {
|
|
177
|
-
const result = await fetchFriendList(page, { pageNum: p, allowNonZero: opts.allowNonZero });
|
|
178
|
-
if (opts.allowNonZero && !Array.isArray(result)) {
|
|
179
|
-
return { friend: null, code: result.code };
|
|
180
|
-
}
|
|
181
|
-
const friends = Array.isArray(result) ? result : [];
|
|
182
|
-
const found = friends.find((f) => f.encryptUid === encryptUid);
|
|
183
|
-
if (found)
|
|
184
|
-
return opts.allowNonZero ? { friend: found, code: 0 } : found;
|
|
185
|
-
if (friends.length === 0)
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
// Optionally check greet list
|
|
189
|
-
if (checkGreetList) {
|
|
190
|
-
const greetList = await fetchRecommendList(page);
|
|
191
|
-
const found = greetList.find((f) => f.encryptUid === encryptUid);
|
|
192
|
-
if (found)
|
|
193
|
-
return opts.allowNonZero ? { friend: found, code: 0 } : found;
|
|
194
|
-
}
|
|
195
|
-
return opts.allowNonZero ? { friend: null, code: 0 } : null;
|
|
196
|
-
}
|
|
197
|
-
// ── UI automation helpers ───────────────────────────────────────────────────
|
|
198
|
-
/**
|
|
199
|
-
* Click on a candidate in the chat list by their numeric UID.
|
|
200
|
-
* @returns true if clicked, false if not found
|
|
201
|
-
*/
|
|
202
|
-
export async function clickCandidateInList(page, numericUid) {
|
|
203
|
-
const uid = String(numericUid).replace(/[^0-9]/g, ''); // sanitize to digits only
|
|
204
|
-
const result = await page.evaluate(`
|
|
205
|
-
async () => {
|
|
206
|
-
const uid = ${JSON.stringify(uid)};
|
|
207
|
-
const item = document.querySelector('#_' + uid + '-0') || document.querySelector('[id^="_' + uid + '"]');
|
|
208
|
-
if (item) {
|
|
209
|
-
item.click();
|
|
210
|
-
return { clicked: true };
|
|
211
|
-
}
|
|
212
|
-
const items = document.querySelectorAll('.geek-item');
|
|
213
|
-
for (const el of items) {
|
|
214
|
-
if (el.id && el.id.startsWith('_' + uid)) {
|
|
215
|
-
el.click();
|
|
216
|
-
return { clicked: true };
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return { clicked: false };
|
|
220
|
-
}
|
|
221
|
-
`);
|
|
222
|
-
return result.clicked;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Type a message into the chat editor and send it.
|
|
226
|
-
* @returns true if sent successfully
|
|
227
|
-
*/
|
|
228
|
-
export async function typeAndSendMessage(page, text) {
|
|
229
|
-
const typed = await page.evaluate(`
|
|
230
|
-
async () => {
|
|
231
|
-
const selectors = [
|
|
232
|
-
'.chat-editor [contenteditable="true"]',
|
|
233
|
-
'.chat-input [contenteditable="true"]',
|
|
234
|
-
'.message-editor [contenteditable="true"]',
|
|
235
|
-
'.chat-conversation [contenteditable="true"]',
|
|
236
|
-
'[contenteditable="true"]',
|
|
237
|
-
'textarea',
|
|
238
|
-
];
|
|
239
|
-
for (const sel of selectors) {
|
|
240
|
-
const el = document.querySelector(sel);
|
|
241
|
-
if (el && el.offsetParent !== null) {
|
|
242
|
-
el.focus();
|
|
243
|
-
if (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT') {
|
|
244
|
-
el.value = ${JSON.stringify(text)};
|
|
245
|
-
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
246
|
-
} else {
|
|
247
|
-
el.textContent = '';
|
|
248
|
-
el.focus();
|
|
249
|
-
document.execCommand('insertText', false, ${JSON.stringify(text)});
|
|
250
|
-
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
251
|
-
}
|
|
252
|
-
return { found: true };
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
return { found: false };
|
|
256
|
-
}
|
|
257
|
-
`);
|
|
258
|
-
if (!typed.found)
|
|
259
|
-
return false;
|
|
260
|
-
await page.wait({ time: 0.5 });
|
|
261
|
-
// Click send button
|
|
262
|
-
const sent = await page.evaluate(`
|
|
263
|
-
async () => {
|
|
264
|
-
const btn = document.querySelector('.conversation-editor .submit')
|
|
265
|
-
|| document.querySelector('.submit-content .submit')
|
|
266
|
-
|| document.querySelector('.conversation-operate .submit');
|
|
267
|
-
if (btn) {
|
|
268
|
-
btn.click();
|
|
269
|
-
return { clicked: true };
|
|
270
|
-
}
|
|
271
|
-
return { clicked: false };
|
|
272
|
-
}
|
|
273
|
-
`);
|
|
274
|
-
if (!sent.clicked) {
|
|
275
|
-
await page.pressKey('Enter');
|
|
276
|
-
}
|
|
277
|
-
return true;
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Verbose log helper — prints when WEBCMD_VERBOSE is set.
|
|
281
|
-
*/
|
|
282
|
-
export function verbose(msg) {
|
|
283
|
-
if (process.env.WEBCMD_VERBOSE) {
|
|
284
|
-
console.error(`[webcmd:boss] ${msg}`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
// ── Geek-side helpers ────────────────────────────────────────────────────────
|
|
288
|
-
export const IDENTITY_MISMATCH_CODE = 24;
|
|
289
|
-
const GEEK_CHAT_URL = `https://${BOSS_DOMAIN}/web/geek/chat`;
|
|
290
|
-
/**
|
|
291
|
-
* Navigate to the job-seeker chat page.
|
|
292
|
-
* Establishes the cookie + JS-global context needed for geek-side API calls.
|
|
293
|
-
*/
|
|
294
|
-
export async function navigateToGeekChat(page, waitSeconds = 2) {
|
|
295
|
-
await page.goto(GEEK_CHAT_URL);
|
|
296
|
-
await page.wait({ time: waitSeconds });
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Read the encryptSystemId value required by the geek-side list API.
|
|
300
|
-
* Strategy (in order):
|
|
301
|
-
* 1. Vue app state / Pinia stores / $route.query (Option 1 — runtime source)
|
|
302
|
-
* 2. performance.getEntriesByType('resource') — parse from geekFilterByLabel URL
|
|
303
|
-
* that the page itself already issued (Option 2 — most deterministic)
|
|
304
|
-
* 3. cookie, inline <script> SSR state, known window globals, localStorage (fallbacks)
|
|
305
|
-
* Returns empty string if nothing is found; the API may still succeed without it.
|
|
306
|
-
* Caller must have navigated to the geek chat page first.
|
|
307
|
-
*/
|
|
308
|
-
export async function readEncryptSystemId(page) {
|
|
309
|
-
const result = await page.evaluate(`
|
|
310
|
-
(() => {
|
|
311
|
-
// 1. Vue app state / Pinia / $route.query
|
|
312
|
-
// The chat component reads encryptSystemId from the app runtime to build
|
|
313
|
-
// its own geekFilterByLabel request, so the value lives in the Vue tree.
|
|
314
|
-
try {
|
|
315
|
-
const appEl = document.querySelector('#app') || document.querySelector('[data-v-app]');
|
|
316
|
-
const vueApp = appEl && (appEl.__vue_app__ || appEl._vei);
|
|
317
|
-
if (vueApp) {
|
|
318
|
-
// 1a. Pinia stores (Vue 3 standard state management on BOSS直聘)
|
|
319
|
-
const pinia = vueApp.config && vueApp.config.globalProperties.$pinia;
|
|
320
|
-
if (pinia && pinia.state && pinia.state.value) {
|
|
321
|
-
for (const store of Object.values(pinia.state.value)) {
|
|
322
|
-
try {
|
|
323
|
-
const flat = JSON.stringify(store);
|
|
324
|
-
if (flat.includes('encryptSystemId')) {
|
|
325
|
-
const m = flat.match(/"encryptSystemId":"([^"]+)"/);
|
|
326
|
-
if (m) return m[1];
|
|
327
|
-
}
|
|
328
|
-
} catch (_) {}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
// 1b. Vue Router current route query
|
|
332
|
-
const router = vueApp.config && vueApp.config.globalProperties.$router;
|
|
333
|
-
const query = router && router.currentRoute && router.currentRoute.value && router.currentRoute.value.query;
|
|
334
|
-
if (query && query.encryptSystemId) return query.encryptSystemId;
|
|
335
|
-
}
|
|
336
|
-
} catch (_) {}
|
|
337
|
-
// 2. Performance resource entries — the page already issued geekFilterByLabel
|
|
338
|
-
// with encryptSystemId in the URL; read it back from the resource timing API.
|
|
339
|
-
try {
|
|
340
|
-
const entries = performance.getEntriesByType('resource');
|
|
341
|
-
for (const entry of entries) {
|
|
342
|
-
if (!entry.name.includes('geekFilterByLabel')) continue;
|
|
343
|
-
const u = new URL(entry.name);
|
|
344
|
-
const v = u.searchParams.get('encryptSystemId');
|
|
345
|
-
if (v) return v;
|
|
346
|
-
}
|
|
347
|
-
} catch (_) {}
|
|
348
|
-
// 3. cookie
|
|
349
|
-
try {
|
|
350
|
-
const m = document.cookie.match(/encryptSystemId=([^;]+)/i);
|
|
351
|
-
if (m) return decodeURIComponent(m[1]);
|
|
352
|
-
} catch (_) {}
|
|
353
|
-
// 4. inline <script> SSR state (Nuxt embeds server state here)
|
|
354
|
-
try {
|
|
355
|
-
for (const s of document.querySelectorAll('script:not([src])')) {
|
|
356
|
-
const t = s.textContent || '';
|
|
357
|
-
if (!t.includes('encryptSystemId')) continue;
|
|
358
|
-
const m = t.match(/"encryptSystemId":"([^"]+)"/);
|
|
359
|
-
if (m) return m[1];
|
|
360
|
-
}
|
|
361
|
-
} catch (_) {}
|
|
362
|
-
// 5. known BOSS / Nuxt window globals
|
|
363
|
-
const KNOWN = [
|
|
364
|
-
'__NUXT__', '__INITIAL_STATE__', '__ZP_INFO__', '__BOSS_ZP__',
|
|
365
|
-
'pageGlobalVar', 'ZP_DATA', '__ZP_DATA__', '__PAGE_DATA__',
|
|
366
|
-
];
|
|
367
|
-
for (const k of KNOWN) {
|
|
368
|
-
const obj = window[k];
|
|
369
|
-
if (!obj || typeof obj !== 'object') continue;
|
|
370
|
-
try {
|
|
371
|
-
const flat = JSON.stringify(obj);
|
|
372
|
-
if (!flat.includes('encryptSystemId')) continue;
|
|
373
|
-
const m = flat.match(/"encryptSystemId":"([^"]+)"/);
|
|
374
|
-
if (m) return m[1];
|
|
375
|
-
} catch (_) {}
|
|
376
|
-
}
|
|
377
|
-
// 6. localStorage
|
|
378
|
-
try {
|
|
379
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
380
|
-
const k = localStorage.key(i);
|
|
381
|
-
if (!k) continue;
|
|
382
|
-
if (k.toLowerCase().includes('encryptsystemid')) {
|
|
383
|
-
const v = localStorage.getItem(k);
|
|
384
|
-
if (v) return v;
|
|
385
|
-
}
|
|
386
|
-
const v = localStorage.getItem(k) || '';
|
|
387
|
-
if (v.includes('encryptSystemId')) {
|
|
388
|
-
const m = v.match(/"encryptSystemId":"([^"]+)"/);
|
|
389
|
-
if (m) return m[1];
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
} catch (_) {}
|
|
393
|
-
return '';
|
|
394
|
-
})()
|
|
395
|
-
`);
|
|
396
|
-
return result || '';
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Fetch the job-seeker chat list (brief info, no securityId).
|
|
400
|
-
* Use fetchGeekFriendInfoList to enrich with securityId before calling chatmsg.
|
|
401
|
-
*/
|
|
402
|
-
export async function fetchGeekFriendLabelList(page, opts = {}) {
|
|
403
|
-
const labelId = opts.labelId ?? 0;
|
|
404
|
-
const encryptSystemId = opts.encryptSystemId ?? '';
|
|
405
|
-
const url = `https://${BOSS_DOMAIN}/wapi/zprelation/friend/geekFilterByLabel?labelId=${labelId}&encryptSystemId=${encodeURIComponent(encryptSystemId)}`;
|
|
406
|
-
const data = await bossFetch(page, url, { allowNonZero: opts.allowNonZero });
|
|
407
|
-
if (opts.allowNonZero && data.code !== 0) return data;
|
|
408
|
-
const list = data.zpData?.friendList;
|
|
409
|
-
if (!Array.isArray(list)) {
|
|
410
|
-
throw new CommandExecutionError('Boss geek chat list response did not include zpData.friendList');
|
|
411
|
-
}
|
|
412
|
-
return list;
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Enrich a batch of geek friends with full fields including securityId.
|
|
416
|
-
* Processes in batches of 50 to avoid oversized request bodies.
|
|
417
|
-
*/
|
|
418
|
-
export async function fetchGeekFriendInfoList(page, friendIds = []) {
|
|
419
|
-
if (!friendIds.length) return [];
|
|
420
|
-
const BATCH_SIZE = 50;
|
|
421
|
-
const results = [];
|
|
422
|
-
for (let i = 0; i < friendIds.length; i += BATCH_SIZE) {
|
|
423
|
-
const batch = friendIds.slice(i, i + BATCH_SIZE).map(String);
|
|
424
|
-
const body = `friendIds=${batch.join(',')}`;
|
|
425
|
-
const data = await bossFetch(page, `https://${BOSS_DOMAIN}/wapi/zprelation/friend/getGeekFriendList.json`, {
|
|
426
|
-
method: 'POST',
|
|
427
|
-
body,
|
|
428
|
-
});
|
|
429
|
-
const batchResult = data.zpData?.result;
|
|
430
|
-
if (!Array.isArray(batchResult)) {
|
|
431
|
-
throw new CommandExecutionError('Boss geek friend enrichment response did not include zpData.result');
|
|
432
|
-
}
|
|
433
|
-
results.push(...batchResult);
|
|
434
|
-
}
|
|
435
|
-
return results;
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Find a geek-side friend by encrypted uid.
|
|
439
|
-
* Merges label-list and enriched data; returns null if not found.
|
|
440
|
-
*/
|
|
441
|
-
export async function findGeekFriendByUid(page, encryptUid, opts = {}) {
|
|
442
|
-
const labelList = await fetchGeekFriendLabelList(page, { encryptSystemId: opts.encryptSystemId });
|
|
443
|
-
const candidate = labelList.find((f) => f.encryptFriendId === encryptUid ||
|
|
444
|
-
String(f.uid) === String(encryptUid) ||
|
|
445
|
-
String(f.friendId) === String(encryptUid));
|
|
446
|
-
if (!candidate) return null;
|
|
447
|
-
const enriched = await fetchGeekFriendInfoList(page, [candidate.friendId]);
|
|
448
|
-
return { ...candidate, ...(enriched[0] || {}) };
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Fetch message history for a geek-side chat.
|
|
452
|
-
* friend must have .uid (boss's numeric id) and .securityId.
|
|
453
|
-
*/
|
|
454
|
-
export async function fetchGeekHistoryMsg(page, friend, opts = {}) {
|
|
455
|
-
const pageNum = opts.page ?? 1;
|
|
456
|
-
const bossId = friend.uid;
|
|
457
|
-
const securityId = encodeURIComponent(friend.securityId || '');
|
|
458
|
-
const url = `https://${BOSS_DOMAIN}/wapi/zpchat/geek/historyMsg?bossId=${bossId}&securityId=${securityId}&page=${pageNum}&c=20&src=0`;
|
|
459
|
-
const data = await bossFetch(page, url);
|
|
460
|
-
const messages = data.zpData?.messages ?? data.zpData?.historyMsgList;
|
|
461
|
-
if (!Array.isArray(messages)) {
|
|
462
|
-
throw new CommandExecutionError('Boss geek history response did not include a message list');
|
|
463
|
-
}
|
|
464
|
-
if (messages.length === 0) {
|
|
465
|
-
throw new EmptyResultError('boss chatmsg', 'Boss returned no messages for this chat.');
|
|
466
|
-
}
|
|
467
|
-
return messages;
|
|
468
|
-
}
|
package/clis/boss/utils.test.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { AuthRequiredError, CommandExecutionError } from '@agentrhq/webcmd/errors';
|
|
3
|
-
import { assertOk } from './utils.js';
|
|
4
|
-
|
|
5
|
-
describe('assertOk', () => {
|
|
6
|
-
it('returns silently on code 0', () => {
|
|
7
|
-
expect(() => assertOk({ code: 0 })).not.toThrow();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('maps expired cookie codes (7, 37) to AuthRequiredError', () => {
|
|
11
|
-
expect(() => assertOk({ code: 7, message: 'expired' })).toThrow(AuthRequiredError);
|
|
12
|
-
expect(() => assertOk({ code: 37, message: 'expired' })).toThrow(AuthRequiredError);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('maps code 24 (identity mismatch) to AuthRequiredError with recruiter-only hint', () => {
|
|
16
|
-
try {
|
|
17
|
-
assertOk({ code: 24, message: '请切换身份后再试' });
|
|
18
|
-
throw new Error('assertOk should have thrown');
|
|
19
|
-
} catch (err) {
|
|
20
|
-
expect(err).toBeInstanceOf(AuthRequiredError);
|
|
21
|
-
expect(String(err.message)).toContain('招聘端');
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('falls through to CommandExecutionError for other non-zero codes', () => {
|
|
26
|
-
expect(() => assertOk({ code: 99, message: 'something else' }))
|
|
27
|
-
.toThrow(CommandExecutionError);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('throws CommandExecutionError on malformed (non-object) response', () => {
|
|
31
|
-
expect(() => assertOk(null)).toThrow(CommandExecutionError);
|
|
32
|
-
expect(() => assertOk('not-an-object')).toThrow(CommandExecutionError);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
2
|
-
import { AuthRequiredError } from '@agentrhq/webcmd/errors';
|
|
3
|
-
import { getCourses, initSession, enterCourse, getTabIframeUrl, parseAssignmentsFromDom, sleep, } from './utils.js';
|
|
4
|
-
cli({
|
|
5
|
-
site: 'chaoxing',
|
|
6
|
-
name: 'assignments',
|
|
7
|
-
access: 'read',
|
|
8
|
-
description: '学习通作业列表',
|
|
9
|
-
domain: 'mooc2-ans.chaoxing.com',
|
|
10
|
-
strategy: Strategy.COOKIE,
|
|
11
|
-
args: [
|
|
12
|
-
{ name: 'course', type: 'string', help: '按课程名过滤(模糊匹配)' },
|
|
13
|
-
{
|
|
14
|
-
name: 'status',
|
|
15
|
-
type: 'string',
|
|
16
|
-
default: 'all',
|
|
17
|
-
choices: ['all', 'pending', 'submitted', 'graded'],
|
|
18
|
-
help: '按状态过滤',
|
|
19
|
-
},
|
|
20
|
-
{ name: 'limit', type: 'int', default: 20, help: '最大返回数量' },
|
|
21
|
-
{ name: 'timeout', type: 'int', required: false, default: 90, help: 'Max seconds for the overall command (default: 90)' },
|
|
22
|
-
],
|
|
23
|
-
columns: ['rank', 'course', 'title', 'deadline', 'status', 'score'],
|
|
24
|
-
func: async (page, kwargs) => {
|
|
25
|
-
const { course: courseFilter, status: statusFilter = 'all', limit = 20 } = kwargs;
|
|
26
|
-
// 1. Establish session
|
|
27
|
-
await initSession(page);
|
|
28
|
-
// 2. Get courses
|
|
29
|
-
const courses = await getCourses(page);
|
|
30
|
-
if (!courses.length)
|
|
31
|
-
throw new AuthRequiredError('mooc2-ans.chaoxing.com', '未获取到课程列表');
|
|
32
|
-
const filtered = courseFilter
|
|
33
|
-
? courses.filter(c => c.title.includes(courseFilter))
|
|
34
|
-
: courses;
|
|
35
|
-
if (courseFilter && !filtered.length) {
|
|
36
|
-
throw new Error(`未找到匹配「${courseFilter}」的课程`);
|
|
37
|
-
}
|
|
38
|
-
// 3. Per-course: enter → click 作业 tab → navigate to iframe → parse
|
|
39
|
-
const allRows = [];
|
|
40
|
-
for (const c of filtered) {
|
|
41
|
-
try {
|
|
42
|
-
await enterCourse(page, c);
|
|
43
|
-
const iframeUrl = await getTabIframeUrl(page, '作业');
|
|
44
|
-
if (!iframeUrl)
|
|
45
|
-
continue;
|
|
46
|
-
await page.goto(iframeUrl);
|
|
47
|
-
await page.wait(2);
|
|
48
|
-
const rows = await parseAssignmentsFromDom(page, c.title);
|
|
49
|
-
allRows.push(...rows);
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
// Single course failure: skip, continue
|
|
53
|
-
}
|
|
54
|
-
if (filtered.length > 1)
|
|
55
|
-
await sleep(600);
|
|
56
|
-
}
|
|
57
|
-
// 4. Sort: pending first, then by deadline
|
|
58
|
-
allRows.sort((a, b) => {
|
|
59
|
-
const order = (s) => s === '未交' ? 0 : s === '待批阅' ? 1 : s === '已完成' ? 2 : s === '已批阅' ? 3 : 4;
|
|
60
|
-
return order(a.status) - order(b.status);
|
|
61
|
-
});
|
|
62
|
-
// 5. Filter by status
|
|
63
|
-
const statusMap = {
|
|
64
|
-
pending: ['未交'],
|
|
65
|
-
submitted: ['待批阅', '已完成'],
|
|
66
|
-
graded: ['已批阅'],
|
|
67
|
-
};
|
|
68
|
-
const finalRows = statusFilter === 'all'
|
|
69
|
-
? allRows
|
|
70
|
-
: allRows.filter(r => statusMap[statusFilter]?.includes(r.status));
|
|
71
|
-
return finalRows.slice(0, Number(limit)).map((item, i) => ({
|
|
72
|
-
rank: i + 1,
|
|
73
|
-
...item,
|
|
74
|
-
}));
|
|
75
|
-
},
|
|
76
|
-
});
|
package/clis/chaoxing/auth.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { AuthRequiredError, CommandExecutionError } from '@agentrhq/webcmd/errors';
|
|
2
|
-
import { registerSiteAuthCommands } from '../_shared/site-auth.js';
|
|
3
|
-
|
|
4
|
-
async function hasChaoxingSessionCookie(page) {
|
|
5
|
-
const cookies = await page.getCookies({ url: 'https://i.chaoxing.com' });
|
|
6
|
-
return cookies.some(c => /^(UID|_uid|chaoxinguser|cx_p_token)$/i.test(c.name) && c.value);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
async function verifyChaoxingIdentity(page) {
|
|
10
|
-
if (!await hasChaoxingSessionCookie(page)) {
|
|
11
|
-
throw new AuthRequiredError('chaoxing.com', 'Chaoxing session cookies missing');
|
|
12
|
-
}
|
|
13
|
-
await page.goto('https://i.chaoxing.com/');
|
|
14
|
-
await page.wait(3);
|
|
15
|
-
const probe = await page.evaluate(`
|
|
16
|
-
(() => {
|
|
17
|
-
if (/passport2\\.chaoxing\\.com\\/login/.test(location.href)) {
|
|
18
|
-
return { kind: 'auth', detail: 'Chaoxing i.chaoxing.com redirected to passport2 login' };
|
|
19
|
-
}
|
|
20
|
-
const userIdCookie = (document.cookie.split('; ').find(c => /^(_uid|UID)=/.test(c)) || '').split('=')[1] || '';
|
|
21
|
-
let userName = '';
|
|
22
|
-
const unameCookie = (document.cookie.split('; ').find(c => /^uname=/.test(c)) || '').split('=')[1] || '';
|
|
23
|
-
if (unameCookie) {
|
|
24
|
-
try { userName = decodeURIComponent(unameCookie); } catch { userName = unameCookie; }
|
|
25
|
-
}
|
|
26
|
-
if (!userName) {
|
|
27
|
-
const el = document.querySelector('.userTitle, .myInfo, .user-name, [class*=userName]');
|
|
28
|
-
userName = (el?.innerText || '').trim();
|
|
29
|
-
}
|
|
30
|
-
if (!userIdCookie && !userName) {
|
|
31
|
-
return { kind: 'auth', detail: 'Chaoxing i.chaoxing.com no user identity surface — anonymous' };
|
|
32
|
-
}
|
|
33
|
-
return { ok: true, user_id: userIdCookie, name: userName };
|
|
34
|
-
})()
|
|
35
|
-
`);
|
|
36
|
-
if (probe?.kind === 'auth') throw new AuthRequiredError('chaoxing.com', probe.detail);
|
|
37
|
-
if (!probe?.ok) throw new CommandExecutionError(`Unexpected Chaoxing probe: ${JSON.stringify(probe)}`);
|
|
38
|
-
return { user_id: probe.user_id, name: probe.name };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
registerSiteAuthCommands({
|
|
42
|
-
site: 'chaoxing',
|
|
43
|
-
domain: 'chaoxing.com',
|
|
44
|
-
loginUrl: 'https://passport2.chaoxing.com/login?fid=&newversion=true&refer=https%3A%2F%2Fi.chaoxing.com',
|
|
45
|
-
columns: ['user_id', 'name'],
|
|
46
|
-
quickCheck: hasChaoxingSessionCookie,
|
|
47
|
-
verify: verifyChaoxingIdentity,
|
|
48
|
-
poll: async (page) => {
|
|
49
|
-
if (!await hasChaoxingSessionCookie(page)) {
|
|
50
|
-
throw new AuthRequiredError('chaoxing.com', 'Waiting for Chaoxing session cookies');
|
|
51
|
-
}
|
|
52
|
-
return verifyChaoxingIdentity(page);
|
|
53
|
-
},
|
|
54
|
-
});
|