@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
|
@@ -45,7 +45,7 @@ describe('twitter list-tweets parser', () => {
|
|
|
45
45
|
const tweet = extractTimelineTweet({
|
|
46
46
|
rest_id: '500',
|
|
47
47
|
legacy: {
|
|
48
|
-
full_text: '
|
|
48
|
+
full_text: 'Overall,family background still matters',
|
|
49
49
|
is_quote_status: true,
|
|
50
50
|
quoted_status_id_str: '499',
|
|
51
51
|
},
|
|
@@ -54,7 +54,7 @@ describe('twitter list-tweets parser', () => {
|
|
|
54
54
|
result: {
|
|
55
55
|
rest_id: '499',
|
|
56
56
|
legacy: {
|
|
57
|
-
full_text: '
|
|
57
|
+
full_text: 'official family background review',
|
|
58
58
|
created_at: 'Wed May 13 22:00:00 +0000 2026',
|
|
59
59
|
extended_entities: {
|
|
60
60
|
media: [{ type: 'photo', media_url_https: 'https://pbs.twimg.com/media/x.jpg' }],
|
|
@@ -68,7 +68,7 @@ describe('twitter list-tweets parser', () => {
|
|
|
68
68
|
id: '499',
|
|
69
69
|
author: 'alice',
|
|
70
70
|
name: 'Alice',
|
|
71
|
-
text: '
|
|
71
|
+
text: 'official family background review',
|
|
72
72
|
created_at: 'Wed May 13 22:00:00 +0000 2026',
|
|
73
73
|
url: 'https://x.com/alice/status/499',
|
|
74
74
|
has_media: true,
|
package/clis/twitter/lists.js
CHANGED
|
@@ -63,12 +63,12 @@ export function extractListEntry(entry, seen) {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
// X
|
|
67
|
-
//
|
|
68
|
-
// - `owned-subscribed-list-module-*` →
|
|
69
|
-
// - `list-to-follow-module-*` → "Discover new Lists"
|
|
70
|
-
// - `cursor-*` →
|
|
71
|
-
//
|
|
66
|
+
// X localized text ListsManagementPageTimeline put /<user>/lists all page section
|
|
67
|
+
// into one TimelineAddEntries instruction localized text,by entry.entryId prefix distinction:
|
|
68
|
+
// - `owned-subscribed-list-module-*` → user owned + subscribed list(should keep)
|
|
69
|
+
// - `list-to-follow-module-*` → "Discover new Lists" algorithmic recommendations(should remove)
|
|
70
|
+
// - `cursor-*` → pagination cursor(none list data)
|
|
71
|
+
// legacy parser ignore entryId always drill down,caused recommendations list treated as user-created/subscriptions leaked.
|
|
72
72
|
const OWNED_SUBSCRIBED_ENTRY_PREFIX = 'owned-subscribed-list-module-';
|
|
73
73
|
|
|
74
74
|
export function isOwnedSubscribedEntry(entry) {
|
|
@@ -109,8 +109,8 @@ describe('twitter lists parser', () => {
|
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
it('skips "Discover new Lists" recommendations (list-to-follow-module-*)', () => {
|
|
112
|
-
//
|
|
113
|
-
//
|
|
112
|
+
// real X.com /<user>/lists response:Discover recommendation + Your Lists same instruction,
|
|
113
|
+
// differs only by entry.entryId prefix.Parser must filter recommendations by prefix.
|
|
114
114
|
const payload = {
|
|
115
115
|
data: {
|
|
116
116
|
viewer: {
|
package/clis/twitter/reply-dm.js
CHANGED
|
@@ -9,7 +9,7 @@ cli({
|
|
|
9
9
|
strategy: Strategy.UI,
|
|
10
10
|
browser: true,
|
|
11
11
|
args: [
|
|
12
|
-
{ name: 'text', type: 'string', required: true, positional: true, help: 'Message text to send (e.g. "
|
|
12
|
+
{ name: 'text', type: 'string', required: true, positional: true, help: 'Message text to send (e.g. "my messaging handle wxkabi")' },
|
|
13
13
|
{ name: 'max', type: 'int', required: false, default: 20, help: 'Maximum number of conversations to reply to (default: 20)' },
|
|
14
14
|
{ name: 'skip-replied', type: 'boolean', required: false, default: true, help: 'Skip conversations where you already sent the same text (default: true)' },
|
|
15
15
|
{ name: 'timeout', type: 'int', required: false, default: 600, help: 'Max seconds for the overall command (default: 600 — batch op)' },
|
|
@@ -275,8 +275,7 @@ describe('twitter parseTweetUrl', () => {
|
|
|
275
275
|
describe('twitter buildTwitterArticleScopeSource', () => {
|
|
276
276
|
// JSDOM-based tests prove the returned source actually works on real DOM —
|
|
277
277
|
// mocked `evaluate` tests in adapter specs only verify the script string
|
|
278
|
-
// contains expected tokens, but cannot catch silent matching bugs
|
|
279
|
-
// dianping #1312: mocked-evaluate single tests miss in-browser logic bugs).
|
|
278
|
+
// contains expected tokens, but cannot catch silent in-browser matching bugs.
|
|
280
279
|
function loadHelpers(tweetId, dom) {
|
|
281
280
|
const source = buildTwitterArticleScopeSource(tweetId);
|
|
282
281
|
const probe = new Function(
|
|
@@ -742,7 +741,7 @@ describe('twitter extractQuotedTweet', () => {
|
|
|
742
741
|
result: {
|
|
743
742
|
rest_id: '2040254679301718161',
|
|
744
743
|
legacy: {
|
|
745
|
-
full_text: '
|
|
744
|
+
full_text: 'official family background review',
|
|
746
745
|
created_at: 'Wed May 13 22:00:00 +0000 2026',
|
|
747
746
|
},
|
|
748
747
|
core: {
|
|
@@ -757,7 +756,7 @@ describe('twitter extractQuotedTweet', () => {
|
|
|
757
756
|
id: '2040254679301718161',
|
|
758
757
|
author: 'alice',
|
|
759
758
|
name: 'Alice',
|
|
760
|
-
text: '
|
|
759
|
+
text: 'official family background review',
|
|
761
760
|
created_at: 'Wed May 13 22:00:00 +0000 2026',
|
|
762
761
|
url: 'https://x.com/alice/status/2040254679301718161',
|
|
763
762
|
has_media: false,
|
|
@@ -773,7 +772,7 @@ describe('twitter extractQuotedTweet', () => {
|
|
|
773
772
|
result: {
|
|
774
773
|
rest_id: '99',
|
|
775
774
|
legacy: {
|
|
776
|
-
full_text: '
|
|
775
|
+
full_text: 'Japanese train record',
|
|
777
776
|
extended_entities: {
|
|
778
777
|
media: [
|
|
779
778
|
{ type: 'photo', media_url_https: 'https://pbs.twimg.com/media/a.jpg' },
|
package/clis/twitter/trending.js
CHANGED
|
@@ -4,7 +4,7 @@ import { AuthRequiredError, EmptyResultError } from '@agentrhq/webcmd/errors';
|
|
|
4
4
|
//
|
|
5
5
|
// X (Twitter) removed the post-count caption from each trend cell on the
|
|
6
6
|
// /explore/tabs/trending page in 2024-2025. The DOM now only carries:
|
|
7
|
-
// divs[0] = rank + category (e.g. "1
|
|
7
|
+
// divs[0] = rank + category (e.g. "1 \u00b7 Trending in United States")
|
|
8
8
|
// divs[1] = topic
|
|
9
9
|
// divs[2..] = caret menu button (no post-count text)
|
|
10
10
|
// We previously surfaced a `tweets` column whose value was permanently
|
package/clis/twitter/utils.js
CHANGED
|
@@ -216,7 +216,7 @@ export async function waitForComposerMediaReady(page, expectedCount = 1) {
|
|
|
216
216
|
).length;
|
|
217
217
|
const blobCount = document.querySelectorAll('img[src^="blob:"], video[src^="blob:"]').length;
|
|
218
218
|
const removeButtonCount = Array.from(document.querySelectorAll('button,[role="button"]')).filter((el) =>
|
|
219
|
-
/remove media|remove image|remove
|
|
219
|
+
/remove media|remove image|remove|localized text/i.test((el.getAttribute('aria-label') || '') + ' ' + (el.textContent || ''))
|
|
220
220
|
).length;
|
|
221
221
|
const explicitPreviewCount = Math.max(
|
|
222
222
|
previewCount,
|
package/clis/web/read.js
CHANGED
|
@@ -223,7 +223,7 @@ function buildRenderAwareExtractorJs(options) {
|
|
|
223
223
|
const section = document.createElement('section');
|
|
224
224
|
section.setAttribute('data-webcmd-iframe-source', desc.src);
|
|
225
225
|
const heading = document.createElement('h2');
|
|
226
|
-
heading.textContent = '
|
|
226
|
+
heading.textContent = 'localized text iframe: ' + (desc.src || fallbackLabel);
|
|
227
227
|
section.appendChild(heading);
|
|
228
228
|
Array.from(frameBody.childNodes).forEach(node => section.appendChild(node));
|
|
229
229
|
return section;
|
package/clis/web/read.test.js
CHANGED
|
@@ -236,7 +236,7 @@ describe('web/read render-aware helpers', () => {
|
|
|
236
236
|
|
|
237
237
|
expect(result.diagnostics.includedFrameCount).toBe(1);
|
|
238
238
|
expect(result.contentHtml).toContain('data-webcmd-iframe-source="https://example.com/frame.html"');
|
|
239
|
-
expect(result.contentHtml).toContain('
|
|
239
|
+
expect(result.contentHtml).toContain('localized text iframe: https://example.com/frame.html');
|
|
240
240
|
expect(result.contentHtml).toContain('Station A 42');
|
|
241
241
|
expect(result.diagnostics.emptyContainers).toEqual(expect.arrayContaining([
|
|
242
242
|
expect.objectContaining({ scope: 'iframe', id: 'gridDatas', url: 'https://example.com/frame.html' }),
|
|
@@ -277,7 +277,7 @@ describe('web/read render-aware helpers', () => {
|
|
|
277
277
|
`, { url: 'https://example.com/main.html', runScripts: 'outside-only' });
|
|
278
278
|
const frame = dom.window.document.querySelector('iframe');
|
|
279
279
|
frame.contentDocument.open();
|
|
280
|
-
frame.contentDocument.write('<body><table id="gridHd"><tr><th
|
|
280
|
+
frame.contentDocument.write('<body><table id="gridHd"><tr><th>water level</th></tr><tr><td>42</td></tr></table><ul id="gridDatas"></ul></body>');
|
|
281
281
|
frame.contentDocument.close();
|
|
282
282
|
|
|
283
283
|
const result = dom.window.eval(__test__.buildRenderAwareExtractorJs({ frames: 'same-origin' }));
|
package/clis/youtube/history.js
CHANGED
|
@@ -55,7 +55,7 @@ cli({
|
|
|
55
55
|
|| text(link);
|
|
56
56
|
const channel =
|
|
57
57
|
text(renderer.querySelector('#channel-name a'))
|
|
58
|
-
|| text(renderer.querySelector('[aria-label^="
|
|
58
|
+
|| text(renderer.querySelector('[aria-label^="Go to channel:"]'))
|
|
59
59
|
|| text(renderer.querySelector('[aria-label^="Go to channel:"]'))
|
|
60
60
|
|| text(renderer.querySelector('ytd-channel-name'))
|
|
61
61
|
|| text(renderer.querySelector('#metadata #byline-container'))
|
|
@@ -68,8 +68,8 @@ cli({
|
|
|
68
68
|
.filter(Boolean);
|
|
69
69
|
const combinedMetadata = (metadata.length ? metadata : lockupMetadata)
|
|
70
70
|
.filter(value => value && value !== title && value !== '•');
|
|
71
|
-
const inferredChannel = channel || combinedMetadata.find(value =>
|
|
72
|
-
const inferredViews = combinedMetadata.find(value =>
|
|
71
|
+
const inferredChannel = channel || combinedMetadata.find(value => !/views|views|ago|agoに|ago|views|views|stream/i.test(value)) || '';
|
|
72
|
+
const inferredViews = combinedMetadata.find(value => /views|views/i.test(value)) || '';
|
|
73
73
|
const inferredPublished = combinedMetadata.find(value => value !== inferredChannel && value !== inferredViews) || '';
|
|
74
74
|
const duration =
|
|
75
75
|
text(renderer.querySelector('ytd-thumbnail-overlay-time-status-renderer'))
|
|
@@ -96,7 +96,7 @@ cli({
|
|
|
96
96
|
push({
|
|
97
97
|
title,
|
|
98
98
|
channel: 'Shorts',
|
|
99
|
-
views: stats.find(value =>
|
|
99
|
+
views: stats.find(value => /views|views/i.test(value)) || '',
|
|
100
100
|
duration: 'SHORT',
|
|
101
101
|
published: '',
|
|
102
102
|
url: href.startsWith('http') ? href : 'https://www.youtube.com' + href,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Speaker turns: detect ">>" markers from YouTube auto-captions
|
|
8
8
|
* - Chapters: optional chapter headings inserted at appropriate timestamps
|
|
9
9
|
*/
|
|
10
|
-
// Include CJK sentence-ending punctuation:
|
|
10
|
+
// Include CJK sentence-ending punctuation: .!? (fullwidth: .!?)
|
|
11
11
|
const SENTENCE_END = /[.!?\u3002\uFF01\uFF1F\uFF0E]["'\u2019\u201D)]*\s*$/;
|
|
12
12
|
const QUESTION_END = /[?\uFF1F]["'\u2019\u201D)]*\s*$/;
|
|
13
13
|
const TRANSCRIPT_GROUP_GAP_SECONDS = 20;
|
|
@@ -52,14 +52,14 @@ describe('groupTranscriptSegments', () => {
|
|
|
52
52
|
});
|
|
53
53
|
it('recognizes CJK sentence-ending punctuation', () => {
|
|
54
54
|
const segments = [
|
|
55
|
-
{ start: 0, text: '
|
|
56
|
-
{ start: 2, text: '
|
|
57
|
-
{ start: 4, text: '
|
|
55
|
+
{ start: 0, text: 'Hello world.' },
|
|
56
|
+
{ start: 2, text: 'This is a test' },
|
|
57
|
+
{ start: 4, text: 'content.' },
|
|
58
58
|
];
|
|
59
59
|
const result = groupTranscriptSegments(segments);
|
|
60
60
|
expect(result).toHaveLength(2);
|
|
61
|
-
expect(result[0].text).toBe('
|
|
62
|
-
expect(result[1].text).toBe('
|
|
61
|
+
expect(result[0].text).toBe('Hello world.');
|
|
62
|
+
expect(result[1].text).toBe('This is a test content.');
|
|
63
63
|
});
|
|
64
64
|
it('returns empty array for empty input', () => {
|
|
65
65
|
expect(groupTranscriptSegments([])).toEqual([]);
|
|
@@ -444,11 +444,11 @@ cli({
|
|
|
444
444
|
}
|
|
445
445
|
if (captionData?.error) {
|
|
446
446
|
const msg = `${captionData.error}${captionData.available ? ' (available: ' + captionData.available.join(', ') + ')' : ''}`;
|
|
447
|
-
// "No captions available"
|
|
448
|
-
//
|
|
449
|
-
//
|
|
447
|
+
// "No captions available" is a valid empty data condition(creator disabled captions + YT no auto captions),
|
|
448
|
+
// Localized "no captions" text follows the same empty-result pattern; downstream should treat code EMPTY_RESULT as skip.
|
|
449
|
+
// retry and softFail count.other error(HTTP / parse / temporary empty response)still treat as fetch failure.
|
|
450
450
|
if (captionData.error === 'No captions available for this video') {
|
|
451
|
-
throw new EmptyResultError('youtube transcript', '
|
|
451
|
+
throw new EmptyResultError('youtube transcript', 'This video has no captions(creator disabled captions + no automatic captions).');
|
|
452
452
|
}
|
|
453
453
|
throw new CommandExecutionError(msg);
|
|
454
454
|
}
|
|
@@ -640,7 +640,7 @@ cli({
|
|
|
640
640
|
}
|
|
641
641
|
// Step 4: Format output based on mode
|
|
642
642
|
if (mode === 'raw') {
|
|
643
|
-
// Precise timestamps in seconds with decimals, matching
|
|
643
|
+
// Precise timestamps in seconds with decimals, matching the subtitle segment format.
|
|
644
644
|
return segments.map((seg, i) => ({
|
|
645
645
|
index: i + 1,
|
|
646
646
|
start: Number(seg.start).toFixed(2) + 's',
|
package/clis/youtube/video.js
CHANGED
|
@@ -114,10 +114,10 @@ cli({
|
|
|
114
114
|
}
|
|
115
115
|
} catch {}
|
|
116
116
|
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
// BADGE_STYLE_TYPE_MEMBERS_ONLY
|
|
117
|
+
// playability gate signal:members-only(channel membership)/ paid video metadata as usual
|
|
118
|
+
// visible,but the video stream is unavailable——playabilityStatus.status != 'OK'.reason text is localized
|
|
119
|
+
// localized text(Chinese cookie is Chinese under this locale),so membersOnly localized text watch HTML localized text locale locale-independent
|
|
120
|
+
// BADGE_STYLE_TYPE_MEMBERS_ONLY badge enum detection,downstream should not parse reason.
|
|
121
121
|
const ps = player.playabilityStatus || {};
|
|
122
122
|
const membersOnly = html.indexOf('BADGE_STYLE_TYPE_MEMBERS_ONLY') !== -1;
|
|
123
123
|
|
|
@@ -21,8 +21,8 @@ const videoSource = readFileSync(resolve(__dirname, 'video.js'), 'utf8');
|
|
|
21
21
|
|
|
22
22
|
describe('youtube video source contract', () => {
|
|
23
23
|
it('extracts playability gate signals inside the watch bootstrap evaluate', () => {
|
|
24
|
-
//
|
|
25
|
-
// reason
|
|
24
|
+
// members-only video metadata localized text——playabilityStatus is the decision source;
|
|
25
|
+
// reason localized text,membersOnly must use locale locale-independent badge enum detection.
|
|
26
26
|
expect(videoSource).toContain('player.playabilityStatus');
|
|
27
27
|
expect(videoSource).toContain('BADGE_STYLE_TYPE_MEMBERS_ONLY');
|
|
28
28
|
});
|
|
@@ -39,8 +39,8 @@ describe('youtube video row mapping', () => {
|
|
|
39
39
|
|
|
40
40
|
it('surfaces playabilityStatus / playabilityReason / membersOnly as rows', async () => {
|
|
41
41
|
page.evaluate.mockResolvedValueOnce({
|
|
42
|
-
title: '
|
|
43
|
-
channel: '
|
|
42
|
+
title: 'KojiKoji Yang:How experts useAI?',
|
|
43
|
+
channel: 'Class Notes',
|
|
44
44
|
videoId: 'jgeqHyFzfIM',
|
|
45
45
|
playabilityStatus: 'UNPLAYABLE',
|
|
46
46
|
playabilityReason: "This video is available to this channel's members",
|
|
@@ -53,8 +53,8 @@ describe('youtube video row mapping', () => {
|
|
|
53
53
|
expect(byField.playabilityStatus).toBe('UNPLAYABLE');
|
|
54
54
|
expect(byField.membersOnly).toBe('true');
|
|
55
55
|
expect(byField.playabilityReason).toContain('members');
|
|
56
|
-
// metadata
|
|
57
|
-
expect(byField.title).toBe('
|
|
56
|
+
// metadata metadata rows still return(member video metadata remains visible)
|
|
57
|
+
expect(byField.title).toBe('KojiKoji Yang:How experts useAI?');
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it('reports OK playability for a normal video', async () => {
|
|
@@ -146,24 +146,24 @@ describe('scoreEndpointEvidence', () => {
|
|
|
146
146
|
describe('findNearestAdapter', () => {
|
|
147
147
|
it('matches by domain suffix', () => {
|
|
148
148
|
const reg = new Map([
|
|
149
|
-
['
|
|
150
|
-
['
|
|
151
|
-
['
|
|
149
|
+
['github search', mkCmd('github', 'search', 'github.com')],
|
|
150
|
+
['github auth', mkCmd('github', 'auth', 'github.com')],
|
|
151
|
+
['linkedin search', mkCmd('linkedin', 'search', 'linkedin.com')],
|
|
152
152
|
]);
|
|
153
|
-
const v = findNearestAdapter('https://
|
|
154
|
-
expect(v?.site).toBe('
|
|
155
|
-
expect(v?.example_commands).toContain('
|
|
153
|
+
const v = findNearestAdapter('https://docs.github.com/', reg);
|
|
154
|
+
expect(v?.site).toBe('github');
|
|
155
|
+
expect(v?.example_commands).toContain('github search');
|
|
156
156
|
});
|
|
157
157
|
it('falls back to site-name containment when no domain is registered', () => {
|
|
158
158
|
const reg = new Map([
|
|
159
|
-
['
|
|
159
|
+
['github search', mkCmd('github', 'search')],
|
|
160
160
|
]);
|
|
161
|
-
const v = findNearestAdapter('https://
|
|
162
|
-
expect(v?.site).toBe('
|
|
161
|
+
const v = findNearestAdapter('https://gist.github.com/', reg);
|
|
162
|
+
expect(v?.site).toBe('github');
|
|
163
163
|
});
|
|
164
164
|
it('returns null when no adapter matches', () => {
|
|
165
165
|
const reg = new Map([
|
|
166
|
-
['
|
|
166
|
+
['github search', mkCmd('github', 'search', 'github.com')],
|
|
167
167
|
]);
|
|
168
168
|
const v = findNearestAdapter('https://random-site.io/', reg);
|
|
169
169
|
expect(v).toBeNull();
|
|
@@ -201,9 +201,9 @@ describe('analyzeSite', () => {
|
|
|
201
201
|
});
|
|
202
202
|
it('includes nearest_adapter when the registry has a match', () => {
|
|
203
203
|
const reg = new Map([
|
|
204
|
-
['
|
|
204
|
+
['github search', mkCmd('github', 'search', 'github.com')],
|
|
205
205
|
]);
|
|
206
|
-
const report = analyzeSite(mkSignals({ finalUrl: 'https://
|
|
207
|
-
expect(report.nearest_adapter?.site).toBe('
|
|
206
|
+
const report = analyzeSite(mkSignals({ finalUrl: 'https://github.com/features/actions' }), reg);
|
|
207
|
+
expect(report.nearest_adapter?.site).toBe('github');
|
|
208
208
|
});
|
|
209
209
|
});
|
|
@@ -9,6 +9,6 @@ export declare function waitForBridgeReady(fetchHealth: HealthFetcher, opts: {
|
|
|
9
9
|
contextId?: string;
|
|
10
10
|
intervalMs?: number;
|
|
11
11
|
}): Promise<DaemonHealth>;
|
|
12
|
-
export declare const PRE_DISPATCH_ERROR_CODES: Set<"
|
|
12
|
+
export declare const PRE_DISPATCH_ERROR_CODES: Set<"profile_disconnected" | "extension_not_connected">;
|
|
13
13
|
export type PreDispatchErrorCode = typeof PRE_DISPATCH_ERROR_CODES extends Set<infer T> ? T : never;
|
|
14
14
|
export declare function isPreDispatchError(errorCode: string | undefined): boolean;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { fetchDaemonStatus, getDaemonHealth, requestDaemonShutdown, type BrowserProfileStatus, type DaemonHealth, type DaemonStatus } from './daemon-transport.js';
|
|
7
7
|
import type { BrowserRuntimeCommand, BrowserRuntimeResult } from './protocol.js';
|
|
8
|
+
export declare function setDaemonCommandTimeoutSeconds(seconds: number | null): void;
|
|
8
9
|
export type DaemonCommand = BrowserRuntimeCommand;
|
|
9
10
|
export type DaemonResult = BrowserRuntimeResult;
|
|
10
11
|
export declare class BrowserCommandError extends Error {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { sleep } from '../utils.js';
|
|
7
7
|
import { BrowserConnectError } from '../errors.js';
|
|
8
|
+
import { COMMAND_RESULT_UNKNOWN_CODE, COMMAND_RESULT_UNKNOWN_HINT } from '../daemon-utils.js';
|
|
8
9
|
import { classifyBrowserError } from './errors.js';
|
|
9
10
|
import { resolveProfileContextId } from './profile.js';
|
|
10
11
|
import { DEFAULT_BROWSER_CONNECT_TIMEOUT } from './config.js';
|
|
@@ -15,6 +16,51 @@ let _idCounter = 0;
|
|
|
15
16
|
function generateId() {
|
|
16
17
|
return `cmd_${process.pid}_${Date.now()}_${++_idCounter}`;
|
|
17
18
|
}
|
|
19
|
+
const DEFAULT_COMMAND_TIMEOUT_SECONDS = 120;
|
|
20
|
+
const RUNTIME_OP_TIMEOUT_MARGIN_MS = 15_000;
|
|
21
|
+
const HTTP_TIMEOUT_MARGIN_MS = 10_000;
|
|
22
|
+
const TRANSPORT_MAX_ATTEMPTS = 4;
|
|
23
|
+
let _userCommandTimeoutSeconds = null;
|
|
24
|
+
export function setDaemonCommandTimeoutSeconds(seconds) {
|
|
25
|
+
_userCommandTimeoutSeconds = typeof seconds === 'number' && seconds > 0 ? Math.ceil(seconds) : null;
|
|
26
|
+
}
|
|
27
|
+
function effectiveCommandTimeoutSeconds(params) {
|
|
28
|
+
const base = _userCommandTimeoutSeconds ?? DEFAULT_COMMAND_TIMEOUT_SECONDS;
|
|
29
|
+
if (typeof params.timeoutMs === 'number' && params.timeoutMs > 0) {
|
|
30
|
+
return Math.max(base, Math.ceil((params.timeoutMs + RUNTIME_OP_TIMEOUT_MARGIN_MS) / 1000));
|
|
31
|
+
}
|
|
32
|
+
return base;
|
|
33
|
+
}
|
|
34
|
+
const UNKNOWN_OUTCOME_CODES = new Set([
|
|
35
|
+
COMMAND_RESULT_UNKNOWN_CODE,
|
|
36
|
+
'command_lost',
|
|
37
|
+
'result_evicted',
|
|
38
|
+
]);
|
|
39
|
+
const PRE_CONNECT_ERROR_CODES = new Set([
|
|
40
|
+
'ECONNREFUSED',
|
|
41
|
+
'UND_ERR_CONNECT_TIMEOUT',
|
|
42
|
+
'EHOSTUNREACH',
|
|
43
|
+
'ENETUNREACH',
|
|
44
|
+
'ENOTFOUND',
|
|
45
|
+
]);
|
|
46
|
+
function isPreConnectFetchError(err) {
|
|
47
|
+
const queue = [err];
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
while (queue.length) {
|
|
50
|
+
const current = queue.pop();
|
|
51
|
+
if (!current || typeof current !== 'object' || seen.has(current))
|
|
52
|
+
continue;
|
|
53
|
+
seen.add(current);
|
|
54
|
+
const { code, cause, errors } = current;
|
|
55
|
+
if (typeof code === 'string' && PRE_CONNECT_ERROR_CODES.has(code))
|
|
56
|
+
return true;
|
|
57
|
+
if (cause)
|
|
58
|
+
queue.push(cause);
|
|
59
|
+
if (Array.isArray(errors))
|
|
60
|
+
queue.push(...errors);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
18
64
|
export class BrowserCommandError extends Error {
|
|
19
65
|
code;
|
|
20
66
|
hint;
|
|
@@ -30,58 +76,75 @@ export { fetchDaemonStatus, getDaemonHealth, requestDaemonShutdown, };
|
|
|
30
76
|
* Internal: send a command to the daemon and return the raw `DaemonResult`.
|
|
31
77
|
*
|
|
32
78
|
* Retry policy is explicit:
|
|
33
|
-
* - pre-dispatch bridge/profile errors
|
|
34
|
-
* path, then resend
|
|
35
|
-
* -
|
|
36
|
-
*
|
|
37
|
-
* - `command_result_unknown
|
|
79
|
+
* - pre-dispatch bridge/profile errors and pre-connect fetch failures run the
|
|
80
|
+
* full daemon/runtime ensure path, then resend the same command id;
|
|
81
|
+
* - executor-transient errors that happened before page code ran get one new
|
|
82
|
+
* logical attempt with a fresh id;
|
|
83
|
+
* - `command_result_unknown`, duplicate pending ids from old daemons,
|
|
84
|
+
* post-connect drops, and AbortError are never retried automatically.
|
|
38
85
|
*/
|
|
39
86
|
async function sendCommandRaw(action, params) {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
87
|
+
const timeoutSeconds = effectiveCommandTimeoutSeconds(params);
|
|
88
|
+
const deadlineAt = Date.now() + timeoutSeconds * 1000;
|
|
89
|
+
const rawWindowMode = process.env.WEBCMD_WINDOW;
|
|
90
|
+
const envWindowMode = rawWindowMode === 'foreground' || rawWindowMode === 'background'
|
|
91
|
+
? rawWindowMode
|
|
92
|
+
: undefined;
|
|
93
|
+
const contextId = params.contextId ?? resolveProfileContextId();
|
|
94
|
+
const windowMode = params.windowMode ?? envWindowMode;
|
|
95
|
+
let id = generateId();
|
|
96
|
+
let ensureUsed = false;
|
|
97
|
+
let semanticRetryUsed = false;
|
|
98
|
+
const ensureBridge = async () => {
|
|
99
|
+
const remainingSeconds = Math.ceil((deadlineAt - Date.now()) / 1000);
|
|
100
|
+
await ensureBrowserBridgeReady({
|
|
101
|
+
timeoutSeconds: Math.max(1, Math.min(DEFAULT_BROWSER_CONNECT_TIMEOUT, remainingSeconds)),
|
|
102
|
+
contextId,
|
|
103
|
+
verbose: false,
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
for (let attempt = 1; attempt <= TRANSPORT_MAX_ATTEMPTS; attempt++) {
|
|
107
|
+
if (attempt > 1 && Date.now() >= deadlineAt) {
|
|
108
|
+
throw new BrowserCommandError('Browser command deadline exhausted across transport retries.', COMMAND_RESULT_UNKNOWN_CODE, COMMAND_RESULT_UNKNOWN_HINT);
|
|
109
|
+
}
|
|
110
|
+
const remainingMs = Math.max(1000, deadlineAt - Date.now());
|
|
111
|
+
const command = {
|
|
112
|
+
id,
|
|
113
|
+
action,
|
|
114
|
+
...params,
|
|
115
|
+
timeout: timeoutSeconds,
|
|
116
|
+
deadlineAt,
|
|
117
|
+
...(contextId && { contextId }),
|
|
118
|
+
...(windowMode && { windowMode }),
|
|
119
|
+
};
|
|
53
120
|
try {
|
|
54
121
|
const res = await requestDaemon('/command', {
|
|
55
122
|
method: 'POST',
|
|
56
123
|
headers: { 'Content-Type': 'application/json' },
|
|
57
124
|
body: JSON.stringify(command),
|
|
58
|
-
timeout:
|
|
125
|
+
timeout: remainingMs + HTTP_TIMEOUT_MARGIN_MS,
|
|
59
126
|
});
|
|
60
127
|
const result = (await res.json());
|
|
61
128
|
if (result.ok)
|
|
62
129
|
return result;
|
|
63
|
-
if (result.errorCode
|
|
130
|
+
if (result.errorCode && UNKNOWN_OUTCOME_CODES.has(result.errorCode)) {
|
|
64
131
|
throw new BrowserCommandError(result.error ?? 'Browser command result is unknown', result.errorCode, result.errorHint);
|
|
65
132
|
}
|
|
66
|
-
if (!dispatchRecoveryUsed && isPreDispatchError(result.errorCode)) {
|
|
67
|
-
dispatchRecoveryUsed = true;
|
|
68
|
-
await ensureBrowserBridgeReady({
|
|
69
|
-
timeoutSeconds: DEFAULT_BROWSER_CONNECT_TIMEOUT,
|
|
70
|
-
contextId,
|
|
71
|
-
verbose: false,
|
|
72
|
-
});
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
133
|
const isDuplicateCommandId = res.status === 409
|
|
76
134
|
&& !result.errorCode
|
|
77
135
|
&& (result.error ?? '').includes('Duplicate command id');
|
|
78
|
-
if (isDuplicateCommandId
|
|
79
|
-
|
|
136
|
+
if (isDuplicateCommandId) {
|
|
137
|
+
throw new BrowserCommandError('Daemon already has this command id pending; the command may already be running.', COMMAND_RESULT_UNKNOWN_CODE, COMMAND_RESULT_UNKNOWN_HINT);
|
|
138
|
+
}
|
|
139
|
+
if (isPreDispatchError(result.errorCode) && !ensureUsed) {
|
|
140
|
+
ensureUsed = true;
|
|
141
|
+
await ensureBridge();
|
|
80
142
|
continue;
|
|
81
143
|
}
|
|
82
|
-
const advice = classifyBrowserError(new
|
|
83
|
-
if (advice.
|
|
84
|
-
|
|
144
|
+
const advice = classifyBrowserError(new BrowserCommandError(result.error ?? '', result.errorCode));
|
|
145
|
+
if (advice.kind === 'extension-transient' && !semanticRetryUsed) {
|
|
146
|
+
semanticRetryUsed = true;
|
|
147
|
+
id = generateId();
|
|
85
148
|
await sleep(advice.delayMs);
|
|
86
149
|
continue;
|
|
87
150
|
}
|
|
@@ -91,24 +154,13 @@ async function sendCommandRaw(action, params) {
|
|
|
91
154
|
if (err instanceof BrowserCommandError || err instanceof BrowserConnectError)
|
|
92
155
|
throw err;
|
|
93
156
|
if (err instanceof Error && err.name === 'AbortError') {
|
|
94
|
-
throw new BrowserCommandError('Browser command timed out client-side; the page may still have applied it.',
|
|
95
|
-
}
|
|
96
|
-
if (!dispatchRecoveryUsed && err instanceof TypeError) {
|
|
97
|
-
dispatchRecoveryUsed = true;
|
|
98
|
-
await ensureBrowserBridgeReady({
|
|
99
|
-
timeoutSeconds: DEFAULT_BROWSER_CONNECT_TIMEOUT,
|
|
100
|
-
contextId,
|
|
101
|
-
verbose: false,
|
|
102
|
-
});
|
|
103
|
-
continue;
|
|
157
|
+
throw new BrowserCommandError('Browser command timed out client-side; the page may still have applied it.', COMMAND_RESULT_UNKNOWN_CODE, COMMAND_RESULT_UNKNOWN_HINT);
|
|
104
158
|
}
|
|
105
|
-
if (err instanceof
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
transientRetryUsed = true;
|
|
109
|
-
await sleep(advice.delayMs);
|
|
159
|
+
if (err instanceof TypeError) {
|
|
160
|
+
await ensureBridge();
|
|
161
|
+
if (isPreConnectFetchError(err))
|
|
110
162
|
continue;
|
|
111
|
-
|
|
163
|
+
throw new BrowserCommandError('Connection to the daemon was lost mid-command; it may have already been applied.', COMMAND_RESULT_UNKNOWN_CODE, COMMAND_RESULT_UNKNOWN_HINT);
|
|
112
164
|
}
|
|
113
165
|
throw err;
|
|
114
166
|
}
|