@agentrhq/webcmd 0.1.2 → 0.2.1
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 +196 -219
- package/cli-manifest.json +16205 -34869
- 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/delete.js +14 -6
- package/clis/twitter/delete.test.js +74 -1
- 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/timeline.js +3 -1
- package/clis/twitter/timeline.test.js +4 -0
- 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/bridge-readiness.test.js +1 -1
- package/dist/src/browser/bridge.d.ts +1 -0
- package/dist/src/browser/bridge.js +6 -4
- package/dist/src/browser/cdp.d.ts +1 -0
- package/dist/src/browser/daemon-client.d.ts +2 -0
- package/dist/src/browser/daemon-client.js +108 -51
- package/dist/src/browser/daemon-client.test.js +135 -47
- package/dist/src/browser/daemon-transport.js +3 -19
- package/dist/src/browser/errors.js +11 -0
- package/dist/src/browser/page.d.ts +2 -1
- package/dist/src/browser/page.js +5 -1
- package/dist/src/browser/profile.d.ts +9 -0
- package/dist/src/browser/profile.js +18 -7
- package/dist/src/browser/profile.test.js +44 -0
- package/dist/src/browser/protocol.d.ts +3 -0
- package/dist/src/browser/runtime/local-cloak/actions.js +24 -10
- package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.js +3 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.test.js +87 -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 +24 -19
- package/dist/src/cli.test.js +59 -59
- package/dist/src/commanderAdapter.test.js +19 -19
- package/dist/src/commands/daemon.test.js +13 -13
- package/dist/src/constants.d.ts +2 -3
- package/dist/src/constants.js +3 -10
- 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.js +1 -5
- package/dist/src/daemon.test.js +10 -1
- package/dist/src/doctor.js +19 -1
- package/dist/src/doctor.test.js +38 -4
- 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 +7 -3
- 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.js +19 -1
- package/dist/src/external.test.js +39 -18
- 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 -6
- package/dist/src/manifest-types.d.ts +1 -1
- package/dist/src/node-network.test.js +5 -5
- 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.d.ts +1 -0
- package/dist/src/release-notes.test.js +61 -0
- package/dist/src/runtime-identity.test.js +0 -8
- package/dist/src/runtime.d.ts +2 -0
- package/dist/src/runtime.js +1 -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 +5 -2
- 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/browser/profile.test.d.ts} +0 -0
- /package/dist/src/{weixin-download.test.d.ts → generate-release-notes-cli.test.d.ts} +0 -0
package/clis/12306/price.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 12306 ticket price lookup for a single train + segment.
|
|
3
|
-
*
|
|
4
|
-
* Cascades three anonymous API calls:
|
|
5
|
-
* 1. /otn/leftTicket/init: mint session cookies
|
|
6
|
-
* 2. /otn/czxx/queryByTrainNo: resolve from/to station_no within the
|
|
7
|
-
* train route (price endpoint addresses stops by station_no, not
|
|
8
|
-
* telecode)
|
|
9
|
-
* 3. /otn/leftTicket/queryTicketPrice: ticket prices keyed by seat
|
|
10
|
-
* letter (M=一等座, O=二等座, A9=商务座, A1=硬座, A3=硬卧,
|
|
11
|
-
* A4=软卧, F=动卧, P=特等座, WZ=无座, etc.)
|
|
12
|
-
*/
|
|
13
|
-
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
14
|
-
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
15
|
-
import { fetchStationBundle, mintSession, resolveStation, validateDate } from './utils.js';
|
|
16
|
-
|
|
17
|
-
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36';
|
|
18
|
-
const TRAIN_NO_RE = /^[0-9A-Za-z]{8,18}$/;
|
|
19
|
-
const SEAT_TYPES_RE = /^[A-Z0-9]{1,32}$/;
|
|
20
|
-
|
|
21
|
-
const SEAT_LETTERS = {
|
|
22
|
-
'A9': '商务座',
|
|
23
|
-
'P': '特等座',
|
|
24
|
-
'M': '一等座',
|
|
25
|
-
'O': '二等座',
|
|
26
|
-
'A1': '硬座',
|
|
27
|
-
'A3': '硬卧',
|
|
28
|
-
'A4': '软卧',
|
|
29
|
-
'F': '动卧',
|
|
30
|
-
'WZ': '无座',
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
async function queryStopsForPrice(cookieHeader, trainNo, fromCode, toCode, date, fetchImpl = fetch) {
|
|
34
|
-
const url = `https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=${trainNo}&from_station_telecode=${fromCode}&to_station_telecode=${toCode}&depart_date=${date}`;
|
|
35
|
-
const resp = await fetchImpl(url, {
|
|
36
|
-
headers: {
|
|
37
|
-
'User-Agent': UA,
|
|
38
|
-
'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init',
|
|
39
|
-
'Cookie': cookieHeader,
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
if (!resp.ok) throw new CommandExecutionError(`12306 queryByTrainNo returned HTTP ${resp.status}`);
|
|
43
|
-
let json;
|
|
44
|
-
try {
|
|
45
|
-
json = await resp.json();
|
|
46
|
-
} catch {
|
|
47
|
-
throw new CommandExecutionError('12306 queryByTrainNo returned non-JSON body');
|
|
48
|
-
}
|
|
49
|
-
if (json?.status !== true || !Array.isArray(json?.data?.data)) {
|
|
50
|
-
throw new CommandExecutionError('12306 queryByTrainNo returned an unexpected payload shape');
|
|
51
|
-
}
|
|
52
|
-
return json.data.data;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function pickStationNos(stops, fromCode, toCode, fromName, toName) {
|
|
56
|
-
const matches = (s, code, name) => (s.station_name && name && s.station_name === name);
|
|
57
|
-
const fromStop = stops.find((s) => matches(s, fromCode, fromName));
|
|
58
|
-
const toStop = stops.find((s) => matches(s, toCode, toName));
|
|
59
|
-
if (!fromStop) throw new CommandExecutionError(`Train does not stop at ${fromName}`);
|
|
60
|
-
if (!toStop) throw new CommandExecutionError(`Train does not stop at ${toName}`);
|
|
61
|
-
return { fromNo: fromStop.station_no, toNo: toStop.station_no };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function queryPrice(cookieHeader, trainNo, fromNo, toNo, seatTypes, date, fetchImpl = fetch) {
|
|
65
|
-
const url = `https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=${trainNo}&from_station_no=${fromNo}&to_station_no=${toNo}&seat_types=${seatTypes}&train_date=${date}`;
|
|
66
|
-
const resp = await fetchImpl(url, {
|
|
67
|
-
headers: {
|
|
68
|
-
'User-Agent': UA,
|
|
69
|
-
'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init',
|
|
70
|
-
'Cookie': cookieHeader,
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
if (!resp.ok) throw new CommandExecutionError(`12306 queryTicketPrice returned HTTP ${resp.status}`);
|
|
74
|
-
let json;
|
|
75
|
-
try {
|
|
76
|
-
json = await resp.json();
|
|
77
|
-
} catch {
|
|
78
|
-
throw new CommandExecutionError('12306 queryTicketPrice returned non-JSON body');
|
|
79
|
-
}
|
|
80
|
-
if (json?.status !== true || !json?.data) {
|
|
81
|
-
throw new CommandExecutionError('12306 queryTicketPrice returned an unexpected payload shape');
|
|
82
|
-
}
|
|
83
|
-
return json.data;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function parsePriceData(priceData) {
|
|
87
|
-
const rows = [];
|
|
88
|
-
for (const [letter, value] of Object.entries(priceData)) {
|
|
89
|
-
if (letter === 'train_no' || letter === 'OT') continue;
|
|
90
|
-
if (typeof value !== 'string' || !value) continue;
|
|
91
|
-
// 12306 doubles up some prices as bare numerics ("9": "21580"), which
|
|
92
|
-
// mirror their letter sibling ("A9": "¥2158.0") in cents/no-decimal
|
|
93
|
-
// form. Skip the bare numeric letter codes to avoid duplicates.
|
|
94
|
-
if (/^\d+$/.test(letter)) continue;
|
|
95
|
-
if (!/^[A-Z]/.test(letter)) continue;
|
|
96
|
-
const numeric = value.replace(/^¥/, '');
|
|
97
|
-
if (!/^[\d.]+$/.test(numeric)) continue;
|
|
98
|
-
rows.push({
|
|
99
|
-
seat_code: letter,
|
|
100
|
-
seat_name: SEAT_LETTERS[letter] || letter,
|
|
101
|
-
price: numeric,
|
|
102
|
-
currency: 'CNY',
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
rows.sort((a, b) => Number(b.price) - Number(a.price));
|
|
106
|
-
return rows;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
cli({
|
|
110
|
-
site: '12306',
|
|
111
|
-
name: 'price',
|
|
112
|
-
access: 'read',
|
|
113
|
-
description: 'Look up 12306 ticket prices by seat class for one train on a given date and segment (anonymous, no login required)',
|
|
114
|
-
domain: 'kyfw.12306.cn',
|
|
115
|
-
strategy: Strategy.PUBLIC,
|
|
116
|
-
browser: false,
|
|
117
|
-
args: [
|
|
118
|
-
{ name: 'train-no', positional: true, required: true, help: 'Internal train_no from `12306 trains` (e.g. 24000000G10L)' },
|
|
119
|
-
{ name: 'from', required: true, help: 'Origin station (Chinese name, telecode, or pinyin) - must be a stop of this train' },
|
|
120
|
-
{ name: 'to', required: true, help: 'Destination station - must be a stop of this train' },
|
|
121
|
-
{ name: 'date', required: true, help: 'Departure date in YYYY-MM-DD' },
|
|
122
|
-
{ name: 'seat-types', default: 'OM9PA1A3A4FWZ', help: 'Seat-type letters to query (default covers the common classes). Examples: OM9 (二等/一等/商务), A1A3A4 (硬座/硬卧/软卧).' },
|
|
123
|
-
],
|
|
124
|
-
columns: ['seat_code', 'seat_name', 'price', 'currency'],
|
|
125
|
-
func: async (kwargs) => {
|
|
126
|
-
const trainNo = String(kwargs['train-no'] ?? '').trim();
|
|
127
|
-
if (!trainNo) throw new ArgumentError('<train-no> must not be empty');
|
|
128
|
-
if (!TRAIN_NO_RE.test(trainNo)) {
|
|
129
|
-
throw new ArgumentError(
|
|
130
|
-
`<train-no> "${trainNo}" does not look like a 12306 internal train_no`,
|
|
131
|
-
'Use the train_no field from `12306 trains` output (e.g. 24000000G10L), not the public code (G1).',
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
const fromArg = String(kwargs.from ?? '').trim();
|
|
135
|
-
const toArg = String(kwargs.to ?? '').trim();
|
|
136
|
-
if (!fromArg) throw new ArgumentError('--from station must not be empty');
|
|
137
|
-
if (!toArg) throw new ArgumentError('--to station must not be empty');
|
|
138
|
-
const date = validateDate(kwargs.date);
|
|
139
|
-
const seatTypes = String(kwargs['seat-types'] ?? '').trim() || 'OM9PA1A3A4FWZ';
|
|
140
|
-
if (!SEAT_TYPES_RE.test(seatTypes)) {
|
|
141
|
-
throw new ArgumentError('--seat-types must contain only 12306 seat letters/digits (A-Z, 0-9)');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const stations = await fetchStationBundle();
|
|
145
|
-
const fromStation = resolveStation(stations, fromArg);
|
|
146
|
-
const toStation = resolveStation(stations, toArg);
|
|
147
|
-
if (fromStation.code === toStation.code) {
|
|
148
|
-
throw new ArgumentError(`--from and --to must differ; both resolved to ${fromStation.name} (${fromStation.code})`);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const cookieHeader = await mintSession();
|
|
152
|
-
const stops = await queryStopsForPrice(cookieHeader, trainNo, fromStation.code, toStation.code, date);
|
|
153
|
-
const { fromNo, toNo } = pickStationNos(stops, fromStation.code, toStation.code, fromStation.name, toStation.name);
|
|
154
|
-
const priceData = await queryPrice(cookieHeader, trainNo, fromNo, toNo, seatTypes, date);
|
|
155
|
-
const rows = parsePriceData(priceData);
|
|
156
|
-
if (rows.length === 0) {
|
|
157
|
-
throw new EmptyResultError(
|
|
158
|
-
`No prices returned for train_no=${trainNo} ${fromStation.name} -> ${toStation.name} on ${date}`,
|
|
159
|
-
'Try a different seat-types letter set, or check that this train operates on the date.',
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
return rows;
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
export const __test__ = { parsePriceData, pickStationNos, queryStopsForPrice, queryPrice, SEAT_LETTERS, TRAIN_NO_RE };
|
package/clis/12306/stations.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 12306 station search.
|
|
3
|
-
*
|
|
4
|
-
* Queries the public `station_name.js` bundle and filters by the user's
|
|
5
|
-
* keyword. Anonymous, no session needed.
|
|
6
|
-
*/
|
|
7
|
-
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
8
|
-
import { ArgumentError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
9
|
-
import { fetchStationBundle } from './utils.js';
|
|
10
|
-
|
|
11
|
-
const MAX_LIMIT = 50;
|
|
12
|
-
|
|
13
|
-
function normalizeLimit(value, defaultValue, max) {
|
|
14
|
-
if (value === undefined || value === null || value === '') return defaultValue;
|
|
15
|
-
const n = Number(value);
|
|
16
|
-
if (!Number.isInteger(n) || n < 1) {
|
|
17
|
-
throw new ArgumentError(`limit must be a positive integer (1-${max})`);
|
|
18
|
-
}
|
|
19
|
-
if (n > max) {
|
|
20
|
-
throw new ArgumentError(`limit must be <= ${max}`);
|
|
21
|
-
}
|
|
22
|
-
return n;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
cli({
|
|
26
|
-
site: '12306',
|
|
27
|
-
name: 'stations',
|
|
28
|
-
access: 'read',
|
|
29
|
-
description: 'Search 12306 (China Railway) stations by Chinese name, telecode, or pinyin keyword',
|
|
30
|
-
domain: 'kyfw.12306.cn',
|
|
31
|
-
strategy: Strategy.PUBLIC,
|
|
32
|
-
browser: false,
|
|
33
|
-
args: [
|
|
34
|
-
{ name: 'keyword', positional: true, required: true, help: 'Chinese substring (上海), telecode (AOH), or pinyin (shanghai)' },
|
|
35
|
-
{ name: 'limit', type: 'int', default: 20, help: `Maximum results (1-${MAX_LIMIT})` },
|
|
36
|
-
],
|
|
37
|
-
columns: ['name', 'code', 'pinyin', 'abbr', 'city'],
|
|
38
|
-
func: async (kwargs) => {
|
|
39
|
-
const keyword = String(kwargs.keyword ?? '').trim();
|
|
40
|
-
if (!keyword) throw new ArgumentError('keyword must not be empty');
|
|
41
|
-
const limit = normalizeLimit(kwargs.limit, 20, MAX_LIMIT);
|
|
42
|
-
|
|
43
|
-
const stations = await fetchStationBundle();
|
|
44
|
-
const lower = keyword.toLowerCase();
|
|
45
|
-
const matches = stations.filter((s) =>
|
|
46
|
-
s.name.includes(keyword)
|
|
47
|
-
|| s.code === keyword.toUpperCase()
|
|
48
|
-
|| s.pinyin.includes(lower)
|
|
49
|
-
|| s.abbr.includes(lower)
|
|
50
|
-
|| s.short.includes(lower)
|
|
51
|
-
|| s.city.includes(keyword),
|
|
52
|
-
);
|
|
53
|
-
if (matches.length === 0) {
|
|
54
|
-
throw new EmptyResultError(`No 12306 stations match "${keyword}"`);
|
|
55
|
-
}
|
|
56
|
-
return matches.slice(0, limit).map((s) => ({
|
|
57
|
-
name: s.name,
|
|
58
|
-
code: s.code,
|
|
59
|
-
pinyin: s.pinyin,
|
|
60
|
-
abbr: s.abbr,
|
|
61
|
-
city: s.city,
|
|
62
|
-
}));
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
export const __test__ = { normalizeLimit };
|
package/clis/12306/train.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 12306 train stop details - list every station a train calls at,
|
|
3
|
-
* with arrival / departure / stopover time.
|
|
4
|
-
*
|
|
5
|
-
* Requires the internal `train_no` returned by `12306 trains`
|
|
6
|
-
* (`24000000G10L`), not the public train code (`G1`).
|
|
7
|
-
*/
|
|
8
|
-
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
9
|
-
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
10
|
-
import { fetchStationBundle, mintSession, resolveStation, validateDate } from './utils.js';
|
|
11
|
-
|
|
12
|
-
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36';
|
|
13
|
-
const TRAIN_NO_RE = /^[0-9A-Za-z]{8,18}$/;
|
|
14
|
-
|
|
15
|
-
async function queryStops(cookieHeader, trainNo, fromCode, toCode, date, fetchImpl = fetch) {
|
|
16
|
-
const url = `https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=${trainNo}&from_station_telecode=${fromCode}&to_station_telecode=${toCode}&depart_date=${date}`;
|
|
17
|
-
const resp = await fetchImpl(url, {
|
|
18
|
-
headers: {
|
|
19
|
-
'User-Agent': UA,
|
|
20
|
-
'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init',
|
|
21
|
-
'Cookie': cookieHeader,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
if (!resp.ok) {
|
|
25
|
-
throw new CommandExecutionError(`12306 queryByTrainNo returned HTTP ${resp.status}`);
|
|
26
|
-
}
|
|
27
|
-
let json;
|
|
28
|
-
try {
|
|
29
|
-
json = await resp.json();
|
|
30
|
-
} catch {
|
|
31
|
-
throw new CommandExecutionError('12306 queryByTrainNo returned non-JSON body');
|
|
32
|
-
}
|
|
33
|
-
if (json?.status !== true || !Array.isArray(json?.data?.data)) {
|
|
34
|
-
throw new CommandExecutionError(`12306 queryByTrainNo returned an unexpected payload shape`);
|
|
35
|
-
}
|
|
36
|
-
return json.data.data;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
cli({
|
|
40
|
-
site: '12306',
|
|
41
|
-
name: 'train',
|
|
42
|
-
access: 'read',
|
|
43
|
-
description: 'List every station a 12306 train calls at, with arrival / departure / stopover time (anonymous, no login required)',
|
|
44
|
-
domain: 'kyfw.12306.cn',
|
|
45
|
-
strategy: Strategy.PUBLIC,
|
|
46
|
-
browser: false,
|
|
47
|
-
args: [
|
|
48
|
-
{ name: 'train-no', positional: true, required: true, help: 'Internal train_no from `12306 trains` (e.g. 24000000G10L), not the public code (G1)' },
|
|
49
|
-
{ name: 'from', required: true, help: 'Origin station for the segment: Chinese name, telecode, or pinyin' },
|
|
50
|
-
{ name: 'to', required: true, help: 'Destination station for the segment' },
|
|
51
|
-
{ name: 'date', required: true, help: 'Departure date in YYYY-MM-DD' },
|
|
52
|
-
],
|
|
53
|
-
columns: ['station_no', 'station_name', 'arrive_time', 'start_time', 'stopover_time'],
|
|
54
|
-
func: async (kwargs) => {
|
|
55
|
-
const trainNo = String(kwargs['train-no'] ?? '').trim();
|
|
56
|
-
if (!trainNo) throw new ArgumentError('<train-no> must not be empty');
|
|
57
|
-
if (!TRAIN_NO_RE.test(trainNo)) {
|
|
58
|
-
throw new ArgumentError(
|
|
59
|
-
`<train-no> "${trainNo}" does not look like a 12306 internal train_no`,
|
|
60
|
-
'Use the train_no field from `12306 trains` output (e.g. 24000000G10L), not the public code (G1).',
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
const fromArg = String(kwargs.from ?? '').trim();
|
|
64
|
-
const toArg = String(kwargs.to ?? '').trim();
|
|
65
|
-
if (!fromArg) throw new ArgumentError('--from station must not be empty');
|
|
66
|
-
if (!toArg) throw new ArgumentError('--to station must not be empty');
|
|
67
|
-
const date = validateDate(kwargs.date);
|
|
68
|
-
|
|
69
|
-
const stations = await fetchStationBundle();
|
|
70
|
-
const fromStation = resolveStation(stations, fromArg);
|
|
71
|
-
const toStation = resolveStation(stations, toArg);
|
|
72
|
-
if (fromStation.code === toStation.code) {
|
|
73
|
-
throw new ArgumentError(`--from and --to must differ; both resolved to ${fromStation.name} (${fromStation.code})`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const cookieHeader = await mintSession();
|
|
77
|
-
const stops = await queryStops(cookieHeader, trainNo, fromStation.code, toStation.code, date);
|
|
78
|
-
if (stops.length === 0) {
|
|
79
|
-
throw new EmptyResultError(`No stops returned for train_no=${trainNo} on ${date}`);
|
|
80
|
-
}
|
|
81
|
-
return stops.map((s) => ({
|
|
82
|
-
station_no: s.station_no || '',
|
|
83
|
-
station_name: s.station_name || '',
|
|
84
|
-
arrive_time: s.arrive_time === '----' ? '' : (s.arrive_time || ''),
|
|
85
|
-
start_time: s.start_time === '----' ? '' : (s.start_time || ''),
|
|
86
|
-
stopover_time: s.stopover_time === '----' ? '' : (s.stopover_time || ''),
|
|
87
|
-
}));
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
export const __test__ = { queryStops, TRAIN_NO_RE };
|
package/clis/12306/trains.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 12306 train availability between two stations on a given date.
|
|
3
|
-
*
|
|
4
|
-
* Flow:
|
|
5
|
-
* 1. Fetch the station bundle (cached implicitly via per-process module state).
|
|
6
|
-
* 2. Mint anonymous session cookies via /otn/leftTicket/init.
|
|
7
|
-
* 3. Query /otn/leftTicket/queryG; if 12306 returns
|
|
8
|
-
* `{c_url: "leftTicket/queryX"}` (endpoint rotation), retry once
|
|
9
|
-
* against the suggested name.
|
|
10
|
-
* 4. Parse the `|`-separated train records.
|
|
11
|
-
*/
|
|
12
|
-
import { cli, Strategy } from '@agentrhq/webcmd/registry';
|
|
13
|
-
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
14
|
-
import { fetchStationBundle, mintSession, resolveStation, validateDate, parseTrainRecord } from './utils.js';
|
|
15
|
-
|
|
16
|
-
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36';
|
|
17
|
-
const QUERY_ENDPOINTS = ['queryG', 'queryO', 'queryZ', 'queryA'];
|
|
18
|
-
const MAX_LIMIT = 100;
|
|
19
|
-
const QUERY_ENDPOINT_RE = /^query[A-Z]$/;
|
|
20
|
-
|
|
21
|
-
function normalizeLimit(value, defaultValue, max) {
|
|
22
|
-
if (value === undefined || value === null || value === '') return defaultValue;
|
|
23
|
-
const n = Number(value);
|
|
24
|
-
if (!Number.isInteger(n) || n < 1) {
|
|
25
|
-
throw new ArgumentError(`limit must be a positive integer (1-${max})`);
|
|
26
|
-
}
|
|
27
|
-
if (n > max) {
|
|
28
|
-
throw new ArgumentError(`limit must be <= ${max}`);
|
|
29
|
-
}
|
|
30
|
-
return n;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function extractQueryEndpoint(value) {
|
|
34
|
-
const raw = String(value ?? '').trim();
|
|
35
|
-
if (!raw) return '';
|
|
36
|
-
const direct = raw.replace(/^leftTicket\//, '').trim();
|
|
37
|
-
if (QUERY_ENDPOINT_RE.test(direct)) return direct;
|
|
38
|
-
try {
|
|
39
|
-
const url = new URL(raw, 'https://kyfw.12306.cn');
|
|
40
|
-
if (url.hostname !== 'kyfw.12306.cn') return '';
|
|
41
|
-
const match = url.pathname.match(/\/leftTicket\/(query[A-Z])$/);
|
|
42
|
-
return match ? match[1] : '';
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return '';
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function parseRotationEndpoint(resp, endpoint, bodyText) {
|
|
50
|
-
let json;
|
|
51
|
-
if (bodyText) {
|
|
52
|
-
try { json = JSON.parse(bodyText); } catch { /* body may be HTML on non-rotation redirects */ }
|
|
53
|
-
}
|
|
54
|
-
const bodyEndpoint = extractQueryEndpoint(json?.c_url);
|
|
55
|
-
if (bodyEndpoint) return bodyEndpoint;
|
|
56
|
-
const locationEndpoint = extractQueryEndpoint(resp.headers?.get?.('location'));
|
|
57
|
-
if (locationEndpoint) return locationEndpoint;
|
|
58
|
-
if (resp.status === 302) {
|
|
59
|
-
throw new CommandExecutionError(`12306 ${endpoint} redirected without a leftTicket query endpoint`);
|
|
60
|
-
}
|
|
61
|
-
if (json?.c_url) {
|
|
62
|
-
throw new CommandExecutionError(`12306 ${endpoint} returned an invalid rotation endpoint`);
|
|
63
|
-
}
|
|
64
|
-
return '';
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function queryLeftTickets(cookieHeader, fromCode, toCode, date) {
|
|
68
|
-
const headers = {
|
|
69
|
-
'User-Agent': UA,
|
|
70
|
-
'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init',
|
|
71
|
-
'Cookie': cookieHeader,
|
|
72
|
-
};
|
|
73
|
-
const queryParams = `leftTicketDTO.train_date=${date}&leftTicketDTO.from_station=${fromCode}&leftTicketDTO.to_station=${toCode}&purpose_codes=ADULT`;
|
|
74
|
-
let lastResponseText = '';
|
|
75
|
-
const queue = [...QUERY_ENDPOINTS];
|
|
76
|
-
const tried = new Set();
|
|
77
|
-
while (queue.length > 0) {
|
|
78
|
-
const endpoint = queue.shift();
|
|
79
|
-
if (tried.has(endpoint)) continue;
|
|
80
|
-
tried.add(endpoint);
|
|
81
|
-
const url = `https://kyfw.12306.cn/otn/leftTicket/${endpoint}?${queryParams}`;
|
|
82
|
-
const resp = await fetch(url, { headers, redirect: 'manual' });
|
|
83
|
-
if (!resp.ok) {
|
|
84
|
-
if (resp.status === 302) {
|
|
85
|
-
const body = await resp.text();
|
|
86
|
-
const rotated = await parseRotationEndpoint(resp, endpoint, body);
|
|
87
|
-
if (rotated && !tried.has(rotated)) {
|
|
88
|
-
queue.unshift(rotated);
|
|
89
|
-
}
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
throw new CommandExecutionError(`12306 ${endpoint} returned HTTP ${resp.status}`);
|
|
93
|
-
}
|
|
94
|
-
const text = await resp.text();
|
|
95
|
-
lastResponseText = text;
|
|
96
|
-
let json;
|
|
97
|
-
try { json = JSON.parse(text); } catch {
|
|
98
|
-
throw new CommandExecutionError(`12306 ${endpoint} returned non-JSON body`);
|
|
99
|
-
}
|
|
100
|
-
if (json?.c_url && typeof json.c_url === 'string') {
|
|
101
|
-
const rotated = await parseRotationEndpoint(resp, endpoint, text);
|
|
102
|
-
if (rotated && !tried.has(rotated)) {
|
|
103
|
-
queue.unshift(rotated);
|
|
104
|
-
}
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
if (Array.isArray(json?.data?.result)) {
|
|
108
|
-
return json.data.result;
|
|
109
|
-
}
|
|
110
|
-
throw new CommandExecutionError(`12306 ${endpoint} returned an unexpected payload shape`);
|
|
111
|
-
}
|
|
112
|
-
throw new CommandExecutionError(`12306 rejected every known query endpoint name (${QUERY_ENDPOINTS.join(', ')}); the wire protocol may have changed. Last body: ${lastResponseText.slice(0, 200)}`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
cli({
|
|
116
|
-
site: '12306',
|
|
117
|
-
name: 'trains',
|
|
118
|
-
access: 'read',
|
|
119
|
-
description: 'List trains between two 12306 stations on a given date (anonymous, no login required)',
|
|
120
|
-
domain: 'kyfw.12306.cn',
|
|
121
|
-
strategy: Strategy.PUBLIC,
|
|
122
|
-
browser: false,
|
|
123
|
-
args: [
|
|
124
|
-
{ name: 'from', positional: true, required: true, help: 'Origin station: Chinese name (北京), telecode (BJP), or pinyin (beijing)' },
|
|
125
|
-
{ name: 'to', positional: true, required: true, help: 'Destination station: same forms as <from>' },
|
|
126
|
-
{ name: 'date', required: true, help: 'Departure date in YYYY-MM-DD' },
|
|
127
|
-
{ name: 'limit', type: 'int', default: 50, help: `Maximum rows (1-${MAX_LIMIT})` },
|
|
128
|
-
],
|
|
129
|
-
columns: [
|
|
130
|
-
'code', 'from_station', 'to_station', 'start_time', 'arrive_time',
|
|
131
|
-
'duration', 'available', 'business_seat', 'first_seat', 'second_seat',
|
|
132
|
-
'soft_sleeper', 'hard_sleeper', 'hard_seat', 'no_seat', 'train_no',
|
|
133
|
-
],
|
|
134
|
-
func: async (kwargs) => {
|
|
135
|
-
const fromArg = String(kwargs.from ?? '').trim();
|
|
136
|
-
const toArg = String(kwargs.to ?? '').trim();
|
|
137
|
-
if (!fromArg) throw new ArgumentError('<from> station must not be empty');
|
|
138
|
-
if (!toArg) throw new ArgumentError('<to> station must not be empty');
|
|
139
|
-
const date = validateDate(kwargs.date);
|
|
140
|
-
const limit = normalizeLimit(kwargs.limit, 50, MAX_LIMIT);
|
|
141
|
-
|
|
142
|
-
const stations = await fetchStationBundle();
|
|
143
|
-
const fromStation = resolveStation(stations, fromArg);
|
|
144
|
-
const toStation = resolveStation(stations, toArg);
|
|
145
|
-
if (fromStation.code === toStation.code) {
|
|
146
|
-
throw new ArgumentError(`<from> and <to> must differ; both resolved to ${fromStation.name} (${fromStation.code})`);
|
|
147
|
-
}
|
|
148
|
-
const stationByCode = new Map(stations.map((s) => [s.code, s]));
|
|
149
|
-
|
|
150
|
-
const cookieHeader = await mintSession();
|
|
151
|
-
const rawRows = await queryLeftTickets(cookieHeader, fromStation.code, toStation.code, date);
|
|
152
|
-
const decoded = rawRows
|
|
153
|
-
.map((line) => parseTrainRecord(decodeURIComponent(line.replace(/%0A/g, '')), stationByCode))
|
|
154
|
-
.filter(Boolean);
|
|
155
|
-
|
|
156
|
-
if (decoded.length === 0) {
|
|
157
|
-
throw new EmptyResultError(
|
|
158
|
-
`No trains found from ${fromStation.name} to ${toStation.name} on ${date}`,
|
|
159
|
-
'Try a different date or check whether the route is operated by 12306.',
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
return decoded.slice(0, limit);
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
export const __test__ = { normalizeLimit, extractQueryEndpoint, queryLeftTickets };
|