@sovovs/bycli 1.8.0 → 2.0.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/cli-manifest.json +0 -61
- package/dist/src/adapter-shadow.js +2 -2
- package/dist/src/browser/analyze.d.ts +10 -99
- package/dist/src/browser/analyze.js +10 -226
- package/dist/src/browser/cdp.js +64 -7
- package/dist/src/browser/navigation-guard.d.ts +78 -0
- package/dist/src/browser/navigation-guard.js +142 -0
- package/dist/src/browser/navigation-guard.test.d.ts +1 -0
- package/dist/src/browser/url-policy.d.ts +89 -0
- package/dist/src/browser/url-policy.js +311 -0
- package/dist/src/browser/url-policy.test.d.ts +1 -0
- package/dist/src/browser/verify-fixture.js +2 -2
- package/dist/src/cli.js +10 -13
- package/dist/src/config-paths.d.ts +19 -0
- package/dist/src/config-paths.js +31 -0
- package/dist/src/daemon.js +240 -0
- package/dist/src/discovery.d.ts +5 -3
- package/dist/src/discovery.js +8 -6
- package/dist/src/execution.js +8 -3
- package/dist/src/main.js +18 -2
- package/dist/src/plugin.js +11 -8
- package/dist/src/recorder/highlevel/analyze.d.ts +29 -0
- package/dist/src/recorder/highlevel/analyze.js +91 -0
- package/dist/src/recorder/highlevel/init.d.ts +125 -0
- package/dist/src/recorder/highlevel/init.js +279 -0
- package/dist/src/recorder/highlevel/init.test.d.ts +1 -0
- package/dist/src/recorder/highlevel/verify.d.ts +73 -0
- package/dist/src/recorder/highlevel/verify.js +74 -0
- package/dist/src/recorder/http/analyze-runner.d.ts +28 -0
- package/dist/src/recorder/http/analyze-runner.js +78 -0
- package/dist/src/recorder/http/analyze-runner.test.d.ts +1 -0
- package/dist/src/recorder/http/handlers.d.ts +51 -0
- package/dist/src/recorder/http/handlers.js +219 -0
- package/dist/src/recorder/http/wrapper-config.d.ts +20 -0
- package/dist/src/recorder/http/wrapper-config.js +82 -0
- package/dist/src/recorder/http/wrapper-envelope.d.ts +31 -0
- package/dist/src/recorder/http/wrapper-envelope.js +51 -0
- package/dist/src/recorder/http/wrapper-gates.d.ts +16 -0
- package/dist/src/recorder/http/wrapper-gates.js +28 -0
- package/dist/src/recorder/http/wrapper-metrics.d.ts +1 -0
- package/dist/src/recorder/http/wrapper-metrics.js +5 -0
- package/dist/src/recorder/http/wrapper-registry.d.ts +50 -0
- package/dist/src/recorder/http/wrapper-registry.js +98 -0
- package/dist/src/recorder/http/wrapper-server.d.ts +59 -0
- package/dist/src/recorder/http/wrapper-server.js +240 -0
- package/dist/src/recorder/http/wrapper.test.d.ts +1 -0
- package/dist/src/recorder/observability/logger.d.ts +5 -0
- package/dist/src/recorder/observability/logger.js +13 -0
- package/dist/src/recorder/runner/config.d.ts +34 -0
- package/dist/src/recorder/runner/config.js +84 -0
- package/dist/src/recorder/runner/config.test.d.ts +1 -0
- package/dist/src/recorder/runner/reap.d.ts +79 -0
- package/dist/src/recorder/runner/reap.js +230 -0
- package/dist/src/recorder/runner/reap.test.d.ts +1 -0
- package/dist/src/recorder/runner/runner-port.d.ts +95 -0
- package/dist/src/recorder/runner/runner-port.js +518 -0
- package/dist/src/recorder/runner/runner-port.test.d.ts +1 -0
- package/dist/src/recorder/runner/session-keys.d.ts +28 -0
- package/dist/src/recorder/runner/session-keys.js +72 -0
- package/dist/src/recorder/runner/session-keys.test.d.ts +1 -0
- package/dist/src/recorder/runner/verify-runner-main.d.ts +95 -0
- package/dist/src/recorder/runner/verify-runner-main.js +275 -0
- package/dist/src/recorder/runner/verify-runner-main.test.d.ts +1 -0
- package/package.json +8 -5
- package/scripts/m1-daemon-navigate-drive.mjs +138 -0
- package/scripts/m1-extension-spike.mjs +237 -0
- package/scripts/m1-live-spike.mjs +156 -0
- package/scripts/m6b-connect-back-spike.sh +31 -0
- package/scripts/recorder.sh +186 -0
- package/clis/12306/utils.test.js +0 -331
- package/clis/1688/assets.test.js +0 -39
- package/clis/1688/download.test.js +0 -31
- package/clis/1688/item.test.js +0 -67
- package/clis/1688/search.test.js +0 -75
- package/clis/1688/shared.test.js +0 -57
- package/clis/1688/store.test.js +0 -62
- package/clis/36kr/article.test.js +0 -46
- package/clis/36kr/hot.test.js +0 -15
- package/clis/36kr/news.test.js +0 -85
- package/clis/51job/utils.test.js +0 -69
- package/clis/_atlassian/shared.test.js +0 -170
- package/clis/aibase/news.test.js +0 -59
- package/clis/amazon/bestsellers.test.js +0 -29
- package/clis/amazon/discussion.test.js +0 -124
- package/clis/amazon/offer.test.js +0 -29
- package/clis/amazon/product.test.js +0 -24
- package/clis/amazon/rankings.test.js +0 -41
- package/clis/amazon/search.test.js +0 -22
- package/clis/amazon/shared.test.js +0 -44
- package/clis/apple-podcasts/commands.test.js +0 -119
- package/clis/apple-podcasts/utils.test.js +0 -57
- package/clis/arxiv/arxiv.test.js +0 -112
- package/clis/baidu-scholar/search.test.js +0 -23
- package/clis/barchart/greeks.test.js +0 -138
- package/clis/bilibili/comment.test.js +0 -153
- package/clis/bilibili/comments.test.js +0 -142
- package/clis/bilibili/dynamic.test.js +0 -68
- package/clis/bilibili/hot.test.js +0 -17
- package/clis/bilibili/subtitle.test.js +0 -196
- package/clis/bilibili/summary.test.js +0 -210
- package/clis/bilibili/utils.test.js +0 -61
- package/clis/bilibili/video.test.js +0 -132
- package/clis/binance/commands.test.js +0 -70
- package/clis/bloomberg/utils.test.js +0 -129
- package/clis/booking/booking.test.js +0 -356
- package/clis/boss/chatlist.test.js +0 -211
- package/clis/boss/chatmsg.test.js +0 -230
- package/clis/boss/search.test.js +0 -78
- package/clis/boss/utils.test.js +0 -34
- package/clis/brave/search.test.js +0 -76
- package/clis/chaoxing/utils.test.js +0 -45
- package/clis/chatgpt/commands.test.js +0 -45
- package/clis/chatgpt/envelope.test.js +0 -108
- package/clis/chatgpt/image.test.js +0 -188
- package/clis/chatgpt/utils.test.js +0 -330
- package/clis/chatgpt-app/ax.test.js +0 -35
- package/clis/chatwise/composer.test.js +0 -186
- package/clis/chess/analyze.test.js +0 -79
- package/clis/chess/game.test.js +0 -178
- package/clis/chess/games.test.js +0 -164
- package/clis/chess/stats.test.js +0 -79
- package/clis/chess/utils.test.js +0 -230
- package/clis/claude/ask.test.js +0 -338
- package/clis/claude/commands.test.js +0 -118
- package/clis/claude/utils.test.js +0 -148
- package/clis/cnki/search.test.js +0 -18
- package/clis/codex/sidebar.test.js +0 -329
- package/clis/coingecko/coingecko.test.js +0 -109
- package/clis/confluence/commands.test.js +0 -195
- package/clis/coupang/coupang.test.js +0 -159
- package/clis/coupang/utils.test.js +0 -62
- package/clis/ctrip/ctrip.test.js +0 -719
- package/clis/dblp/dblp.test.js +0 -397
- package/clis/deepseek/ask.test.js +0 -312
- package/clis/deepseek/detail.test.js +0 -81
- package/clis/deepseek/send.test.js +0 -107
- package/clis/deepseek/utils.test.js +0 -370
- package/clis/defillama/defillama.test.js +0 -99
- package/clis/devto/devto.test.js +0 -236
- package/clis/dianping/dianping.test.js +0 -578
- package/clis/douban/download.test.js +0 -170
- package/clis/douban/movie-hot.test.js +0 -14
- package/clis/douban/search.test.js +0 -11
- package/clis/douban/subject.test.js +0 -11
- package/clis/douban/utils.test.js +0 -438
- package/clis/doubao/detail.test.js +0 -42
- package/clis/doubao/history.test.js +0 -37
- package/clis/doubao/utils.test.js +0 -344
- package/clis/douyin/_shared/browser-fetch.test.js +0 -64
- package/clis/douyin/_shared/creation-id.test.js +0 -22
- package/clis/douyin/_shared/imagex-upload.test.js +0 -87
- package/clis/douyin/_shared/sts2.test.js +0 -27
- package/clis/douyin/_shared/text-extra.test.js +0 -37
- 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.test.js +0 -229
- package/clis/douyin/_shared/transcode.test.js +0 -91
- package/clis/douyin/_shared/vod-upload.test.js +0 -38
- package/clis/douyin/activities.test.js +0 -55
- package/clis/douyin/collections.test.js +0 -45
- package/clis/douyin/delete.test.js +0 -100
- package/clis/douyin/draft.test.js +0 -335
- package/clis/douyin/drafts.test.js +0 -11
- package/clis/douyin/hashtag.test.js +0 -171
- package/clis/douyin/location.test.js +0 -23
- package/clis/douyin/profile.test.js +0 -46
- package/clis/douyin/publish-upload-id.test.js +0 -170
- package/clis/douyin/publish.test.js +0 -38
- package/clis/douyin/stats.test.js +0 -22
- package/clis/douyin/update.test.js +0 -11
- package/clis/douyin/user-videos.test.js +0 -151
- package/clis/douyin/videos.test.js +0 -54
- package/clis/duckduckgo/search.test.js +0 -128
- package/clis/duckduckgo/suggest.test.js +0 -66
- package/clis/eastmoney/hot-rank.test.js +0 -59
- package/clis/endoflife/endoflife.test.js +0 -51
- package/clis/facebook/feed.test.js +0 -169
- package/clis/facebook/marketplace.test.js +0 -91
- package/clis/facebook/notifications.test.js +0 -458
- package/clis/facebook/search.test.js +0 -55
- package/clis/flathub/flathub.test.js +0 -90
- package/clis/flomo/memos.test.js +0 -144
- package/clis/gemini/ask.test.js +0 -100
- package/clis/gemini/deep-research-result.test.js +0 -155
- package/clis/gemini/deep-research.test.js +0 -181
- package/clis/gemini/reply-state.test.js +0 -671
- package/clis/gemini/utils.test.js +0 -198
- package/clis/geogebra/geogebra.test.js +0 -175
- package/clis/gitee/search.test.js +0 -65
- package/clis/gitee/user.test.js +0 -63
- package/clis/google/utils.test.js +0 -75
- package/clis/google-scholar/cite.test.js +0 -47
- package/clis/google-scholar/profile.test.js +0 -49
- package/clis/google-scholar/search.test.js +0 -71
- package/clis/goproxy/goproxy.test.js +0 -103
- package/clis/gov-law/commands.test.js +0 -39
- package/clis/gov-policy/gov-policy.test.js +0 -224
- package/clis/grok/ask.test.js +0 -29
- package/clis/grok/utils.test.js +0 -103
- package/clis/hackernews/hackernews.test.js +0 -132
- package/clis/hf/hf.test.js +0 -16
- package/clis/hupu/hot.test.js +0 -224
- package/clis/imdb/utils.test.js +0 -88
- package/clis/indeed/indeed.test.js +0 -375
- package/clis/instagram/_shared/private-publish.test.js +0 -705
- package/clis/instagram/_shared/protocol-capture.test.js +0 -114
- package/clis/instagram/download.test.js +0 -118
- package/clis/instagram/note.test.js +0 -53
- package/clis/instagram/post.test.js +0 -1647
- package/clis/instagram/reel.test.js +0 -167
- package/clis/instagram/story.test.js +0 -134
- package/clis/jd/commands.test.js +0 -41
- package/clis/jd/item.test.js +0 -354
- package/clis/jianyu/search.test.js +0 -153
- package/clis/jianyu/shared/procurement-contract.test.js +0 -72
- package/clis/jianyu/shared/procurement-detail.test.js +0 -84
- package/clis/jike/read.test.js +0 -86
- package/clis/jira/commands.test.js +0 -287
- package/clis/juejin/search.js +0 -123
- package/clis/juejin/search.test.js +0 -98
- package/clis/lesswrong/frontpage.test.js +0 -37
- package/clis/lichess/lichess.test.js +0 -85
- package/clis/linkedin/connect.test.js +0 -213
- package/clis/linkedin/inbox.test.js +0 -152
- package/clis/linkedin/job-detail.test.js +0 -38
- package/clis/linkedin/jobs-preferences.test.js +0 -43
- package/clis/linkedin/people-search.test.js +0 -216
- package/clis/linkedin/post-analytics.test.js +0 -40
- package/clis/linkedin/posts.test.js +0 -40
- package/clis/linkedin/profile-analytics.test.js +0 -67
- package/clis/linkedin/profile-experience.test.js +0 -152
- package/clis/linkedin/profile-projects.test.js +0 -111
- package/clis/linkedin/profile-read.test.js +0 -77
- package/clis/linkedin/safe-send.test.js +0 -204
- package/clis/linkedin/salesnav-inbox.test.js +0 -113
- package/clis/linkedin/salesnav-message.test.js +0 -172
- package/clis/linkedin/salesnav-search.test.js +0 -76
- package/clis/linkedin/salesnav-thread.test.js +0 -79
- package/clis/linkedin/search.test.js +0 -222
- package/clis/linkedin/sent-invitations.test.js +0 -62
- package/clis/linkedin/services-read.test.js +0 -105
- package/clis/linkedin/thread-snapshot.test.js +0 -89
- package/clis/linkedin/timeline.test.js +0 -81
- package/clis/linkedin-learning/course.test.js +0 -114
- package/clis/linkedin-learning/search.test.js +0 -144
- package/clis/linkedin-learning/trending.test.js +0 -123
- package/clis/linux-do/feed.test.js +0 -153
- package/clis/linux-do/topic-content.test.js +0 -59
- package/clis/lobsters/lobsters.test.js +0 -169
- package/clis/notebooklm/add-source.test.js +0 -97
- package/clis/notebooklm/compat.test.js +0 -16
- package/clis/notebooklm/create.test.js +0 -58
- package/clis/notebooklm/generate-audio.test.js +0 -63
- package/clis/notebooklm/generate-slides.test.js +0 -75
- package/clis/notebooklm/history.test.js +0 -58
- package/clis/notebooklm/note-list.test.js +0 -56
- package/clis/notebooklm/notes-get.test.js +0 -72
- package/clis/notebooklm/open.test.js +0 -63
- package/clis/notebooklm/rpc.test.js +0 -131
- package/clis/notebooklm/source-fulltext.test.js +0 -106
- package/clis/notebooklm/source-get.test.js +0 -84
- package/clis/notebooklm/source-guide.test.js +0 -104
- package/clis/notebooklm/summary.test.js +0 -78
- package/clis/notebooklm/utils.test.js +0 -449
- package/clis/notebooklm/write-note.test.js +0 -70
- package/clis/nuget/nuget.test.js +0 -111
- package/clis/oeis/oeis.test.js +0 -88
- package/clis/ones/task-helpers.test.js +0 -12
- package/clis/ones/worklog.test.js +0 -20
- package/clis/openfda/openfda.test.js +0 -114
- package/clis/openreview/openreview.test.js +0 -427
- package/clis/osv/osv.test.js +0 -97
- package/clis/paperreview/commands.test.js +0 -243
- package/clis/paperreview/utils.test.js +0 -49
- package/clis/pixiv/download.test.js +0 -87
- package/clis/pixiv/illusts.test.js +0 -99
- package/clis/pixiv/search.test.js +0 -83
- package/clis/powerchina/search.test.js +0 -93
- package/clis/producthunt/utils.test.js +0 -64
- package/clis/pubmed/pubmed.test.js +0 -276
- package/clis/quark/utils.test.js +0 -58
- package/clis/qwen/utils.test.js +0 -45
- package/clis/reddit/extract-media.test.js +0 -149
- package/clis/reddit/frontpage.test.js +0 -34
- package/clis/reddit/home.test.js +0 -170
- package/clis/reddit/hot.test.js +0 -32
- package/clis/reddit/popular.test.js +0 -26
- package/clis/reddit/read.test.js +0 -335
- package/clis/reddit/reply.test.js +0 -89
- package/clis/reddit/search.test.js +0 -26
- package/clis/reddit/subreddit-info.test.js +0 -163
- package/clis/reddit/subreddit.test.js +0 -31
- package/clis/reddit/subscribed.test.js +0 -168
- package/clis/reddit/whoami.test.js +0 -105
- package/clis/rednote/navigation.test.js +0 -26
- package/clis/rednote/rednote.test.js +0 -222
- package/clis/rest-countries/rest-countries.test.js +0 -83
- package/clis/reuters/reuters.test.js +0 -299
- package/clis/rfc/rfc.test.js +0 -74
- package/clis/sinafinance/stock.test.js +0 -59
- package/clis/spotify/utils.test.js +0 -67
- package/clis/stackoverflow/stackoverflow.test.js +0 -404
- package/clis/steam/steam.test.js +0 -46
- package/clis/substack/utils.test.js +0 -44
- package/clis/suno/commands.test.js +0 -188
- package/clis/suno/download.test.js +0 -151
- package/clis/suno/generate.test.js +0 -252
- package/clis/suno/utils.test.js +0 -329
- package/clis/taobao/commands.test.js +0 -41
- package/clis/tdx/hot-rank.test.js +0 -59
- package/clis/ths/hot-rank.test.js +0 -64
- package/clis/tieba/commands.test.js +0 -79
- package/clis/tieba/utils.test.js +0 -290
- package/clis/tiktok/creator-videos.test.js +0 -113
- package/clis/tiktok/refactor.test.js +0 -389
- package/clis/tiktok/write-refactor.test.js +0 -370
- package/clis/toutiao/toutiao.test.js +0 -378
- package/clis/tvmaze/tvmaze.test.js +0 -93
- package/clis/twitter/bookmark-folder.test.js +0 -395
- package/clis/twitter/bookmark-folders.test.js +0 -152
- package/clis/twitter/bookmark.test.js +0 -74
- package/clis/twitter/bookmarks.test.js +0 -205
- package/clis/twitter/delete.test.js +0 -85
- package/clis/twitter/device-follow.test.js +0 -287
- package/clis/twitter/download.test.js +0 -457
- package/clis/twitter/followers.test.js +0 -62
- package/clis/twitter/following.test.js +0 -338
- package/clis/twitter/hide-reply.test.js +0 -76
- package/clis/twitter/like.test.js +0 -73
- package/clis/twitter/likes.test.js +0 -220
- package/clis/twitter/list-add.test.js +0 -133
- package/clis/twitter/list-create.test.js +0 -169
- package/clis/twitter/list-remove.test.js +0 -110
- package/clis/twitter/list-tweets.test.js +0 -196
- package/clis/twitter/lists.test.js +0 -253
- package/clis/twitter/post.test.js +0 -258
- package/clis/twitter/profile.test.js +0 -39
- package/clis/twitter/quote.test.js +0 -194
- package/clis/twitter/reply.test.js +0 -237
- package/clis/twitter/retweet.test.js +0 -73
- package/clis/twitter/search.test.js +0 -349
- package/clis/twitter/shared.test.js +0 -794
- package/clis/twitter/thread.test.js +0 -58
- package/clis/twitter/timeline.test.js +0 -104
- package/clis/twitter/trending.test.js +0 -15
- package/clis/twitter/tweets.test.js +0 -362
- package/clis/twitter/unbookmark.test.js +0 -73
- package/clis/twitter/unlike.test.js +0 -75
- package/clis/twitter/unretweet.test.js +0 -73
- package/clis/twitter/utils.test.js +0 -169
- package/clis/uisdc/news.test.js +0 -66
- package/clis/uiverse/_shared.test.js +0 -62
- package/clis/uiverse/navigation.test.js +0 -12
- package/clis/upwork/upwork.test.js +0 -566
- package/clis/wanfang/search.test.js +0 -23
- package/clis/web/read.test.js +0 -392
- package/clis/weibo/delete.test.js +0 -94
- package/clis/weibo/envelope.test.js +0 -85
- package/clis/weibo/favorites.test.js +0 -114
- package/clis/weibo/publish.test.js +0 -192
- package/clis/weibo/user-posts.test.js +0 -92
- package/clis/weibo/utils.test.js +0 -36
- package/clis/weixin/drafts.test.js +0 -69
- package/clis/weixin/search.test.js +0 -227
- package/clis/weread/ai-outline.test.js +0 -83
- package/clis/weread/book-search.test.js +0 -242
- package/clis/weread/commands.test.js +0 -398
- package/clis/weread/private-api-regression.test.js +0 -369
- package/clis/weread/search-regression.test.js +0 -494
- package/clis/weread/utils.test.js +0 -128
- package/clis/weread-official/commands.test.js +0 -385
- package/clis/weread-official/utils.test.js +0 -242
- package/clis/wikidata/wikidata.test.js +0 -83
- package/clis/wikipedia/trending.test.js +0 -57
- package/clis/wttr/wttr.test.js +0 -84
- package/clis/xianyu/chat.test.js +0 -84
- package/clis/xianyu/im.test.js +0 -253
- package/clis/xianyu/item.test.js +0 -56
- package/clis/xianyu/publish.test.js +0 -220
- package/clis/xianyu/search.test.js +0 -17
- package/clis/xiaoe/xiaoe.test.js +0 -486
- package/clis/xiaohongshu/comments.test.js +0 -258
- package/clis/xiaohongshu/creator-note-detail.test.js +0 -451
- package/clis/xiaohongshu/creator-notes-summary.test.js +0 -94
- package/clis/xiaohongshu/creator-notes.test.js +0 -281
- package/clis/xiaohongshu/creator-stats.test.js +0 -24
- package/clis/xiaohongshu/delete-note.test.js +0 -172
- package/clis/xiaohongshu/download.test.js +0 -316
- package/clis/xiaohongshu/navigation.test.js +0 -34
- package/clis/xiaohongshu/note.test.js +0 -249
- package/clis/xiaohongshu/publish.test.js +0 -608
- package/clis/xiaohongshu/search.test.js +0 -325
- package/clis/xiaohongshu/user-helpers.test.js +0 -160
- package/clis/xiaoyuzhou/auth.test.js +0 -124
- package/clis/xiaoyuzhou/download.test.js +0 -135
- package/clis/xiaoyuzhou/podcast-episodes.test.js +0 -78
- package/clis/xiaoyuzhou/transcript.test.js +0 -195
- package/clis/xiaoyuzhou/utils.test.js +0 -39
- package/clis/xueqiu/comments.test.js +0 -696
- package/clis/xueqiu/danjuan-utils.test.js +0 -41
- package/clis/xueqiu/utils.test.js +0 -26
- package/clis/yahoo/search.test.js +0 -94
- package/clis/youdao/note.test.js +0 -99
- package/clis/youtube/channel.test.js +0 -59
- package/clis/youtube/feed.test.js +0 -131
- package/clis/youtube/transcript-group.test.js +0 -99
- package/clis/youtube/transcript.test.js +0 -296
- package/clis/youtube/utils.test.js +0 -84
- package/clis/yuanbao/ask.test.js +0 -124
- package/clis/yuanbao/new.test.js +0 -30
- package/clis/yuanbao/shared.test.js +0 -80
- package/clis/zhihu/answer-comments.test.js +0 -287
- package/clis/zhihu/answer-detail.test.js +0 -338
- package/clis/zhihu/answer.test.js +0 -54
- package/clis/zhihu/collection.test.js +0 -337
- package/clis/zhihu/collections.test.js +0 -182
- package/clis/zhihu/comment.test.js +0 -50
- package/clis/zhihu/download.test.js +0 -12
- package/clis/zhihu/favorite.test.js +0 -59
- package/clis/zhihu/follow.test.js +0 -42
- package/clis/zhihu/like.test.js +0 -41
- package/clis/zhihu/question.test.js +0 -251
- package/clis/zhihu/recommend.test.js +0 -143
- package/clis/zhihu/search.test.js +0 -198
- package/clis/zhihu/target.test.js +0 -77
- package/clis/zhihu/text.test.js +0 -24
- package/clis/zhihu/write-shared.test.js +0 -176
- package/clis/zlibrary/commands.test.js +0 -65
- package/clis/zsxq/search.test.js +0 -24
- package/clis/zsxq/topic.test.js +0 -30
- package/clis/zsxq/topics.test.js +0 -24
- package/clis/zsxq/utils.test.js +0 -31
- package/dist/src/adapter-shadow.test.js +0 -49
- package/dist/src/adapter-source.test.js +0 -29
- package/dist/src/browser/analyze.test.js +0 -166
- package/dist/src/browser/article-extract.e2e.test.js +0 -105
- package/dist/src/browser/article-extract.test.js +0 -94
- package/dist/src/browser/ax-snapshot.test.js +0 -91
- package/dist/src/browser/base-page.test.js +0 -758
- package/dist/src/browser/cdp-click-fixture.test.js +0 -87
- package/dist/src/browser/cdp.test.js +0 -79
- package/dist/src/browser/compound.test.js +0 -175
- package/dist/src/browser/daemon-client.test.js +0 -199
- package/dist/src/browser/dom-helpers.test.js +0 -106
- package/dist/src/browser/dom-snapshot.test.js +0 -313
- package/dist/src/browser/errors.test.js +0 -60
- package/dist/src/browser/extract.test.js +0 -129
- package/dist/src/browser/find.test.js +0 -180
- package/dist/src/browser/html-tree.test.js +0 -181
- package/dist/src/browser/network-cache.test.js +0 -58
- package/dist/src/browser/network-key.test.js +0 -49
- package/dist/src/browser/page.test.js +0 -378
- package/dist/src/browser/shape-filter.test.js +0 -101
- package/dist/src/browser/shape.test.js +0 -82
- package/dist/src/browser/stealth.test.js +0 -134
- package/dist/src/browser/target-errors.test.js +0 -94
- package/dist/src/browser/target-resolver.test.js +0 -118
- package/dist/src/browser/utils.test.js +0 -29
- package/dist/src/browser/verify-fixture.test.js +0 -219
- package/dist/src/browser.test.js +0 -232
- package/dist/src/build-manifest.test.js +0 -341
- package/dist/src/capabilityRouting.test.js +0 -63
- package/dist/src/cli-argv-preprocess.test.js +0 -209
- package/dist/src/cli.test.js +0 -2803
- package/dist/src/commanderAdapter.test.js +0 -352
- package/dist/src/commands/daemon.test.js +0 -219
- package/dist/src/completion.test.js +0 -24
- package/dist/src/convention-audit.test.js +0 -247
- package/dist/src/daemon.test.js +0 -60
- package/dist/src/doctor.test.js +0 -263
- package/dist/src/download/article-download.test.js +0 -235
- package/dist/src/download/index.test.js +0 -140
- package/dist/src/download/media-download.test.js +0 -112
- package/dist/src/download/progress.test.js +0 -36
- package/dist/src/electron-apps.test.js +0 -49
- package/dist/src/engine.test.js +0 -312
- package/dist/src/errors.test.js +0 -109
- package/dist/src/execution.test.js +0 -623
- package/dist/src/extension-manifest-regression.test.js +0 -12
- package/dist/src/external.test.js +0 -146
- package/dist/src/help.test.js +0 -58
- package/dist/src/hooks.test.js +0 -92
- package/dist/src/interceptor.test.js +0 -81
- package/dist/src/launcher.test.js +0 -138
- package/dist/src/node-network.test.js +0 -55
- package/dist/src/observation/artifact.test.js +0 -121
- package/dist/src/observation/manager.test.js +0 -13
- package/dist/src/observation/redaction.test.js +0 -32
- package/dist/src/observation/retention.test.js +0 -118
- package/dist/src/observation/ring-buffer.test.js +0 -22
- package/dist/src/output.test.js +0 -53
- package/dist/src/package-exports.test.js +0 -112
- package/dist/src/pipeline/executor.test.js +0 -182
- package/dist/src/pipeline/steps/download.test.js +0 -102
- package/dist/src/pipeline/steps/fetch.test.js +0 -117
- package/dist/src/pipeline/template.test.js +0 -175
- package/dist/src/pipeline/transform.test.js +0 -133
- package/dist/src/plugin-manifest.test.js +0 -179
- package/dist/src/plugin-scaffold.test.js +0 -83
- package/dist/src/plugin.test.js +0 -1324
- package/dist/src/registry.test.js +0 -209
- package/dist/src/runtime-detect.test.js +0 -39
- package/dist/src/serialization.test.js +0 -78
- package/dist/src/snapshotFormatter.test.js +0 -521
- package/dist/src/tui.test.js +0 -19
- package/dist/src/update-check.test.js +0 -116
- package/dist/src/utils.test.js +0 -155
- package/dist/src/validate.test.js +0 -90
- package/dist/src/weixin-download.test.js +0 -45
package/dist/src/utils.test.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { parseJsonOrThrowLoginWall, throwIfLoginWall, BROWSER_JSON_SNIFF_FN, } from './utils.js';
|
|
3
|
-
import { LoginWallError } from './errors.js';
|
|
4
|
-
function makeResponse(body, opts = {}) {
|
|
5
|
-
return new Response(body, {
|
|
6
|
-
status: opts.status ?? 200,
|
|
7
|
-
headers: { 'content-type': opts.contentType ?? 'application/json' },
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
describe('parseJsonOrThrowLoginWall', () => {
|
|
11
|
-
it('returns parsed JSON on a normal application/json response', async () => {
|
|
12
|
-
const res = makeResponse(JSON.stringify({ hello: 'world', n: 42 }));
|
|
13
|
-
const parsed = await parseJsonOrThrowLoginWall(res);
|
|
14
|
-
expect(parsed).toEqual({ hello: 'world', n: 42 });
|
|
15
|
-
});
|
|
16
|
-
it('throws LoginWallError when content-type is text/html', async () => {
|
|
17
|
-
const res = makeResponse('<html><body>Please log in</body></html>', {
|
|
18
|
-
status: 401,
|
|
19
|
-
contentType: 'text/html; charset=utf-8',
|
|
20
|
-
});
|
|
21
|
-
await expect(parseJsonOrThrowLoginWall(res, { url: 'https://example.com/api' })).rejects.toMatchObject({
|
|
22
|
-
name: 'LoginWallError',
|
|
23
|
-
code: 'LOGIN_WALL',
|
|
24
|
-
status: 401,
|
|
25
|
-
url: 'https://example.com/api',
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
it('throws LoginWallError when body starts with <!DOCTYPE even if content-type is missing', async () => {
|
|
29
|
-
// application/json content-type but body is actually HTML — WAFs sometimes do this
|
|
30
|
-
const res = new Response('<!DOCTYPE html><html><head></head><body>blocked</body></html>', {
|
|
31
|
-
status: 200,
|
|
32
|
-
headers: { 'content-type': 'application/json' },
|
|
33
|
-
});
|
|
34
|
-
try {
|
|
35
|
-
await parseJsonOrThrowLoginWall(res, { url: 'https://x.com/api/list' });
|
|
36
|
-
throw new Error('expected throw');
|
|
37
|
-
}
|
|
38
|
-
catch (err) {
|
|
39
|
-
expect(err).toBeInstanceOf(LoginWallError);
|
|
40
|
-
const e = err;
|
|
41
|
-
expect(e.status).toBe(200);
|
|
42
|
-
expect(e.url).toBe('https://x.com/api/list');
|
|
43
|
-
expect(e.bodyPreview.startsWith('<!DOCTYPE')).toBe(true);
|
|
44
|
-
expect(e.exitCode).toBe(77); // NOPERM
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
it('throws LoginWallError when body starts with <html (no DOCTYPE)', async () => {
|
|
48
|
-
const res = new Response('<html lang="en"><body>nope</body></html>', {
|
|
49
|
-
status: 429,
|
|
50
|
-
headers: { 'content-type': 'application/json' },
|
|
51
|
-
});
|
|
52
|
-
await expect(parseJsonOrThrowLoginWall(res)).rejects.toBeInstanceOf(LoginWallError);
|
|
53
|
-
});
|
|
54
|
-
it('throws LoginWallError when body has leading whitespace before <!DOCTYPE', async () => {
|
|
55
|
-
const res = new Response(' \n\n<!DOCTYPE html><html></html>', {
|
|
56
|
-
status: 200,
|
|
57
|
-
headers: { 'content-type': 'application/octet-stream' },
|
|
58
|
-
});
|
|
59
|
-
await expect(parseJsonOrThrowLoginWall(res)).rejects.toBeInstanceOf(LoginWallError);
|
|
60
|
-
});
|
|
61
|
-
it('throws a regular Error (NOT LoginWallError) on real malformed JSON', async () => {
|
|
62
|
-
const res = makeResponse('{not really json,');
|
|
63
|
-
try {
|
|
64
|
-
await parseJsonOrThrowLoginWall(res);
|
|
65
|
-
throw new Error('expected throw');
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
expect(err).toBeInstanceOf(Error);
|
|
69
|
-
expect(err).not.toBeInstanceOf(LoginWallError);
|
|
70
|
-
const msg = err.message;
|
|
71
|
-
expect(msg).toContain('JSON parse failed');
|
|
72
|
-
expect(msg).toContain('body[0..50]=');
|
|
73
|
-
// body preview must be present so debugging doesn't require a repro
|
|
74
|
-
expect(msg).toContain('not really json');
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
it('preserves first 100 chars of body in bodyPreview', async () => {
|
|
78
|
-
const longHtml = '<!DOCTYPE html><html><head><title>' + 'x'.repeat(500) + '</title></head></html>';
|
|
79
|
-
const res = new Response(longHtml, { status: 403, headers: { 'content-type': 'text/html' } });
|
|
80
|
-
try {
|
|
81
|
-
await parseJsonOrThrowLoginWall(res);
|
|
82
|
-
throw new Error('expected throw');
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
const e = err;
|
|
86
|
-
expect(e.bodyPreview.length).toBe(100);
|
|
87
|
-
expect(e.bodyPreview.startsWith('<!DOCTYPE')).toBe(true);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('throwIfLoginWall', () => {
|
|
92
|
-
it('returns the value unchanged when it is not a login-wall sentinel', () => {
|
|
93
|
-
const data = { data: { foo: 'bar' } };
|
|
94
|
-
expect(throwIfLoginWall(data)).toBe(data);
|
|
95
|
-
expect(throwIfLoginWall('hello')).toBe('hello');
|
|
96
|
-
expect(throwIfLoginWall(null)).toBe(null);
|
|
97
|
-
expect(throwIfLoginWall(undefined)).toBe(undefined);
|
|
98
|
-
expect(throwIfLoginWall(42)).toBe(42);
|
|
99
|
-
expect(throwIfLoginWall([1, 2, 3])).toEqual([1, 2, 3]);
|
|
100
|
-
});
|
|
101
|
-
it('returns objects that happen to have unrelated __loginWall-ish keys unchanged', () => {
|
|
102
|
-
// Must NOT trigger on partial matches — sentinel needs __loginWall === true AND numeric status
|
|
103
|
-
expect(throwIfLoginWall({ __loginWall: false })).toEqual({ __loginWall: false });
|
|
104
|
-
expect(throwIfLoginWall({ __loginWall: true })).toEqual({ __loginWall: true }); // missing status → not a real sentinel
|
|
105
|
-
});
|
|
106
|
-
it('throws LoginWallError when value is the browser-side sentinel', () => {
|
|
107
|
-
const signal = {
|
|
108
|
-
__loginWall: true,
|
|
109
|
-
status: 403,
|
|
110
|
-
url: 'https://x.com/i/api/graphql/...',
|
|
111
|
-
contentType: 'text/html',
|
|
112
|
-
bodyPreview: '<!DOCTYPE html><html><head><title>Login</title>',
|
|
113
|
-
};
|
|
114
|
-
try {
|
|
115
|
-
throwIfLoginWall(signal);
|
|
116
|
-
throw new Error('expected throw');
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
expect(err).toBeInstanceOf(LoginWallError);
|
|
120
|
-
const e = err;
|
|
121
|
-
expect(e.status).toBe(403);
|
|
122
|
-
expect(e.url).toBe('https://x.com/i/api/graphql/...');
|
|
123
|
-
expect(e.bodyPreview).toContain('<!DOCTYPE');
|
|
124
|
-
expect(e.code).toBe('LOGIN_WALL');
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
it('opts.url overrides the URL embedded in the sentinel', () => {
|
|
128
|
-
const signal = {
|
|
129
|
-
__loginWall: true,
|
|
130
|
-
status: 401,
|
|
131
|
-
url: '',
|
|
132
|
-
contentType: 'text/html',
|
|
133
|
-
bodyPreview: '<html>',
|
|
134
|
-
};
|
|
135
|
-
try {
|
|
136
|
-
throwIfLoginWall(signal, { url: 'https://override.example.com/api' });
|
|
137
|
-
throw new Error('expected throw');
|
|
138
|
-
}
|
|
139
|
-
catch (err) {
|
|
140
|
-
expect(err.url).toBe('https://override.example.com/api');
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
describe('BROWSER_JSON_SNIFF_FN', () => {
|
|
145
|
-
it('is a non-empty string that defines fetchJsonOrLoginWall', () => {
|
|
146
|
-
expect(typeof BROWSER_JSON_SNIFF_FN).toBe('string');
|
|
147
|
-
expect(BROWSER_JSON_SNIFF_FN).toContain('fetchJsonOrLoginWall');
|
|
148
|
-
expect(BROWSER_JSON_SNIFF_FN).toContain('__loginWall');
|
|
149
|
-
});
|
|
150
|
-
it('can be evaluated as JS without syntax errors', () => {
|
|
151
|
-
// We can't run the actual fetch path here (no Response polyfill loop), but
|
|
152
|
-
// we CAN confirm the fragment parses cleanly when embedded inside an async IIFE.
|
|
153
|
-
expect(() => new Function(`(async () => { ${BROWSER_JSON_SNIFF_FN} })`)).not.toThrow();
|
|
154
|
-
});
|
|
155
|
-
});
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for src/validate.ts.
|
|
3
|
-
*
|
|
4
|
-
* Focus: regression guards for the "single source of truth" link between
|
|
5
|
-
* pipeline step registry (src/pipeline/registry.ts) and validate.ts step
|
|
6
|
-
* allowlist. A new step registered via `registerStep()` must automatically
|
|
7
|
-
* be allowlisted by `bycli validate` — no parallel hand-maintained list.
|
|
8
|
-
*/
|
|
9
|
-
import { describe, it, expect } from 'vitest';
|
|
10
|
-
import { getRegisteredStepNames, registerStep } from './pipeline/registry.js';
|
|
11
|
-
import { cli, getRegistry, Strategy } from './registry.js';
|
|
12
|
-
import { validateClisWithTarget } from './validate.js';
|
|
13
|
-
describe('validate.ts pipeline step allowlist', () => {
|
|
14
|
-
it('uses every step name registered in pipeline/registry.ts', () => {
|
|
15
|
-
const registered = getRegisteredStepNames();
|
|
16
|
-
expect(registered).toContain('navigate');
|
|
17
|
-
expect(registered).toContain('click');
|
|
18
|
-
expect(registered).toContain('type');
|
|
19
|
-
expect(registered).toContain('fill');
|
|
20
|
-
expect(registered).toContain('fetch');
|
|
21
|
-
expect(registered.length).toBeGreaterThanOrEqual(15);
|
|
22
|
-
});
|
|
23
|
-
it('does not warn for any step name currently registered in the pipeline registry', () => {
|
|
24
|
-
// Snapshot the registry before mutating it for the test.
|
|
25
|
-
const reg = getRegistry();
|
|
26
|
-
const original = reg.get('validate-allowlist-test/all-steps');
|
|
27
|
-
if (original)
|
|
28
|
-
reg.delete('validate-allowlist-test/all-steps');
|
|
29
|
-
const allRegisteredSteps = getRegisteredStepNames();
|
|
30
|
-
cli({
|
|
31
|
-
site: 'validate-allowlist-test',
|
|
32
|
-
name: 'all-steps',
|
|
33
|
-
access: 'read',
|
|
34
|
-
browser: false,
|
|
35
|
-
strategy: Strategy.PUBLIC,
|
|
36
|
-
args: [],
|
|
37
|
-
pipeline: allRegisteredSteps.map(stepName => ({ [stepName]: {} })),
|
|
38
|
-
func: async () => [],
|
|
39
|
-
});
|
|
40
|
-
try {
|
|
41
|
-
const report = validateClisWithTarget([], 'validate-allowlist-test/all-steps');
|
|
42
|
-
const r = report.results[0];
|
|
43
|
-
const unknownStepWarning = r.warnings.find(w => w.startsWith('Pipeline step '));
|
|
44
|
-
expect(unknownStepWarning).toBeUndefined();
|
|
45
|
-
}
|
|
46
|
-
finally {
|
|
47
|
-
reg.delete('validate-allowlist-test/all-steps');
|
|
48
|
-
if (original)
|
|
49
|
-
reg.set('validate-allowlist-test/all-steps', original);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
it('newly registered step automatically appears in validator allowlist', () => {
|
|
53
|
-
const customStep = '__test_custom_step__';
|
|
54
|
-
expect(getRegisteredStepNames()).not.toContain(customStep);
|
|
55
|
-
registerStep(customStep, async (_p, _params, data) => data);
|
|
56
|
-
try {
|
|
57
|
-
expect(getRegisteredStepNames()).toContain(customStep);
|
|
58
|
-
const reg = getRegistry();
|
|
59
|
-
const original = reg.get('validate-dynamic-test/uses-custom');
|
|
60
|
-
if (original)
|
|
61
|
-
reg.delete('validate-dynamic-test/uses-custom');
|
|
62
|
-
cli({
|
|
63
|
-
site: 'validate-dynamic-test',
|
|
64
|
-
name: 'uses-custom',
|
|
65
|
-
access: 'read',
|
|
66
|
-
browser: false,
|
|
67
|
-
strategy: Strategy.PUBLIC,
|
|
68
|
-
args: [],
|
|
69
|
-
pipeline: [{ [customStep]: {} }],
|
|
70
|
-
func: async () => [],
|
|
71
|
-
});
|
|
72
|
-
try {
|
|
73
|
-
const report = validateClisWithTarget([], 'validate-dynamic-test/uses-custom');
|
|
74
|
-
const r = report.results[0];
|
|
75
|
-
const unknownStepWarning = r.warnings.find(w => w.includes(customStep));
|
|
76
|
-
expect(unknownStepWarning).toBeUndefined();
|
|
77
|
-
}
|
|
78
|
-
finally {
|
|
79
|
-
reg.delete('validate-dynamic-test/uses-custom');
|
|
80
|
-
if (original)
|
|
81
|
-
reg.set('validate-dynamic-test/uses-custom', original);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
finally {
|
|
85
|
-
// Best-effort cleanup of the test step. There is no `unregisterStep` —
|
|
86
|
-
// leaving it registered is harmless because the test step name is
|
|
87
|
-
// namespaced and never used outside this file.
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
async function loadModule() {
|
|
3
|
-
// @ts-expect-error JS adapter — no type declarations
|
|
4
|
-
return import('../clis/weixin/download.js');
|
|
5
|
-
}
|
|
6
|
-
describe('weixin publish time extraction', () => {
|
|
7
|
-
it('prefers publish_time text over create_time-like date strings', async () => {
|
|
8
|
-
const mod = await loadModule();
|
|
9
|
-
expect(mod.extractWechatPublishTime('2026年3月24日 22:38', 'var create_time = "2026年3月24日 22:38";')).toBe('2026年3月24日 22:38');
|
|
10
|
-
});
|
|
11
|
-
it('falls back to unix timestamp create_time values', async () => {
|
|
12
|
-
const mod = await loadModule();
|
|
13
|
-
expect(mod.extractWechatPublishTime('', 'var create_time = "1711291080";')).toBe('2024-03-24 22:38:00');
|
|
14
|
-
});
|
|
15
|
-
it('rejects malformed create_time values', async () => {
|
|
16
|
-
const mod = await loadModule();
|
|
17
|
-
expect(mod.extractWechatPublishTime('', 'var create_time = "2026年3月24日 22:38";')).toBe('');
|
|
18
|
-
expect(mod.extractWechatPublishTime('', 'var create_time = "1711291080abc";')).toBe('');
|
|
19
|
-
expect(mod.extractWechatPublishTime('', 'var create_time = "17112910800";')).toBe('');
|
|
20
|
-
});
|
|
21
|
-
it('builds a self-contained browser helper that matches fallback behavior', async () => {
|
|
22
|
-
const mod = await loadModule();
|
|
23
|
-
const extractInPage = eval(mod.buildExtractWechatPublishTimeJs());
|
|
24
|
-
expect(extractInPage('', 'var create_time = "1711291080";')).toBe('2024-03-24 22:38:00');
|
|
25
|
-
});
|
|
26
|
-
it('browser helper still prefers DOM publish_time text', async () => {
|
|
27
|
-
const mod = await loadModule();
|
|
28
|
-
const extractInPage = eval(mod.buildExtractWechatPublishTimeJs());
|
|
29
|
-
expect(extractInPage('2026年3月24日 22:38', 'var create_time = "1711291080";')).toBe('2026年3月24日 22:38');
|
|
30
|
-
});
|
|
31
|
-
it('detects WeChat verification gate pages', async () => {
|
|
32
|
-
const mod = await loadModule();
|
|
33
|
-
expect(mod.detectWechatAccessIssue('环境异常 当前环境异常,完成验证后即可继续访问。 去验证', '<html><body><a id="js_verify">去验证</a></body></html>')).toBe('environment verification required');
|
|
34
|
-
});
|
|
35
|
-
it('browser access detector matches the server-side verifier', async () => {
|
|
36
|
-
const mod = await loadModule();
|
|
37
|
-
const detectInPage = eval(mod.buildDetectWechatAccessIssueJs());
|
|
38
|
-
expect(detectInPage('环境异常 当前环境异常,完成验证后即可继续访问。 去验证', '<html>secitptpage/verify.html<a id="js_verify">去验证</a></html>')).toBe('environment verification required');
|
|
39
|
-
});
|
|
40
|
-
it('picks the first non-empty WeChat metadata field', async () => {
|
|
41
|
-
const mod = await loadModule();
|
|
42
|
-
expect(mod.pickFirstWechatMetaText('', 'Name cleared', '数字生命卡兹克')).toBe('数字生命卡兹克');
|
|
43
|
-
expect(mod.pickFirstWechatMetaText('', ' 聊聊刚刚上线的PixVerse V6视频模型。 ')).toBe('聊聊刚刚上线的PixVerse V6视频模型。');
|
|
44
|
-
});
|
|
45
|
-
});
|