@sovovs/bycli 1.8.0 → 2.1.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/clis/twitter/search.js +3 -3
- 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 +67 -7
- package/dist/src/browser/daemon-client.d.ts +2 -0
- package/dist/src/browser/daemon-client.js +1 -1
- package/dist/src/browser/extension-capabilities.d.ts +13 -0
- package/dist/src/browser/extension-capabilities.js +22 -0
- package/dist/src/browser/extension-capabilities.test.d.ts +1 -0
- package/dist/src/browser/extension-version-metadata.test.d.ts +1 -0
- 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/page.d.ts +1 -0
- package/dist/src/browser/page.js +20 -1
- 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/build-manifest.js +4 -2
- package/dist/src/capabilityRouting.d.ts +3 -2
- package/dist/src/capabilityRouting.js +10 -2
- package/dist/src/cli.js +11 -14
- package/dist/src/commanderAdapter.js +5 -5
- package/dist/src/config-paths.d.ts +19 -0
- package/dist/src/config-paths.js +31 -0
- package/dist/src/daemon.js +256 -0
- package/dist/src/discovery.d.ts +10 -3
- package/dist/src/discovery.js +20 -10
- package/dist/src/discovery.test.d.ts +1 -0
- package/dist/src/execution.d.ts +5 -0
- package/dist/src/execution.js +272 -48
- package/dist/src/help.js +8 -8
- package/dist/src/main.js +18 -2
- package/dist/src/manifest-schema.d.ts +9 -0
- package/dist/src/manifest-schema.js +162 -0
- package/dist/src/manifest-schema.test.d.ts +1 -0
- package/dist/src/manifest-types.d.ts +1 -1
- package/dist/src/observation/redaction.js +10 -4
- 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 +96 -0
- package/dist/src/recorder/runner/verify-runner-main.js +292 -0
- package/dist/src/recorder/runner/verify-runner-main.test.d.ts +1 -0
- package/dist/src/registry-api.d.ts +1 -1
- package/dist/src/registry-api.types.test.d.ts +1 -0
- package/dist/src/registry-transaction.d.ts +42 -0
- package/dist/src/registry-transaction.js +194 -0
- package/dist/src/registry-transaction.test.d.ts +1 -0
- package/dist/src/registry.d.ts +58 -16
- package/dist/src/registry.js +131 -15
- package/dist/src/serialization.d.ts +1 -1
- package/dist/src/serialization.js +3 -3
- package/dist/src/types.d.ts +2 -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/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
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export class ManifestSchemaError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'ManifestSchemaError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
function fail(context, path, reason) {
|
|
8
|
+
throw new ManifestSchemaError(`${context} ${path}: ${reason}`);
|
|
9
|
+
}
|
|
10
|
+
function markSeen(value, context, path, seen) {
|
|
11
|
+
if (seen.has(value))
|
|
12
|
+
fail(context, path, 'cyclic or repeated/shared object identities cannot be represented faithfully in JSON');
|
|
13
|
+
seen.add(value);
|
|
14
|
+
}
|
|
15
|
+
function denseArrayValues(value, context, path) {
|
|
16
|
+
if (Object.getPrototypeOf(value) !== Array.prototype) {
|
|
17
|
+
fail(context, path, 'must be a standard JSON array (custom array instances are not supported)');
|
|
18
|
+
}
|
|
19
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
20
|
+
fail(context, path, 'symbol-keyed array properties cannot be represented in JSON');
|
|
21
|
+
}
|
|
22
|
+
const propertyNames = Object.getOwnPropertyNames(value);
|
|
23
|
+
const expectedNames = new Set(['length']);
|
|
24
|
+
for (let index = 0; index < value.length; index += 1)
|
|
25
|
+
expectedNames.add(String(index));
|
|
26
|
+
for (const propertyName of propertyNames) {
|
|
27
|
+
if (!expectedNames.has(propertyName)) {
|
|
28
|
+
fail(context, `${path}.${propertyName}`, 'extra array properties cannot be represented in JSON');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (propertyNames.length !== expectedNames.size) {
|
|
32
|
+
fail(context, path, 'sparse arrays cannot be represented faithfully in JSON');
|
|
33
|
+
}
|
|
34
|
+
const lengthDescriptor = Object.getOwnPropertyDescriptor(value, 'length');
|
|
35
|
+
if (!lengthDescriptor
|
|
36
|
+
|| !('value' in lengthDescriptor)
|
|
37
|
+
|| lengthDescriptor.value !== value.length
|
|
38
|
+
|| lengthDescriptor.enumerable
|
|
39
|
+
|| lengthDescriptor.configurable
|
|
40
|
+
|| !lengthDescriptor.writable) {
|
|
41
|
+
fail(context, `${path}.length`, 'non-standard array length descriptors cannot be represented faithfully in JSON');
|
|
42
|
+
}
|
|
43
|
+
const values = [];
|
|
44
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
45
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
46
|
+
if (!descriptor)
|
|
47
|
+
fail(context, `${path}[${index}]`, 'sparse arrays cannot be represented faithfully in JSON');
|
|
48
|
+
if (!('value' in descriptor)
|
|
49
|
+
|| !descriptor.enumerable
|
|
50
|
+
|| !descriptor.configurable
|
|
51
|
+
|| !descriptor.writable) {
|
|
52
|
+
fail(context, `${path}[${index}]`, 'non-standard array item descriptors cannot be represented faithfully in JSON');
|
|
53
|
+
}
|
|
54
|
+
values.push(descriptor.value);
|
|
55
|
+
}
|
|
56
|
+
return values;
|
|
57
|
+
}
|
|
58
|
+
function canonicalJsonValue(value, context, path, seen) {
|
|
59
|
+
if (value === null)
|
|
60
|
+
return 'null';
|
|
61
|
+
if (typeof value === 'string')
|
|
62
|
+
return `string:${JSON.stringify(value)}`;
|
|
63
|
+
if (typeof value === 'boolean')
|
|
64
|
+
return `boolean:${value}`;
|
|
65
|
+
if (typeof value === 'number') {
|
|
66
|
+
if (!Number.isFinite(value))
|
|
67
|
+
fail(context, path, 'must be a finite JSON number');
|
|
68
|
+
if (Object.is(value, -0))
|
|
69
|
+
fail(context, path, 'negative zero cannot be represented faithfully in JSON');
|
|
70
|
+
return `number:${String(value)}`;
|
|
71
|
+
}
|
|
72
|
+
if (value === undefined)
|
|
73
|
+
fail(context, path, 'explicit undefined cannot be represented in JSON');
|
|
74
|
+
if (typeof value === 'function')
|
|
75
|
+
fail(context, path, 'functions cannot be represented in JSON');
|
|
76
|
+
if (typeof value === 'symbol')
|
|
77
|
+
fail(context, path, 'symbols cannot be represented in JSON');
|
|
78
|
+
if (typeof value === 'bigint')
|
|
79
|
+
fail(context, path, 'bigints cannot be represented in JSON');
|
|
80
|
+
markSeen(value, context, path, seen);
|
|
81
|
+
{
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
const items = denseArrayValues(value, context, path)
|
|
84
|
+
.map((item, index) => canonicalJsonValue(item, context, `${path}[${index}]`, seen));
|
|
85
|
+
return `array:[${items.join(',')}]`;
|
|
86
|
+
}
|
|
87
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
88
|
+
fail(context, path, 'must be a plain JSON object (Date and custom instances are not supported)');
|
|
89
|
+
}
|
|
90
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
91
|
+
fail(context, path, 'symbol-keyed properties cannot be represented in JSON');
|
|
92
|
+
}
|
|
93
|
+
const propertyNames = Object.getOwnPropertyNames(value);
|
|
94
|
+
const entries = [];
|
|
95
|
+
for (const key of propertyNames.sort()) {
|
|
96
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
97
|
+
if (!descriptor?.enumerable
|
|
98
|
+
|| !('value' in descriptor)
|
|
99
|
+
|| !descriptor.configurable
|
|
100
|
+
|| !descriptor.writable) {
|
|
101
|
+
fail(context, `${path}.${key}`, 'only enumerable data properties can be represented faithfully in JSON');
|
|
102
|
+
}
|
|
103
|
+
entries.push(`${JSON.stringify(key)}:${canonicalJsonValue(descriptor.value, context, `${path}.${key}`, seen)}`);
|
|
104
|
+
}
|
|
105
|
+
return `object:{${entries.join(',')}}`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function optionalBoolean(value, context, path) {
|
|
109
|
+
if (value === undefined)
|
|
110
|
+
return false;
|
|
111
|
+
if (typeof value !== 'boolean')
|
|
112
|
+
fail(context, path, 'must be a boolean when present');
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Canonical execution-relevant argument schema used by both manifest build and
|
|
117
|
+
* runtime hydration. Objects are key-order independent; arrays remain ordered.
|
|
118
|
+
*/
|
|
119
|
+
export function canonicalizeManifestArgSchema(args, context) {
|
|
120
|
+
if (!Array.isArray(args))
|
|
121
|
+
fail(context, 'args', 'must be a dense array');
|
|
122
|
+
const seen = new Set();
|
|
123
|
+
markSeen(args, context, 'args', seen);
|
|
124
|
+
const argValues = denseArrayValues(args, context, 'args');
|
|
125
|
+
return argValues.map((arg, index) => {
|
|
126
|
+
const argContext = `${context} argument "${String(arg.name)}"`;
|
|
127
|
+
if (typeof arg.name !== 'string' || arg.name.length === 0)
|
|
128
|
+
fail(argContext, 'name', 'must be a non-empty string');
|
|
129
|
+
if (arg.type !== undefined && typeof arg.type !== 'string')
|
|
130
|
+
fail(argContext, 'type', 'must be a string when present');
|
|
131
|
+
if (arg.help !== undefined && typeof arg.help !== 'string')
|
|
132
|
+
fail(argContext, 'help', 'must be a string when present');
|
|
133
|
+
const hasDefault = Object.prototype.hasOwnProperty.call(arg, 'default');
|
|
134
|
+
const defaultValue = hasDefault
|
|
135
|
+
? canonicalJsonValue(arg.default, argContext, 'default', seen)
|
|
136
|
+
: 'missing';
|
|
137
|
+
const hasChoices = Object.prototype.hasOwnProperty.call(arg, 'choices');
|
|
138
|
+
let choices = 'missing';
|
|
139
|
+
if (hasChoices) {
|
|
140
|
+
if (!Array.isArray(arg.choices))
|
|
141
|
+
fail(argContext, 'choices', 'must be an array of strings when present');
|
|
142
|
+
markSeen(arg.choices, argContext, 'choices', seen);
|
|
143
|
+
choices = `array:[${denseArrayValues(arg.choices, argContext, 'choices').map((choice, choiceIndex) => {
|
|
144
|
+
if (typeof choice !== 'string') {
|
|
145
|
+
fail(argContext, `choices[${choiceIndex}]`, 'choice values must be strings');
|
|
146
|
+
}
|
|
147
|
+
return `string:${JSON.stringify(choice)}`;
|
|
148
|
+
}).join(',')}]`;
|
|
149
|
+
}
|
|
150
|
+
return [
|
|
151
|
+
`arg:${index}`,
|
|
152
|
+
`name:${JSON.stringify(arg.name)}`,
|
|
153
|
+
`type:${JSON.stringify(arg.type ?? 'str')}`,
|
|
154
|
+
`default:${defaultValue}`,
|
|
155
|
+
`required:${optionalBoolean(arg.required, argContext, 'required')}`,
|
|
156
|
+
`valueRequired:${optionalBoolean(arg.valueRequired, argContext, 'valueRequired')}`,
|
|
157
|
+
`positional:${optionalBoolean(arg.positional, argContext, 'positional')}`,
|
|
158
|
+
`help:${JSON.stringify(arg.help ?? '')}`,
|
|
159
|
+
`choices:${choices}`,
|
|
160
|
+
].join('|');
|
|
161
|
+
}).join('||');
|
|
162
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -10,7 +10,13 @@ const SENSITIVE_HEADER_NAMES = new Set([
|
|
|
10
10
|
'x-xsrf-token',
|
|
11
11
|
]);
|
|
12
12
|
const SENSITIVE_FIELD_PATTERN = /(password|passwd|pwd|token|secret|authorization|cookie|set-cookie|api[_-]?key|access[_-]?token|refresh[_-]?token|session[_-]?id|csrf|xsrf)/i;
|
|
13
|
-
const SENSITIVE_URL_PARAMS = /([?&])(token|key|secret|password|auth|access_token|api_key|session_id|csrf|xsrf)=[^&]*/gi;
|
|
13
|
+
const SENSITIVE_URL_PARAMS = /([?&])(token|key|secret|fingerprint|password|auth|access_token|api_key|session_id|csrf|xsrf)=[^&]*/gi;
|
|
14
|
+
function hasFingerprintFieldSegment(name) {
|
|
15
|
+
return name
|
|
16
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
17
|
+
.split(/[-_.\s]+/)
|
|
18
|
+
.some((segment) => segment.toLowerCase() === 'fingerprint');
|
|
19
|
+
}
|
|
14
20
|
export function redactUrl(url) {
|
|
15
21
|
return url.replace(SENSITIVE_URL_PARAMS, '$1$2=[REDACTED]');
|
|
16
22
|
}
|
|
@@ -31,8 +37,8 @@ export function redactText(text, opts = {}) {
|
|
|
31
37
|
const max = opts.maxStringLength ?? 50_000;
|
|
32
38
|
let out = text
|
|
33
39
|
.replace(/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi, 'Bearer [REDACTED]')
|
|
34
|
-
.replace(/(["'])(password|passwd|pwd|token|secret|api_key|apikey|access_token|session_id)\1\s*:\s*(["'])(.*?)\3/gi, '$1$2$1:$3[REDACTED]$3')
|
|
35
|
-
.replace(/(token|secret|password|api_key|apikey|access_token|session_id)[=:]\s*['"]?[^'"\s,;}&]+['"]?/gi, '$1=[REDACTED]')
|
|
40
|
+
.replace(/(["'])(password|passwd|pwd|token|secret|fingerprint|api_key|apikey|access_token|session_id)\1\s*:\s*(["'])(.*?)\3/gi, '$1$2$1:$3[REDACTED]$3')
|
|
41
|
+
.replace(/(token|secret|fingerprint|password|api_key|apikey|access_token|session_id)\s*[=:]\s*['"]?[^'"\s,;}&]+['"]?/gi, '$1=[REDACTED]')
|
|
36
42
|
.replace(/(cookie[=:]\s*)[^\n;]{3,}/gi, '$1[REDACTED]')
|
|
37
43
|
.replace(/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g, '[REDACTED_JWT]');
|
|
38
44
|
if (out.length > max)
|
|
@@ -41,7 +47,7 @@ export function redactText(text, opts = {}) {
|
|
|
41
47
|
}
|
|
42
48
|
export function redactValue(value, opts = {}, keyHint, depth = 0) {
|
|
43
49
|
const allow = new Set((opts.allowlist ?? []).map((key) => key.toLowerCase()));
|
|
44
|
-
if (keyHint && SENSITIVE_FIELD_PATTERN.test(keyHint) && !allow.has(keyHint.toLowerCase())) {
|
|
50
|
+
if (keyHint && (SENSITIVE_FIELD_PATTERN.test(keyHint) || hasFingerprintFieldSegment(keyHint)) && !allow.has(keyHint.toLowerCase())) {
|
|
45
51
|
return DEFAULT_REDACTION;
|
|
46
52
|
}
|
|
47
53
|
if (typeof value === 'string') {
|
package/dist/src/plugin.js
CHANGED
|
@@ -1013,13 +1013,16 @@ function getPluginSource(dir) {
|
|
|
1013
1013
|
}
|
|
1014
1014
|
/** Parse a plugin source string into clone URL, repo name, and optional sub-plugin. */
|
|
1015
1015
|
function parseSource(source) {
|
|
1016
|
+
// Strip either the legacy `bycli-plugin-` or the current `opencli-plugin-`
|
|
1017
|
+
// repo-name prefix when deriving the local plugin name.
|
|
1018
|
+
const PLUGIN_NAME_PREFIX = /^(?:bycli|opencli)-plugin-/;
|
|
1016
1019
|
if (source.startsWith('file://')) {
|
|
1017
1020
|
try {
|
|
1018
1021
|
const localPath = path.resolve(fileURLToPath(source));
|
|
1019
1022
|
return {
|
|
1020
1023
|
type: 'local',
|
|
1021
1024
|
localPath,
|
|
1022
|
-
name: path.basename(localPath).replace(
|
|
1025
|
+
name: path.basename(localPath).replace(PLUGIN_NAME_PREFIX, ''),
|
|
1023
1026
|
};
|
|
1024
1027
|
}
|
|
1025
1028
|
catch {
|
|
@@ -1031,14 +1034,14 @@ function parseSource(source) {
|
|
|
1031
1034
|
return {
|
|
1032
1035
|
type: 'local',
|
|
1033
1036
|
localPath,
|
|
1034
|
-
name: path.basename(localPath).replace(
|
|
1037
|
+
name: path.basename(localPath).replace(PLUGIN_NAME_PREFIX, ''),
|
|
1035
1038
|
};
|
|
1036
1039
|
}
|
|
1037
1040
|
// github:user/repo/subplugin (monorepo specific sub-plugin)
|
|
1038
1041
|
const githubSubMatch = source.match(/^github:([\w.-]+)\/([\w.-]+)\/([\w.-]+)$/);
|
|
1039
1042
|
if (githubSubMatch) {
|
|
1040
1043
|
const [, user, repo, sub] = githubSubMatch;
|
|
1041
|
-
const name = repo.replace(
|
|
1044
|
+
const name = repo.replace(PLUGIN_NAME_PREFIX, '');
|
|
1042
1045
|
return {
|
|
1043
1046
|
type: 'git',
|
|
1044
1047
|
cloneUrl: `https://github.com/${user}/${repo}.git`,
|
|
@@ -1050,7 +1053,7 @@ function parseSource(source) {
|
|
|
1050
1053
|
const githubMatch = source.match(/^github:([\w.-]+)\/([\w.-]+)$/);
|
|
1051
1054
|
if (githubMatch) {
|
|
1052
1055
|
const [, user, repo] = githubMatch;
|
|
1053
|
-
const name = repo.replace(
|
|
1056
|
+
const name = repo.replace(PLUGIN_NAME_PREFIX, '');
|
|
1054
1057
|
return {
|
|
1055
1058
|
type: 'git',
|
|
1056
1059
|
cloneUrl: `https://github.com/${user}/${repo}.git`,
|
|
@@ -1061,7 +1064,7 @@ function parseSource(source) {
|
|
|
1061
1064
|
const urlMatch = source.match(/^https?:\/\/github\.com\/([\w.-]+)\/([\w.-]+?)(?:\.git)?$/);
|
|
1062
1065
|
if (urlMatch) {
|
|
1063
1066
|
const [, user, repo] = urlMatch;
|
|
1064
|
-
const name = repo.replace(
|
|
1067
|
+
const name = repo.replace(PLUGIN_NAME_PREFIX, '');
|
|
1065
1068
|
return {
|
|
1066
1069
|
type: 'git',
|
|
1067
1070
|
cloneUrl: `https://github.com/${user}/${repo}.git`,
|
|
@@ -1075,7 +1078,7 @@ function parseSource(source) {
|
|
|
1075
1078
|
const pathPart = sshUrlMatch[1];
|
|
1076
1079
|
const segments = pathPart.split('/');
|
|
1077
1080
|
const repoSegment = segments.pop();
|
|
1078
|
-
const name = repoSegment.replace(
|
|
1081
|
+
const name = repoSegment.replace(PLUGIN_NAME_PREFIX, '');
|
|
1079
1082
|
return { type: 'git', cloneUrl: source, name };
|
|
1080
1083
|
}
|
|
1081
1084
|
// git@host:user/repo.git (SCP-style)
|
|
@@ -1084,7 +1087,7 @@ function parseSource(source) {
|
|
|
1084
1087
|
const pathPart = scpMatch[1];
|
|
1085
1088
|
const segments = pathPart.split('/');
|
|
1086
1089
|
const repoSegment = segments.pop();
|
|
1087
|
-
const name = repoSegment.replace(
|
|
1090
|
+
const name = repoSegment.replace(PLUGIN_NAME_PREFIX, '');
|
|
1088
1091
|
return { type: 'git', cloneUrl: source, name };
|
|
1089
1092
|
}
|
|
1090
1093
|
// Generic https/http git URL (non-GitHub hosts)
|
|
@@ -1093,7 +1096,7 @@ function parseSource(source) {
|
|
|
1093
1096
|
const pathPart = genericHttpMatch[1];
|
|
1094
1097
|
const segments = pathPart.split('/');
|
|
1095
1098
|
const repoSegment = segments.pop();
|
|
1096
|
-
const name = repoSegment.replace(
|
|
1099
|
+
const name = repoSegment.replace(PLUGIN_NAME_PREFIX, '');
|
|
1097
1100
|
// Ensure clone URL ends with .git
|
|
1098
1101
|
const cloneUrl = source.endsWith('.git') ? source : `${source}.git`;
|
|
1099
1102
|
return { type: 'git', cloneUrl, name };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-Level analyze module (M5a, 07-high-level-services.md · analyzeBrowser).
|
|
3
|
+
*
|
|
4
|
+
* Module-first (ADR-0004): drives the Page abstraction through the multi-step
|
|
5
|
+
* site probe (goto / wait / network capture / window-global probe / cookies) to
|
|
6
|
+
* assemble PageSignals, then calls the PURE analyzeSite() classifier. In-process
|
|
7
|
+
* async, no child process (07:50). Hosted by the main-repo daemon high-level
|
|
8
|
+
* surface (Codex A' verdict); dashboard-be only forwards.
|
|
9
|
+
*
|
|
10
|
+
* Timeout surfaces as `analyze_timeout` (07:52), never a runner error.
|
|
11
|
+
*/
|
|
12
|
+
import type { IPage } from '../../types.js';
|
|
13
|
+
import { type AdapterRef, type AnalyzeReport } from '../../browser/analyze.js';
|
|
14
|
+
export interface AnalyzeInput {
|
|
15
|
+
url: string;
|
|
16
|
+
/** site-level settle window after load (ms); default 2000 (07 input). */
|
|
17
|
+
settleMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class AnalyzeTimeoutError extends Error {
|
|
20
|
+
readonly code = "analyze_timeout";
|
|
21
|
+
constructor(ms: number);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Collect PageSignals by driving the page, then classify with the pure analyzeSite.
|
|
25
|
+
* `registry` is the adapter registry used for nearest-adapter matching.
|
|
26
|
+
*/
|
|
27
|
+
export declare function analyzeBrowser(page: IPage, registry: Map<string, AdapterRef>, input: AnalyzeInput): Promise<AnalyzeReport>;
|
|
28
|
+
/** Wrap analyzeBrowser with a deadline → AnalyzeTimeoutError (07:52 analyze_timeout). */
|
|
29
|
+
export declare function analyzeBrowserWithTimeout(page: IPage, registry: Map<string, AdapterRef>, input: AnalyzeInput, timeoutMs: number): Promise<AnalyzeReport>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-Level analyze module (M5a, 07-high-level-services.md · analyzeBrowser).
|
|
3
|
+
*
|
|
4
|
+
* Module-first (ADR-0004): drives the Page abstraction through the multi-step
|
|
5
|
+
* site probe (goto / wait / network capture / window-global probe / cookies) to
|
|
6
|
+
* assemble PageSignals, then calls the PURE analyzeSite() classifier. In-process
|
|
7
|
+
* async, no child process (07:50). Hosted by the main-repo daemon high-level
|
|
8
|
+
* surface (Codex A' verdict); dashboard-be only forwards.
|
|
9
|
+
*
|
|
10
|
+
* Timeout surfaces as `analyze_timeout` (07:52), never a runner error.
|
|
11
|
+
*/
|
|
12
|
+
import { analyzeSite } from '../../browser/analyze.js';
|
|
13
|
+
import { generateInterceptorJs } from '../../interceptor.js';
|
|
14
|
+
export class AnalyzeTimeoutError extends Error {
|
|
15
|
+
code = 'analyze_timeout';
|
|
16
|
+
constructor(ms) {
|
|
17
|
+
super(`analyze timed out after ${ms}ms`);
|
|
18
|
+
this.name = 'AnalyzeTimeoutError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const DEFAULT_SETTLE_MS = 2000;
|
|
22
|
+
/** Window-global + cookie + finalUrl probe (mirrors the CLI analyze probe). */
|
|
23
|
+
const PROBE_JS = `(function(){
|
|
24
|
+
return {
|
|
25
|
+
cookieNames: (document.cookie || '').split(';').map(function(c){ return c.trim().split('=')[0]; }).filter(Boolean),
|
|
26
|
+
initialState: {
|
|
27
|
+
__INITIAL_STATE__: typeof window.__INITIAL_STATE__ !== 'undefined',
|
|
28
|
+
__NUXT__: typeof window.__NUXT__ !== 'undefined',
|
|
29
|
+
__NEXT_DATA__: typeof window.__NEXT_DATA__ !== 'undefined',
|
|
30
|
+
__APOLLO_STATE__: typeof window.__APOLLO_STATE__ !== 'undefined',
|
|
31
|
+
},
|
|
32
|
+
title: document.title || '',
|
|
33
|
+
finalUrl: location.href,
|
|
34
|
+
};
|
|
35
|
+
})()`;
|
|
36
|
+
/**
|
|
37
|
+
* Collect PageSignals by driving the page, then classify with the pure analyzeSite.
|
|
38
|
+
* `registry` is the adapter registry used for nearest-adapter matching.
|
|
39
|
+
*/
|
|
40
|
+
export async function analyzeBrowser(page, registry, input) {
|
|
41
|
+
const settleMs = input.settleMs ?? DEFAULT_SETTLE_MS;
|
|
42
|
+
// Prefer the session-level CDP network capture; fall back to an injected interceptor.
|
|
43
|
+
const hasSessionCapture = (await page.startNetworkCapture?.()) ?? false;
|
|
44
|
+
await page.goto(input.url);
|
|
45
|
+
await page.wait(Math.max(1, Math.round(settleMs / 1000)));
|
|
46
|
+
if (!hasSessionCapture) {
|
|
47
|
+
// match-all: analyze wants every json/text response, not a filtered subset.
|
|
48
|
+
try {
|
|
49
|
+
await page.evaluate(generateInterceptorJs('true'));
|
|
50
|
+
}
|
|
51
|
+
catch { /* non-fatal */ }
|
|
52
|
+
}
|
|
53
|
+
await page.wait(1);
|
|
54
|
+
const rawItems = ((await page.readNetworkCapture?.()) ?? []);
|
|
55
|
+
const networkEntries = rawItems.map((e) => ({
|
|
56
|
+
url: e.url ?? '',
|
|
57
|
+
status: e.status ?? 0,
|
|
58
|
+
contentType: e.ct ?? '',
|
|
59
|
+
bodyPreview: typeof e.body === 'string'
|
|
60
|
+
? e.body.slice(0, 2000)
|
|
61
|
+
: (e.body ? JSON.stringify(e.body).slice(0, 2000) : null),
|
|
62
|
+
}));
|
|
63
|
+
const probe = await page.evaluate(PROBE_JS);
|
|
64
|
+
const browserCookieNames = (await page.getCookies({ url: probe.finalUrl || input.url }).catch(() => []))
|
|
65
|
+
.map((c) => c.name)
|
|
66
|
+
.filter(Boolean);
|
|
67
|
+
const cookieNames = [...new Set([...probe.cookieNames, ...browserCookieNames])];
|
|
68
|
+
const signals = {
|
|
69
|
+
requestedUrl: input.url,
|
|
70
|
+
finalUrl: probe.finalUrl,
|
|
71
|
+
cookieNames,
|
|
72
|
+
networkEntries,
|
|
73
|
+
initialState: probe.initialState,
|
|
74
|
+
title: probe.title,
|
|
75
|
+
};
|
|
76
|
+
return analyzeSite(signals, registry);
|
|
77
|
+
}
|
|
78
|
+
/** Wrap analyzeBrowser with a deadline → AnalyzeTimeoutError (07:52 analyze_timeout). */
|
|
79
|
+
export async function analyzeBrowserWithTimeout(page, registry, input, timeoutMs) {
|
|
80
|
+
let timer;
|
|
81
|
+
const timeout = new Promise((_, reject) => {
|
|
82
|
+
timer = setTimeout(() => reject(new AnalyzeTimeoutError(timeoutMs)), timeoutMs);
|
|
83
|
+
});
|
|
84
|
+
try {
|
|
85
|
+
return await Promise.race([analyzeBrowser(page, registry, input), timeout]);
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
if (timer)
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-Level init module (M5b · createAdapterDraft, 07-high-level-services.md).
|
|
3
|
+
*
|
|
4
|
+
* Hosted main-repo side (Codex A' verdict): FS writes live here, not in dashboard-be.
|
|
5
|
+
* Uses the PURE pieces from @sovovs/bycli-recorder-core (validate/render/provenance/
|
|
6
|
+
* dry-run); this module adds the IO: overwrite/shadow check, write to disk, commit
|
|
7
|
+
* marker, config-snapshot injection.
|
|
8
|
+
*
|
|
9
|
+
* SCOPE (甲 / phase-1): writes report + adapter with an embedded provenance header
|
|
10
|
+
* and a commit marker, so a visible adapter always carries provenance (07 forbids an
|
|
11
|
+
* un-provenanced adapter). The FULL multi-file atomic write transaction (txn manifest
|
|
12
|
+
* + fsync + atomic rename) and the crash-recovery table (07:97-104) are deferred —
|
|
13
|
+
* tracked as M5b follow-up. Until then writes are direct (non-atomic), which is
|
|
14
|
+
* acceptable for a single-user local tool with the provenance+marker guard.
|
|
15
|
+
*/
|
|
16
|
+
import { type DryRunDiff } from '@sovovs/bycli-recorder-core';
|
|
17
|
+
/**
|
|
18
|
+
* High-Level init input (be → daemon /v1/init). Per 03:74 these are the DERIVED draft inputs:
|
|
19
|
+
* be derives `domain`/`strategy` from the selected RankCandidate (the UI-facing Recorder
|
|
20
|
+
* InitRequest is select-only and never carries them). `browser` is normally omitted and
|
|
21
|
+
* derived from `strategy` (COOKIE/UI ⇒ true), matching registry normalizeCommand; pass it
|
|
22
|
+
* only to force a value.
|
|
23
|
+
*/
|
|
24
|
+
export interface InitInput {
|
|
25
|
+
/** site/command */
|
|
26
|
+
name: string;
|
|
27
|
+
/** derived by be from the candidate endpoint host (03:74). */
|
|
28
|
+
domain?: string;
|
|
29
|
+
/** derived by be from the candidate: authRequired ⇒ COOKIE else PUBLIC (03:74). */
|
|
30
|
+
strategy?: 'PUBLIC' | 'COOKIE' | 'UI';
|
|
31
|
+
/** optional explicit override; default is derived from strategy (COOKIE/UI ⇒ true). */
|
|
32
|
+
browser?: boolean;
|
|
33
|
+
/** ADR-0005: required when writePolicy=write. */
|
|
34
|
+
writePolicy?: 'dry-run' | 'write';
|
|
35
|
+
responsibleUseAcknowledgedAt?: number;
|
|
36
|
+
/** LLM 合成产物(MVP):有则填进 adapter 模板留白(func/columns/...);无则空骨架(行为不变)。 */
|
|
37
|
+
funcBody?: string;
|
|
38
|
+
columns?: Array<{
|
|
39
|
+
name: string;
|
|
40
|
+
}>;
|
|
41
|
+
description?: string;
|
|
42
|
+
access?: 'read' | 'write';
|
|
43
|
+
/** 合成所用模型;标进 provenance(@generated-by adapter-recorder-llm + @model)。 */
|
|
44
|
+
llmModel?: string;
|
|
45
|
+
}
|
|
46
|
+
/** Config snapshot injected into every RecorderReport (09). */
|
|
47
|
+
export interface ConfigSnapshot {
|
|
48
|
+
releaseChannel: 'stable' | 'preview';
|
|
49
|
+
localExperimentProfile: 'off' | 'control' | 'candidate';
|
|
50
|
+
configSnapshotVersion: number;
|
|
51
|
+
}
|
|
52
|
+
export interface RecorderReport {
|
|
53
|
+
adapterPath: string;
|
|
54
|
+
reportPath: string;
|
|
55
|
+
warnings: string[];
|
|
56
|
+
responsibleUseAcknowledgedAt: number;
|
|
57
|
+
releaseChannel: string;
|
|
58
|
+
localExperimentProfile: string;
|
|
59
|
+
configSnapshotVersion: number;
|
|
60
|
+
}
|
|
61
|
+
export type InitResult = {
|
|
62
|
+
ok: true;
|
|
63
|
+
report: RecorderReport;
|
|
64
|
+
dryRun: DryRunDiff;
|
|
65
|
+
generatedSource: string;
|
|
66
|
+
} | {
|
|
67
|
+
ok: false;
|
|
68
|
+
errorCode: 'validation_failed' | 'responsible_use_required';
|
|
69
|
+
reason: string;
|
|
70
|
+
};
|
|
71
|
+
/** Transaction manifest persisted under the recorder `.txn` dir (07:99). The crash-recovery
|
|
72
|
+
* sweep (recoverInitTransactions) reads these to resolve interrupted writes. */
|
|
73
|
+
export interface InitTxnManifest {
|
|
74
|
+
txnId: string;
|
|
75
|
+
adapterPath: string;
|
|
76
|
+
reportPath: string;
|
|
77
|
+
markerPath: string;
|
|
78
|
+
adapterSha256: string;
|
|
79
|
+
reportSha256: string;
|
|
80
|
+
state: 'preparing' | 'committed';
|
|
81
|
+
createdAt: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create an adapter draft. With writePolicy 'dry-run' (default) nothing is written —
|
|
85
|
+
* only the diff + intended report is returned. With 'write' it requires
|
|
86
|
+
* responsibleUseAcknowledgedAt (ADR-0005) and writes report + adapter to disk.
|
|
87
|
+
*/
|
|
88
|
+
export declare function createAdapterDraft(input: InitInput, snapshot?: ConfigSnapshot): InitResult;
|
|
89
|
+
export interface SaveAdapterInput {
|
|
90
|
+
/** site/command */
|
|
91
|
+
name: string;
|
|
92
|
+
/** 完整 adapter 源码(已审阅;若无 provenance 头会自动补)。 */
|
|
93
|
+
source: string;
|
|
94
|
+
/** 生成所用模型(标进 provenance)。 */
|
|
95
|
+
llmModel?: string;
|
|
96
|
+
}
|
|
97
|
+
export type SaveAdapterResult = {
|
|
98
|
+
ok: true;
|
|
99
|
+
adapterPath: string;
|
|
100
|
+
reportPath: string;
|
|
101
|
+
} | {
|
|
102
|
+
ok: false;
|
|
103
|
+
errorCode: 'validation_failed';
|
|
104
|
+
reason: string;
|
|
105
|
+
};
|
|
106
|
+
export declare function saveAdapterSource(input: SaveAdapterInput): SaveAdapterResult;
|
|
107
|
+
export interface InitRecoveryResult {
|
|
108
|
+
scanned: number;
|
|
109
|
+
committed: number;
|
|
110
|
+
rolledForward: number;
|
|
111
|
+
rolledBack: number;
|
|
112
|
+
quarantined: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolve init write transactions interrupted by a crash (07:106-117). Scans every
|
|
116
|
+
* ~/.bycli/sites/<site>/recorder/.txn/*.manifest.json, observes the referenced artifacts, and
|
|
117
|
+
* applies decideInitRecovery: write/refresh the marker for a provenance-complete transaction,
|
|
118
|
+
* quarantine an unprovenanced/corrupt adapter, or roll back an empty one. Only manifest paths
|
|
119
|
+
* (and adapters with the provenance header) are touched — unknown user files are never deleted.
|
|
120
|
+
* Designed to run once at daemon startup (extends the verify reap).
|
|
121
|
+
*/
|
|
122
|
+
export declare function recoverInitTransactions(opts?: {
|
|
123
|
+
sitesRoot?: string;
|
|
124
|
+
log?: (msg: string) => void;
|
|
125
|
+
}): InitRecoveryResult;
|