@jackwener/opencli 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/cross-project-adapter-migration/SKILL.md +2 -2
- package/.github/pull_request_template.md +7 -0
- package/.github/workflows/doc-check.yml +36 -0
- package/.github/workflows/docs.yml +7 -42
- package/CHANGELOG.md +23 -0
- package/CLI-EXPLORER.md +9 -8
- package/CONTRIBUTING.md +39 -1
- package/README.md +33 -19
- package/README.zh-CN.md +64 -27
- package/SKILL.md +102 -33
- package/dist/browser/cdp.d.ts +4 -4
- package/dist/browser/cdp.js +45 -17
- package/dist/browser/daemon-client.d.ts +2 -1
- package/dist/browser/dom-helpers.js +38 -7
- package/dist/browser/dom-snapshot.d.ts +86 -0
- package/dist/browser/dom-snapshot.js +729 -0
- package/dist/browser/dom-snapshot.test.d.ts +11 -0
- package/dist/browser/dom-snapshot.test.js +212 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.js +1 -0
- package/dist/browser/page.d.ts +18 -25
- package/dist/browser/page.js +44 -5
- package/dist/build-manifest.d.ts +11 -4
- package/dist/build-manifest.js +79 -34
- package/dist/build-manifest.test.js +58 -2
- package/dist/cli-manifest.json +4273 -1771
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +255 -162
- package/dist/clis/apple-podcasts/commands.test.d.ts +2 -0
- package/dist/clis/apple-podcasts/commands.test.js +76 -0
- package/dist/clis/apple-podcasts/search.js +2 -2
- package/dist/clis/apple-podcasts/top.js +9 -2
- package/dist/clis/arxiv/search.js +1 -1
- package/dist/clis/barchart/greeks.js +1 -1
- package/dist/clis/barchart/options.js +1 -1
- package/dist/clis/barchart/quote.js +1 -1
- package/dist/clis/bilibili/download.js +1 -1
- package/dist/clis/bilibili/dynamic.js +1 -1
- package/dist/clis/bilibili/favorite.js +1 -1
- package/dist/clis/bilibili/feed.js +1 -1
- package/dist/clis/bilibili/following.js +2 -2
- package/dist/clis/bilibili/history.js +1 -1
- package/dist/clis/bilibili/me.js +1 -1
- package/dist/clis/bilibili/ranking.js +1 -1
- package/dist/clis/bilibili/search.js +3 -3
- package/dist/clis/bilibili/subtitle.js +2 -2
- package/dist/clis/bilibili/user-videos.js +2 -2
- package/dist/{bilibili.d.ts → clis/bilibili/utils.d.ts} +1 -1
- package/dist/clis/bloomberg/businessweek.js +17 -0
- package/dist/clis/bloomberg/economics.js +17 -0
- package/dist/clis/bloomberg/feeds.d.ts +1 -0
- package/dist/clis/bloomberg/feeds.js +15 -0
- package/dist/clis/bloomberg/industries.d.ts +1 -0
- package/dist/clis/bloomberg/industries.js +17 -0
- package/dist/clis/bloomberg/main.d.ts +1 -0
- package/dist/clis/bloomberg/main.js +17 -0
- package/dist/clis/bloomberg/markets.d.ts +1 -0
- package/dist/clis/bloomberg/markets.js +17 -0
- package/dist/clis/bloomberg/news.d.ts +1 -0
- package/dist/clis/bloomberg/news.js +105 -0
- package/dist/clis/bloomberg/opinions.d.ts +1 -0
- package/dist/clis/bloomberg/opinions.js +17 -0
- package/dist/clis/bloomberg/politics.d.ts +1 -0
- package/dist/clis/bloomberg/politics.js +17 -0
- package/dist/clis/bloomberg/tech.d.ts +1 -0
- package/dist/clis/bloomberg/tech.js +17 -0
- package/dist/clis/bloomberg/utils.d.ts +34 -0
- package/dist/clis/bloomberg/utils.js +364 -0
- package/dist/clis/bloomberg/utils.test.d.ts +1 -0
- package/dist/clis/bloomberg/utils.test.js +129 -0
- package/dist/clis/boss/batchgreet.js +12 -99
- package/dist/clis/boss/chatlist.js +9 -26
- package/dist/clis/boss/chatmsg.js +11 -42
- package/dist/clis/boss/common.d.ts +92 -0
- package/dist/clis/boss/common.js +223 -0
- package/dist/clis/boss/detail.js +8 -50
- package/dist/clis/boss/exchange.js +13 -79
- package/dist/clis/boss/greet.js +20 -147
- package/dist/clis/boss/invite.js +26 -121
- package/dist/clis/boss/joblist.js +6 -31
- package/dist/clis/boss/mark.js +12 -85
- package/dist/clis/boss/recommend.js +10 -49
- package/dist/clis/boss/resume.js +18 -118
- package/dist/clis/boss/search.js +13 -61
- package/dist/clis/boss/send.js +18 -152
- package/dist/clis/boss/stats.js +20 -71
- package/dist/clis/chaoxing/assignments.js +1 -1
- package/dist/clis/chaoxing/exams.js +1 -1
- package/dist/{chaoxing.d.ts → clis/chaoxing/utils.d.ts} +1 -1
- package/dist/{chaoxing.js → clis/chaoxing/utils.js} +0 -2
- package/dist/clis/chaoxing/utils.test.d.ts +1 -0
- package/dist/{chaoxing.test.js → clis/chaoxing/utils.test.js} +1 -1
- package/dist/clis/chatgpt/read.js +1 -1
- package/dist/clis/chatwise/export.js +1 -1
- package/dist/clis/chatwise/model.js +2 -2
- package/dist/clis/chatwise/screenshot.js +1 -1
- package/dist/clis/codex/export.js +1 -1
- package/dist/clis/codex/model.js +2 -2
- package/dist/clis/codex/screenshot.js +1 -1
- package/dist/clis/coupang/add-to-cart.js +3 -4
- package/dist/clis/coupang/search.js +2 -4
- package/dist/clis/coupang/utils.test.d.ts +1 -0
- package/dist/{coupang.test.js → clis/coupang/utils.test.js} +1 -1
- package/dist/clis/ctrip/search.js +1 -1
- package/dist/clis/cursor/export.js +1 -1
- package/dist/clis/cursor/model.js +2 -2
- package/dist/clis/cursor/screenshot.js +1 -1
- package/dist/clis/devto/tag.yaml +34 -0
- package/dist/clis/devto/top.yaml +29 -0
- package/dist/clis/devto/user.yaml +33 -0
- package/dist/clis/douban/book-hot.d.ts +1 -0
- package/dist/clis/douban/book-hot.js +14 -0
- package/dist/clis/douban/marks.d.ts +1 -0
- package/dist/clis/douban/marks.js +115 -0
- package/dist/clis/douban/movie-hot.d.ts +1 -0
- package/dist/clis/douban/movie-hot.js +14 -0
- package/dist/clis/douban/reviews.d.ts +1 -0
- package/dist/clis/douban/reviews.js +106 -0
- package/dist/clis/douban/search.d.ts +1 -0
- package/dist/clis/douban/search.js +16 -0
- package/dist/clis/douban/shared.d.ts +4 -0
- package/dist/clis/douban/shared.js +155 -0
- package/dist/clis/douban/subject.yaml +76 -0
- package/dist/clis/douban/top250.yaml +70 -0
- package/dist/clis/douban/utils.d.ts +35 -0
- package/dist/clis/douban/utils.js +48 -0
- package/dist/clis/facebook/add-friend.yaml +43 -0
- package/dist/clis/facebook/events.yaml +44 -0
- package/dist/clis/facebook/feed.yaml +63 -0
- package/dist/clis/facebook/friends.yaml +42 -0
- package/dist/clis/facebook/groups.yaml +50 -0
- package/dist/clis/facebook/join-group.yaml +44 -0
- package/dist/clis/facebook/memories.yaml +39 -0
- package/dist/clis/facebook/notifications.yaml +40 -0
- package/dist/clis/facebook/profile.yaml +37 -0
- package/dist/clis/facebook/search.yaml +46 -0
- package/dist/clis/google/news.d.ts +5 -0
- package/dist/clis/google/news.js +58 -0
- package/dist/clis/google/search.d.ts +10 -0
- package/dist/clis/google/search.js +127 -0
- package/dist/clis/google/suggest.d.ts +5 -0
- package/dist/clis/google/suggest.js +34 -0
- package/dist/clis/google/trends.d.ts +5 -0
- package/dist/clis/google/trends.js +38 -0
- package/dist/clis/google/utils.d.ts +9 -0
- package/dist/clis/google/utils.js +23 -0
- package/dist/clis/google/utils.test.d.ts +1 -0
- package/dist/clis/google/utils.test.js +75 -0
- package/dist/clis/grok/ask.d.ts +14 -0
- package/dist/clis/grok/ask.js +257 -65
- package/dist/clis/grok/ask.test.d.ts +1 -0
- package/dist/clis/grok/ask.test.js +36 -0
- package/dist/clis/instagram/comment.yaml +52 -0
- package/dist/clis/instagram/explore.yaml +43 -0
- package/dist/clis/instagram/follow.yaml +41 -0
- package/dist/clis/instagram/followers.yaml +51 -0
- package/dist/clis/instagram/following.yaml +51 -0
- package/dist/clis/instagram/like.yaml +46 -0
- package/dist/clis/instagram/profile.yaml +42 -0
- package/dist/clis/instagram/save.yaml +46 -0
- package/dist/clis/instagram/saved.yaml +40 -0
- package/dist/clis/instagram/search.yaml +43 -0
- package/dist/clis/instagram/unfollow.yaml +38 -0
- package/dist/clis/instagram/unlike.yaml +46 -0
- package/dist/clis/instagram/unsave.yaml +46 -0
- package/dist/clis/instagram/user.yaml +54 -0
- package/dist/clis/jike/comment.js +2 -3
- package/dist/clis/jike/create.js +1 -2
- package/dist/clis/jike/feed.js +0 -1
- package/dist/clis/jike/like.js +1 -2
- package/dist/clis/jike/notifications.js +0 -1
- package/dist/clis/jike/post.yaml +1 -0
- package/dist/clis/jike/repost.js +2 -3
- package/dist/clis/jike/search.js +2 -3
- package/dist/clis/jike/topic.yaml +1 -0
- package/dist/clis/jike/user.yaml +1 -0
- package/dist/clis/jimeng/generate.yaml +1 -0
- package/dist/clis/jimeng/history.yaml +0 -1
- package/dist/clis/linkedin/search.js +7 -7
- package/dist/clis/linux-do/category.yaml +2 -0
- package/dist/clis/linux-do/search.yaml +4 -3
- package/dist/clis/linux-do/topic.yaml +1 -0
- package/dist/clis/lobsters/active.yaml +29 -0
- package/dist/clis/lobsters/hot.yaml +29 -0
- package/dist/clis/lobsters/newest.yaml +29 -0
- package/dist/clis/lobsters/tag.yaml +34 -0
- package/dist/clis/medium/feed.d.ts +1 -0
- package/dist/clis/medium/feed.js +15 -0
- package/dist/clis/medium/search.d.ts +1 -0
- package/dist/clis/medium/search.js +15 -0
- package/dist/clis/medium/shared.d.ts +5 -0
- package/dist/clis/medium/shared.js +78 -0
- package/dist/clis/medium/user.d.ts +1 -0
- package/dist/clis/medium/user.js +15 -0
- package/dist/clis/notion/export.js +1 -1
- package/dist/clis/reddit/comment.js +3 -4
- package/dist/clis/reddit/read.js +4 -5
- package/dist/clis/reddit/save.js +2 -3
- package/dist/clis/reddit/saved.js +0 -1
- package/dist/clis/reddit/search.yaml +1 -0
- package/dist/clis/reddit/subreddit.yaml +1 -0
- package/dist/clis/reddit/subscribe.js +1 -2
- package/dist/clis/reddit/upvote.js +2 -3
- package/dist/clis/reddit/upvoted.js +0 -1
- package/dist/clis/reddit/user-comments.yaml +1 -0
- package/dist/clis/reddit/user-posts.yaml +1 -0
- package/dist/clis/reddit/user.yaml +1 -0
- package/dist/clis/reuters/search.js +1 -1
- package/dist/clis/sinablog/article.d.ts +1 -0
- package/dist/clis/sinablog/article.js +14 -0
- package/dist/clis/sinablog/hot.d.ts +1 -0
- package/dist/clis/sinablog/hot.js +14 -0
- package/dist/clis/sinablog/search.d.ts +1 -0
- package/dist/clis/sinablog/search.js +51 -0
- package/dist/clis/sinablog/shared.d.ts +7 -0
- package/dist/clis/sinablog/shared.js +187 -0
- package/dist/clis/sinablog/user.d.ts +1 -0
- package/dist/clis/sinablog/user.js +15 -0
- package/dist/clis/smzdm/search.js +2 -3
- package/dist/clis/stackoverflow/search.yaml +1 -0
- package/dist/clis/steam/top-sellers.yaml +29 -0
- package/dist/clis/substack/feed.d.ts +1 -0
- package/dist/clis/substack/feed.js +15 -0
- package/dist/clis/substack/publication.d.ts +1 -0
- package/dist/clis/substack/publication.js +15 -0
- package/dist/clis/substack/search.d.ts +1 -0
- package/dist/clis/substack/search.js +77 -0
- package/dist/clis/substack/shared.d.ts +4 -0
- package/dist/clis/substack/shared.js +129 -0
- package/dist/clis/tiktok/comment.yaml +66 -0
- package/dist/clis/tiktok/explore.yaml +39 -0
- package/dist/clis/tiktok/follow.yaml +39 -0
- package/dist/clis/tiktok/following.yaml +46 -0
- package/dist/clis/tiktok/friends.yaml +47 -0
- package/dist/clis/tiktok/like.yaml +38 -0
- package/dist/clis/tiktok/live.yaml +51 -0
- package/dist/clis/tiktok/notifications.yaml +52 -0
- package/dist/clis/tiktok/profile.yaml +45 -0
- package/dist/clis/tiktok/save.yaml +34 -0
- package/dist/clis/tiktok/search.yaml +46 -0
- package/dist/clis/tiktok/unfollow.yaml +44 -0
- package/dist/clis/tiktok/unlike.yaml +38 -0
- package/dist/clis/tiktok/unsave.yaml +36 -0
- package/dist/clis/tiktok/user.yaml +44 -0
- package/dist/clis/twitter/accept.js +2 -2
- package/dist/clis/twitter/article.js +2 -2
- package/dist/clis/twitter/block.d.ts +1 -0
- package/dist/clis/twitter/block.js +88 -0
- package/dist/clis/twitter/delete.js +1 -1
- package/dist/clis/twitter/download.d.ts +1 -1
- package/dist/clis/twitter/download.js +3 -3
- package/dist/clis/twitter/followers.js +1 -1
- package/dist/clis/twitter/following.js +1 -1
- package/dist/clis/twitter/hide-reply.d.ts +1 -0
- package/dist/clis/twitter/hide-reply.js +66 -0
- package/dist/clis/twitter/like.js +1 -1
- package/dist/clis/twitter/post.js +1 -1
- package/dist/clis/twitter/reply-dm.js +1 -1
- package/dist/clis/twitter/reply.js +2 -2
- package/dist/clis/twitter/search.js +1 -1
- package/dist/clis/twitter/thread.js +2 -2
- package/dist/clis/twitter/timeline.d.ts +23 -0
- package/dist/clis/twitter/timeline.js +42 -14
- package/dist/clis/twitter/timeline.test.d.ts +1 -0
- package/dist/clis/twitter/timeline.test.js +102 -0
- package/dist/clis/twitter/trending.d.ts +1 -0
- package/dist/clis/twitter/trending.js +91 -0
- package/dist/clis/twitter/unblock.d.ts +1 -0
- package/dist/clis/twitter/unblock.js +71 -0
- package/dist/clis/v2ex/topic.yaml +1 -0
- package/dist/clis/weibo/hot.js +0 -1
- package/dist/clis/weread/book.js +1 -1
- package/dist/clis/weread/highlights.js +1 -1
- package/dist/clis/weread/notes.js +1 -1
- package/dist/clis/weread/search.js +1 -1
- package/dist/clis/wikipedia/random.d.ts +1 -0
- package/dist/clis/wikipedia/random.js +19 -0
- package/dist/clis/wikipedia/search.js +4 -4
- package/dist/clis/wikipedia/summary.js +4 -9
- package/dist/clis/wikipedia/trending.d.ts +1 -0
- package/dist/clis/wikipedia/trending.js +35 -0
- package/dist/clis/wikipedia/utils.d.ts +28 -0
- package/dist/clis/wikipedia/utils.js +13 -0
- package/dist/clis/xiaohongshu/creator-note-detail.d.ts +15 -0
- package/dist/clis/xiaohongshu/creator-note-detail.js +69 -5
- package/dist/clis/xiaohongshu/creator-note-detail.test.js +82 -33
- package/dist/clis/xiaohongshu/creator-notes.js +35 -5
- package/dist/clis/xiaohongshu/creator-notes.test.js +37 -6
- package/dist/clis/xiaohongshu/creator-profile.js +0 -1
- package/dist/clis/xiaohongshu/creator-stats.js +0 -1
- package/dist/clis/xiaohongshu/download.js +2 -3
- package/dist/clis/xiaohongshu/feed.yaml +0 -1
- package/dist/clis/xiaohongshu/notifications.yaml +0 -1
- package/dist/clis/xiaohongshu/search.js +2 -2
- package/dist/clis/xiaohongshu/user.js +1 -2
- package/dist/clis/xueqiu/earnings-date.yaml +69 -0
- package/dist/clis/xueqiu/search.yaml +2 -1
- package/dist/clis/xueqiu/stock.yaml +2 -0
- package/dist/clis/yahoo-finance/quote.js +1 -2
- package/dist/clis/youtube/search.js +1 -1
- package/dist/clis/youtube/transcript.js +1 -1
- package/dist/clis/youtube/video.js +1 -1
- package/dist/clis/zhihu/download.js +1 -2
- package/dist/clis/zhihu/question.js +1 -1
- package/dist/clis/zhihu/search.yaml +4 -3
- package/dist/commanderAdapter.d.ts +21 -0
- package/dist/commanderAdapter.js +117 -0
- package/dist/{engine.d.ts → discovery.d.ts} +6 -4
- package/dist/{engine.js → discovery.js} +93 -104
- package/dist/doctor.js +3 -1
- package/dist/doctor.test.js +46 -2
- package/dist/download/index.d.ts +2 -6
- package/dist/download/index.js +19 -46
- package/dist/engine.test.d.ts +0 -3
- package/dist/engine.test.js +80 -11
- package/dist/execution.d.ts +24 -0
- package/dist/execution.js +153 -0
- package/dist/explore.d.ts +76 -3
- package/dist/explore.js +132 -111
- package/dist/external-clis.yaml +48 -0
- package/dist/external.d.ts +7 -2
- package/dist/external.js +11 -14
- package/dist/generate.d.ts +41 -2
- package/dist/generate.js +5 -4
- package/dist/main.js +2 -1
- package/dist/pipeline/executor.d.ts +2 -2
- package/dist/pipeline/executor.js +2 -2
- package/dist/pipeline/executor.test.js +33 -6
- package/dist/pipeline/registry.d.ts +1 -1
- package/dist/pipeline/steps/browser.d.ts +7 -7
- package/dist/pipeline/steps/browser.js +21 -7
- package/dist/pipeline/steps/fetch.d.ts +1 -1
- package/dist/pipeline/steps/fetch.js +11 -7
- package/dist/pipeline/steps/transform.d.ts +6 -5
- package/dist/pipeline/steps/transform.js +30 -9
- package/dist/pipeline/template.d.ts +6 -6
- package/dist/pipeline/template.js +43 -5
- package/dist/pipeline/template.test.js +18 -0
- package/dist/pipeline/transform.test.js +11 -0
- package/dist/plugin.d.ts +31 -0
- package/dist/plugin.js +216 -0
- package/dist/plugin.test.d.ts +4 -0
- package/dist/plugin.test.js +76 -0
- package/dist/registry-api.d.ts +11 -0
- package/dist/registry-api.js +9 -0
- package/dist/registry.d.ts +13 -0
- package/dist/registry.js +8 -1
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.js +8 -0
- package/dist/serialization.d.ts +34 -0
- package/dist/serialization.js +63 -0
- package/dist/synthesize.d.ts +94 -4
- package/dist/synthesize.js +5 -4
- package/dist/types.d.ts +43 -27
- package/dist/validate.js +8 -2
- package/docs/.vitepress/config.mts +20 -7
- package/docs/adapters/browser/arxiv.md +27 -0
- package/docs/adapters/browser/barchart.md +33 -0
- package/docs/adapters/browser/bilibili.md +9 -0
- package/docs/adapters/browser/bloomberg.md +70 -0
- package/docs/adapters/browser/chaoxing.md +39 -0
- package/docs/adapters/browser/devto.md +35 -0
- package/docs/adapters/browser/douban.md +38 -0
- package/docs/adapters/browser/facebook.md +36 -0
- package/docs/adapters/browser/google.md +62 -0
- package/docs/adapters/browser/grok.md +53 -0
- package/docs/adapters/browser/hf.md +42 -0
- package/docs/adapters/browser/instagram.md +46 -0
- package/docs/adapters/browser/jike.md +45 -0
- package/docs/adapters/browser/jimeng.md +39 -0
- package/docs/adapters/browser/linux-do.md +45 -0
- package/docs/adapters/browser/lobsters.md +32 -0
- package/docs/adapters/browser/medium.md +32 -0
- package/docs/adapters/browser/reddit.md +9 -0
- package/docs/adapters/browser/sinablog.md +36 -0
- package/docs/adapters/browser/sinafinance.md +35 -0
- package/docs/adapters/browser/stackoverflow.md +35 -0
- package/docs/adapters/browser/steam.md +26 -0
- package/docs/adapters/browser/substack.md +38 -0
- package/docs/adapters/browser/tiktok.md +68 -0
- package/docs/adapters/browser/twitter.md +3 -0
- package/docs/adapters/browser/weread.md +48 -0
- package/docs/adapters/browser/wikipedia.md +39 -0
- package/docs/adapters/browser/xiaohongshu.md +5 -1
- package/docs/adapters/browser/xueqiu.md +10 -0
- package/docs/adapters/browser/yahoo-finance.md +6 -5
- package/docs/adapters/desktop/antigravity.md +6 -0
- package/docs/adapters/desktop/chatgpt.md +5 -4
- package/docs/adapters/desktop/codex.md +5 -1
- package/docs/adapters/desktop/cursor.md +4 -0
- package/docs/adapters/desktop/discord.md +7 -7
- package/docs/adapters/index.md +14 -4
- package/docs/advanced/download.md +4 -4
- package/docs/developer/architecture.md +17 -4
- package/docs/guide/getting-started.md +1 -0
- package/docs/guide/plugins.md +153 -0
- package/docs/zh/guide/plugins.md +107 -0
- package/extension/src/background.ts +18 -11
- package/package.json +10 -5
- package/scripts/check-doc-coverage.sh +69 -0
- package/scripts/clean-dist.cjs +13 -0
- package/scripts/copy-yaml.cjs +7 -0
- package/src/browser/cdp.ts +77 -32
- package/src/browser/daemon-client.ts +2 -1
- package/src/browser/dom-helpers.ts +38 -7
- package/src/browser/dom-snapshot.test.ts +249 -0
- package/src/browser/dom-snapshot.ts +770 -0
- package/src/browser/index.ts +2 -0
- package/src/browser/page.ts +57 -20
- package/src/build-manifest.test.ts +70 -2
- package/src/build-manifest.ts +114 -40
- package/src/cli.ts +287 -139
- package/src/clis/apple-podcasts/commands.test.ts +95 -0
- package/src/clis/apple-podcasts/search.ts +2 -2
- package/src/clis/apple-podcasts/top.ts +12 -2
- package/src/clis/arxiv/search.ts +1 -1
- package/src/clis/barchart/greeks.ts +1 -1
- package/src/clis/barchart/options.ts +1 -1
- package/src/clis/barchart/quote.ts +1 -1
- package/src/clis/bilibili/download.ts +1 -1
- package/src/clis/bilibili/dynamic.ts +1 -1
- package/src/clis/bilibili/favorite.ts +1 -1
- package/src/clis/bilibili/feed.ts +1 -1
- package/src/clis/bilibili/following.ts +2 -2
- package/src/clis/bilibili/history.ts +1 -1
- package/src/clis/bilibili/me.ts +1 -1
- package/src/clis/bilibili/ranking.ts +1 -1
- package/src/clis/bilibili/search.ts +3 -3
- package/src/clis/bilibili/subtitle.ts +2 -2
- package/src/clis/bilibili/user-videos.ts +2 -2
- package/src/{bilibili.ts → clis/bilibili/utils.ts} +1 -1
- package/src/clis/bloomberg/businessweek.ts +18 -0
- package/src/clis/bloomberg/economics.ts +18 -0
- package/src/clis/bloomberg/feeds.ts +16 -0
- package/src/clis/bloomberg/industries.ts +18 -0
- package/src/clis/bloomberg/main.ts +18 -0
- package/src/clis/bloomberg/markets.ts +18 -0
- package/src/clis/bloomberg/news.ts +136 -0
- package/src/clis/bloomberg/opinions.ts +18 -0
- package/src/clis/bloomberg/politics.ts +18 -0
- package/src/clis/bloomberg/tech.ts +18 -0
- package/src/clis/bloomberg/utils.test.ts +135 -0
- package/src/clis/bloomberg/utils.ts +429 -0
- package/src/clis/boss/batchgreet.ts +16 -108
- package/src/clis/boss/chatlist.ts +13 -27
- package/src/clis/boss/chatmsg.ts +16 -40
- package/src/clis/boss/common.ts +287 -0
- package/src/clis/boss/detail.ts +9 -55
- package/src/clis/boss/exchange.ts +15 -89
- package/src/clis/boss/greet.ts +25 -162
- package/src/clis/boss/invite.ts +36 -133
- package/src/clis/boss/joblist.ts +7 -36
- package/src/clis/boss/mark.ts +13 -94
- package/src/clis/boss/recommend.ts +12 -57
- package/src/clis/boss/resume.ts +19 -124
- package/src/clis/boss/search.ts +14 -67
- package/src/clis/boss/send.ts +22 -162
- package/src/clis/boss/stats.ts +21 -76
- package/src/clis/chaoxing/assignments.ts +1 -1
- package/src/clis/chaoxing/exams.ts +1 -1
- package/src/{chaoxing.test.ts → clis/chaoxing/utils.test.ts} +1 -1
- package/src/{chaoxing.ts → clis/chaoxing/utils.ts} +1 -3
- package/src/clis/chatgpt/read.ts +1 -1
- package/src/clis/chatwise/export.ts +1 -1
- package/src/clis/chatwise/model.ts +2 -2
- package/src/clis/chatwise/screenshot.ts +1 -1
- package/src/clis/codex/export.ts +1 -1
- package/src/clis/codex/model.ts +2 -2
- package/src/clis/codex/screenshot.ts +1 -1
- package/src/clis/coupang/add-to-cart.ts +3 -4
- package/src/clis/coupang/search.ts +2 -4
- package/src/{coupang.test.ts → clis/coupang/utils.test.ts} +1 -1
- package/src/clis/ctrip/search.ts +1 -1
- package/src/clis/cursor/export.ts +1 -1
- package/src/clis/cursor/model.ts +2 -2
- package/src/clis/cursor/screenshot.ts +1 -1
- package/src/clis/devto/tag.yaml +34 -0
- package/src/clis/devto/top.yaml +29 -0
- package/src/clis/devto/user.yaml +33 -0
- package/src/clis/douban/book-hot.ts +15 -0
- package/src/clis/douban/marks.ts +135 -0
- package/src/clis/douban/movie-hot.ts +15 -0
- package/src/clis/douban/reviews.ts +127 -0
- package/src/clis/douban/search.ts +17 -0
- package/src/clis/douban/shared.ts +165 -0
- package/src/clis/douban/subject.yaml +76 -0
- package/src/clis/douban/top250.yaml +70 -0
- package/src/clis/douban/utils.ts +81 -0
- package/src/clis/facebook/add-friend.yaml +43 -0
- package/src/clis/facebook/events.yaml +44 -0
- package/src/clis/facebook/feed.yaml +63 -0
- package/src/clis/facebook/friends.yaml +42 -0
- package/src/clis/facebook/groups.yaml +50 -0
- package/src/clis/facebook/join-group.yaml +44 -0
- package/src/clis/facebook/memories.yaml +39 -0
- package/src/clis/facebook/notifications.yaml +40 -0
- package/src/clis/facebook/profile.yaml +37 -0
- package/src/clis/facebook/search.yaml +46 -0
- package/src/clis/google/news.ts +66 -0
- package/src/clis/google/search.ts +133 -0
- package/src/clis/google/suggest.ts +40 -0
- package/src/clis/google/trends.ts +44 -0
- package/src/clis/google/utils.test.ts +82 -0
- package/src/clis/google/utils.ts +24 -0
- package/src/clis/grok/ask.test.ts +53 -0
- package/src/clis/grok/ask.ts +300 -69
- package/src/clis/instagram/comment.yaml +52 -0
- package/src/clis/instagram/explore.yaml +43 -0
- package/src/clis/instagram/follow.yaml +41 -0
- package/src/clis/instagram/followers.yaml +51 -0
- package/src/clis/instagram/following.yaml +51 -0
- package/src/clis/instagram/like.yaml +46 -0
- package/src/clis/instagram/profile.yaml +42 -0
- package/src/clis/instagram/save.yaml +46 -0
- package/src/clis/instagram/saved.yaml +40 -0
- package/src/clis/instagram/search.yaml +43 -0
- package/src/clis/instagram/unfollow.yaml +38 -0
- package/src/clis/instagram/unlike.yaml +46 -0
- package/src/clis/instagram/unsave.yaml +46 -0
- package/src/clis/instagram/user.yaml +54 -0
- package/src/clis/jike/comment.ts +2 -3
- package/src/clis/jike/create.ts +1 -2
- package/src/clis/jike/feed.ts +0 -1
- package/src/clis/jike/like.ts +1 -2
- package/src/clis/jike/notifications.ts +0 -1
- package/src/clis/jike/post.yaml +1 -0
- package/src/clis/jike/repost.ts +2 -3
- package/src/clis/jike/search.ts +2 -3
- package/src/clis/jike/topic.yaml +1 -0
- package/src/clis/jike/user.yaml +1 -0
- package/src/clis/jimeng/generate.yaml +1 -0
- package/src/clis/jimeng/history.yaml +0 -1
- package/src/clis/linkedin/search.ts +7 -7
- package/src/clis/linux-do/category.yaml +2 -0
- package/src/clis/linux-do/search.yaml +4 -3
- package/src/clis/linux-do/topic.yaml +1 -0
- package/src/clis/lobsters/active.yaml +29 -0
- package/src/clis/lobsters/hot.yaml +29 -0
- package/src/clis/lobsters/newest.yaml +29 -0
- package/src/clis/lobsters/tag.yaml +34 -0
- package/src/clis/medium/feed.ts +16 -0
- package/src/clis/medium/search.ts +16 -0
- package/src/clis/medium/shared.ts +83 -0
- package/src/clis/medium/user.ts +16 -0
- package/src/clis/notion/export.ts +1 -1
- package/src/clis/reddit/comment.ts +3 -4
- package/src/clis/reddit/read.ts +4 -5
- package/src/clis/reddit/save.ts +2 -3
- package/src/clis/reddit/saved.ts +0 -1
- package/src/clis/reddit/search.yaml +1 -0
- package/src/clis/reddit/subreddit.yaml +1 -0
- package/src/clis/reddit/subscribe.ts +1 -2
- package/src/clis/reddit/upvote.ts +2 -3
- package/src/clis/reddit/upvoted.ts +0 -1
- package/src/clis/reddit/user-comments.yaml +1 -0
- package/src/clis/reddit/user-posts.yaml +1 -0
- package/src/clis/reddit/user.yaml +1 -0
- package/src/clis/reuters/search.ts +1 -1
- package/src/clis/sinablog/article.ts +15 -0
- package/src/clis/sinablog/hot.ts +15 -0
- package/src/clis/sinablog/search.ts +56 -0
- package/src/clis/sinablog/shared.ts +198 -0
- package/src/clis/sinablog/user.ts +16 -0
- package/src/clis/smzdm/search.ts +2 -3
- package/src/clis/stackoverflow/search.yaml +1 -0
- package/src/clis/steam/top-sellers.yaml +29 -0
- package/src/clis/substack/feed.ts +16 -0
- package/src/clis/substack/publication.ts +16 -0
- package/src/clis/substack/search.ts +91 -0
- package/src/clis/substack/shared.ts +132 -0
- package/src/clis/tiktok/comment.yaml +66 -0
- package/src/clis/tiktok/explore.yaml +39 -0
- package/src/clis/tiktok/follow.yaml +39 -0
- package/src/clis/tiktok/following.yaml +46 -0
- package/src/clis/tiktok/friends.yaml +47 -0
- package/src/clis/tiktok/like.yaml +38 -0
- package/src/clis/tiktok/live.yaml +51 -0
- package/src/clis/tiktok/notifications.yaml +52 -0
- package/src/clis/tiktok/profile.yaml +45 -0
- package/src/clis/tiktok/save.yaml +34 -0
- package/src/clis/tiktok/search.yaml +46 -0
- package/src/clis/tiktok/unfollow.yaml +44 -0
- package/src/clis/tiktok/unlike.yaml +38 -0
- package/src/clis/tiktok/unsave.yaml +36 -0
- package/src/clis/tiktok/user.yaml +44 -0
- package/src/clis/twitter/accept.ts +2 -2
- package/src/clis/twitter/article.ts +2 -2
- package/src/clis/twitter/block.ts +92 -0
- package/src/clis/twitter/delete.ts +1 -1
- package/src/clis/twitter/download.ts +3 -3
- package/src/clis/twitter/followers.ts +1 -1
- package/src/clis/twitter/following.ts +1 -1
- package/src/clis/twitter/hide-reply.ts +70 -0
- package/src/clis/twitter/like.ts +1 -1
- package/src/clis/twitter/post.ts +1 -1
- package/src/clis/twitter/reply-dm.ts +1 -1
- package/src/clis/twitter/reply.ts +2 -2
- package/src/clis/twitter/search.ts +1 -1
- package/src/clis/twitter/thread.ts +2 -2
- package/src/clis/twitter/timeline.test.ts +109 -0
- package/src/clis/twitter/timeline.ts +59 -19
- package/src/clis/twitter/trending.ts +113 -0
- package/src/clis/twitter/unblock.ts +75 -0
- package/src/clis/v2ex/topic.yaml +1 -0
- package/src/clis/weibo/hot.ts +0 -1
- package/src/clis/weread/book.ts +1 -1
- package/src/clis/weread/highlights.ts +1 -1
- package/src/clis/weread/notes.ts +1 -1
- package/src/clis/weread/search.ts +1 -1
- package/src/clis/wikipedia/random.ts +19 -0
- package/src/clis/wikipedia/search.ts +11 -5
- package/src/clis/wikipedia/summary.ts +4 -9
- package/src/clis/wikipedia/trending.ts +41 -0
- package/src/clis/wikipedia/utils.ts +31 -0
- package/src/clis/xiaohongshu/creator-note-detail.test.ts +84 -33
- package/src/clis/xiaohongshu/creator-note-detail.ts +89 -5
- package/src/clis/xiaohongshu/creator-notes.test.ts +41 -6
- package/src/clis/xiaohongshu/creator-notes.ts +44 -5
- package/src/clis/xiaohongshu/creator-profile.ts +0 -1
- package/src/clis/xiaohongshu/creator-stats.ts +0 -1
- package/src/clis/xiaohongshu/download.ts +2 -3
- package/src/clis/xiaohongshu/feed.yaml +0 -1
- package/src/clis/xiaohongshu/notifications.yaml +0 -1
- package/src/clis/xiaohongshu/search.ts +2 -2
- package/src/clis/xiaohongshu/user.ts +1 -2
- package/src/clis/xueqiu/earnings-date.yaml +69 -0
- package/src/clis/xueqiu/search.yaml +2 -1
- package/src/clis/xueqiu/stock.yaml +2 -0
- package/src/clis/yahoo-finance/quote.ts +1 -2
- package/src/clis/youtube/search.ts +1 -1
- package/src/clis/youtube/transcript.ts +1 -1
- package/src/clis/youtube/video.ts +1 -1
- package/src/clis/zhihu/download.ts +1 -2
- package/src/clis/zhihu/question.ts +1 -1
- package/src/clis/zhihu/search.yaml +4 -3
- package/src/commanderAdapter.ts +120 -0
- package/src/discovery.ts +277 -0
- package/src/doctor.test.ts +59 -2
- package/src/doctor.ts +4 -2
- package/src/download/index.ts +21 -54
- package/src/engine.test.ts +85 -11
- package/src/execution.ts +164 -0
- package/src/explore.ts +211 -117
- package/src/external-clis.yaml +9 -0
- package/src/external.ts +15 -12
- package/src/generate.ts +58 -9
- package/src/main.ts +2 -1
- package/src/pipeline/executor.test.ts +35 -6
- package/src/pipeline/executor.ts +11 -7
- package/src/pipeline/registry.ts +3 -3
- package/src/pipeline/steps/browser.ts +29 -15
- package/src/pipeline/steps/fetch.ts +18 -13
- package/src/pipeline/steps/transform.ts +40 -15
- package/src/pipeline/template.test.ts +18 -0
- package/src/pipeline/template.ts +86 -13
- package/src/pipeline/transform.test.ts +15 -2
- package/src/plugin.test.ts +86 -0
- package/src/plugin.ts +254 -0
- package/src/registry-api.ts +12 -0
- package/src/registry.ts +24 -1
- package/src/runtime.ts +9 -0
- package/src/serialization.ts +79 -0
- package/src/synthesize.ts +102 -21
- package/src/types.ts +45 -13
- package/src/validate.ts +19 -4
- package/tests/e2e/browser-public.test.ts +36 -0
- package/tests/e2e/public-commands.test.ts +119 -1
- package/dist/clis/feishu/new.d.ts +0 -1
- package/dist/clis/feishu/new.js +0 -27
- package/dist/clis/feishu/read.d.ts +0 -1
- package/dist/clis/feishu/read.js +0 -40
- package/dist/clis/feishu/search.d.ts +0 -1
- package/dist/clis/feishu/search.js +0 -30
- package/dist/clis/feishu/send.d.ts +0 -1
- package/dist/clis/feishu/send.js +0 -39
- package/dist/clis/feishu/status.d.ts +0 -1
- package/dist/clis/feishu/status.js +0 -28
- package/dist/clis/neteasemusic/like.d.ts +0 -1
- package/dist/clis/neteasemusic/like.js +0 -25
- package/dist/clis/neteasemusic/lyrics.d.ts +0 -1
- package/dist/clis/neteasemusic/lyrics.js +0 -47
- package/dist/clis/neteasemusic/next.d.ts +0 -1
- package/dist/clis/neteasemusic/next.js +0 -26
- package/dist/clis/neteasemusic/play.d.ts +0 -1
- package/dist/clis/neteasemusic/play.js +0 -26
- package/dist/clis/neteasemusic/playing.d.ts +0 -1
- package/dist/clis/neteasemusic/playing.js +0 -59
- package/dist/clis/neteasemusic/playlist.d.ts +0 -1
- package/dist/clis/neteasemusic/playlist.js +0 -46
- package/dist/clis/neteasemusic/prev.d.ts +0 -1
- package/dist/clis/neteasemusic/prev.js +0 -25
- package/dist/clis/neteasemusic/search.d.ts +0 -1
- package/dist/clis/neteasemusic/search.js +0 -52
- package/dist/clis/neteasemusic/status.d.ts +0 -1
- package/dist/clis/neteasemusic/status.js +0 -16
- package/dist/clis/neteasemusic/volume.d.ts +0 -1
- package/dist/clis/neteasemusic/volume.js +0 -54
- package/dist/clis/twitter/trending.yaml +0 -46
- package/dist/clis/wechat/chats.d.ts +0 -1
- package/dist/clis/wechat/chats.js +0 -28
- package/dist/clis/wechat/contacts.d.ts +0 -1
- package/dist/clis/wechat/contacts.js +0 -28
- package/dist/clis/wechat/read.d.ts +0 -1
- package/dist/clis/wechat/read.js +0 -58
- package/dist/clis/wechat/search.d.ts +0 -1
- package/dist/clis/wechat/search.js +0 -31
- package/dist/clis/wechat/send.d.ts +0 -1
- package/dist/clis/wechat/send.js +0 -42
- package/dist/clis/wechat/status.d.ts +0 -1
- package/dist/clis/wechat/status.js +0 -29
- package/dist/pipeline.d.ts +0 -7
- package/dist/pipeline.js +0 -7
- package/docs/adapters/browser/github.md +0 -26
- package/docs/adapters/desktop/feishu.md +0 -20
- package/docs/adapters/desktop/neteasemusic.md +0 -31
- package/docs/adapters/desktop/wechat.md +0 -28
- package/docs/public/CNAME +0 -1
- package/src/clis/antigravity/README.md +0 -5
- package/src/clis/antigravity/README.zh-CN.md +0 -51
- package/src/clis/chaoxing/README.md +0 -14
- package/src/clis/chaoxing/README.zh-CN.md +0 -35
- package/src/clis/chatgpt/README.md +0 -5
- package/src/clis/chatgpt/README.zh-CN.md +0 -44
- package/src/clis/chatwise/README.md +0 -5
- package/src/clis/chatwise/README.zh-CN.md +0 -38
- package/src/clis/codex/README.md +0 -5
- package/src/clis/codex/README.zh-CN.md +0 -33
- package/src/clis/cursor/README.md +0 -5
- package/src/clis/cursor/README.zh-CN.md +0 -33
- package/src/clis/discord-app/README.md +0 -5
- package/src/clis/discord-app/README.zh-CN.md +0 -28
- package/src/clis/feishu/README.md +0 -5
- package/src/clis/feishu/README.zh-CN.md +0 -20
- package/src/clis/feishu/new.ts +0 -32
- package/src/clis/feishu/read.ts +0 -48
- package/src/clis/feishu/search.ts +0 -35
- package/src/clis/feishu/send.ts +0 -46
- package/src/clis/feishu/status.ts +0 -34
- package/src/clis/neteasemusic/README.md +0 -5
- package/src/clis/neteasemusic/README.zh-CN.md +0 -31
- package/src/clis/neteasemusic/like.ts +0 -28
- package/src/clis/neteasemusic/lyrics.ts +0 -53
- package/src/clis/neteasemusic/next.ts +0 -30
- package/src/clis/neteasemusic/play.ts +0 -30
- package/src/clis/neteasemusic/playing.ts +0 -62
- package/src/clis/neteasemusic/playlist.ts +0 -51
- package/src/clis/neteasemusic/prev.ts +0 -29
- package/src/clis/neteasemusic/search.ts +0 -58
- package/src/clis/neteasemusic/status.ts +0 -18
- package/src/clis/neteasemusic/volume.ts +0 -61
- package/src/clis/notion/README.md +0 -5
- package/src/clis/notion/README.zh-CN.md +0 -29
- package/src/clis/twitter/trending.yaml +0 -46
- package/src/clis/wechat/README.md +0 -5
- package/src/clis/wechat/README.zh-CN.md +0 -28
- package/src/clis/wechat/chats.ts +0 -33
- package/src/clis/wechat/contacts.ts +0 -33
- package/src/clis/wechat/read.ts +0 -72
- package/src/clis/wechat/search.ts +0 -36
- package/src/clis/wechat/send.ts +0 -49
- package/src/clis/wechat/status.ts +0 -35
- package/src/engine.ts +0 -274
- package/src/pipeline.ts +0 -8
- /package/dist/{bilibili.js → clis/bilibili/utils.js} +0 -0
- /package/dist/{chaoxing.test.d.ts → clis/bloomberg/businessweek.d.ts} +0 -0
- /package/dist/{coupang.test.d.ts → clis/bloomberg/economics.d.ts} +0 -0
- /package/dist/{coupang.d.ts → clis/coupang/utils.d.ts} +0 -0
- /package/dist/{coupang.js → clis/coupang/utils.js} +0 -0
- /package/src/{coupang.ts → clis/coupang/utils.ts} +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for dom-snapshot.ts: DOM snapshot engine.
|
|
3
|
+
*
|
|
4
|
+
* Since the engine generates JavaScript strings for in-page evaluation,
|
|
5
|
+
* these tests validate:
|
|
6
|
+
* 1. The generated code is syntactically valid JS
|
|
7
|
+
* 2. Options are correctly embedded
|
|
8
|
+
* 3. The output structure matches expected format
|
|
9
|
+
* 4. All features are present (Shadow DOM, iframe, table, diff, etc.)
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for dom-snapshot.ts: DOM snapshot engine.
|
|
3
|
+
*
|
|
4
|
+
* Since the engine generates JavaScript strings for in-page evaluation,
|
|
5
|
+
* these tests validate:
|
|
6
|
+
* 1. The generated code is syntactically valid JS
|
|
7
|
+
* 2. Options are correctly embedded
|
|
8
|
+
* 3. The output structure matches expected format
|
|
9
|
+
* 4. All features are present (Shadow DOM, iframe, table, diff, etc.)
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect } from 'vitest';
|
|
12
|
+
import { generateSnapshotJs, scrollToRefJs, getFormStateJs } from './dom-snapshot.js';
|
|
13
|
+
describe('generateSnapshotJs', () => {
|
|
14
|
+
it('returns a non-empty string', () => {
|
|
15
|
+
const js = generateSnapshotJs();
|
|
16
|
+
expect(typeof js).toBe('string');
|
|
17
|
+
expect(js.length).toBeGreaterThan(100);
|
|
18
|
+
});
|
|
19
|
+
it('generates syntactically valid JS (can be parsed)', () => {
|
|
20
|
+
const js = generateSnapshotJs();
|
|
21
|
+
expect(() => new Function(js)).not.toThrow();
|
|
22
|
+
});
|
|
23
|
+
it('embeds default options correctly', () => {
|
|
24
|
+
const js = generateSnapshotJs();
|
|
25
|
+
expect(js).toContain('VIEWPORT_EXPAND = 800');
|
|
26
|
+
expect(js).toContain('MAX_DEPTH = 50');
|
|
27
|
+
expect(js).toContain('INTERACTIVE_ONLY = false');
|
|
28
|
+
expect(js).toContain('MAX_TEXT_LEN = 120');
|
|
29
|
+
expect(js).toContain('INCLUDE_SCROLL_INFO = true');
|
|
30
|
+
expect(js).toContain('BBOX_DEDUP = true');
|
|
31
|
+
expect(js).toContain('INCLUDE_SHADOW_DOM = true');
|
|
32
|
+
expect(js).toContain('INCLUDE_IFRAMES = true');
|
|
33
|
+
expect(js).toContain('PAINT_ORDER_CHECK = true');
|
|
34
|
+
expect(js).toContain('ANNOTATE_REFS = true');
|
|
35
|
+
expect(js).toContain('REPORT_HIDDEN = true');
|
|
36
|
+
expect(js).toContain('FILTER_ADS = true');
|
|
37
|
+
expect(js).toContain('MARKDOWN_TABLES = true');
|
|
38
|
+
expect(js).toContain('PREV_HASHES = null');
|
|
39
|
+
});
|
|
40
|
+
it('embeds custom options correctly', () => {
|
|
41
|
+
const js = generateSnapshotJs({
|
|
42
|
+
viewportExpand: 2000,
|
|
43
|
+
maxDepth: 30,
|
|
44
|
+
interactiveOnly: true,
|
|
45
|
+
maxTextLength: 200,
|
|
46
|
+
includeScrollInfo: false,
|
|
47
|
+
bboxDedup: false,
|
|
48
|
+
includeShadowDom: false,
|
|
49
|
+
includeIframes: false,
|
|
50
|
+
maxIframes: 3,
|
|
51
|
+
paintOrderCheck: false,
|
|
52
|
+
annotateRefs: false,
|
|
53
|
+
reportHidden: false,
|
|
54
|
+
filterAds: false,
|
|
55
|
+
markdownTables: false,
|
|
56
|
+
});
|
|
57
|
+
expect(js).toContain('VIEWPORT_EXPAND = 2000');
|
|
58
|
+
expect(js).toContain('MAX_DEPTH = 30');
|
|
59
|
+
expect(js).toContain('INTERACTIVE_ONLY = true');
|
|
60
|
+
expect(js).toContain('MAX_TEXT_LEN = 200');
|
|
61
|
+
expect(js).toContain('INCLUDE_SCROLL_INFO = false');
|
|
62
|
+
expect(js).toContain('BBOX_DEDUP = false');
|
|
63
|
+
expect(js).toContain('INCLUDE_SHADOW_DOM = false');
|
|
64
|
+
expect(js).toContain('INCLUDE_IFRAMES = false');
|
|
65
|
+
expect(js).toContain('MAX_IFRAMES = 3');
|
|
66
|
+
expect(js).toContain('PAINT_ORDER_CHECK = false');
|
|
67
|
+
expect(js).toContain('ANNOTATE_REFS = false');
|
|
68
|
+
expect(js).toContain('REPORT_HIDDEN = false');
|
|
69
|
+
expect(js).toContain('FILTER_ADS = false');
|
|
70
|
+
expect(js).toContain('MARKDOWN_TABLES = false');
|
|
71
|
+
});
|
|
72
|
+
it('clamps maxDepth between 1 and 200', () => {
|
|
73
|
+
expect(generateSnapshotJs({ maxDepth: -5 })).toContain('MAX_DEPTH = 1');
|
|
74
|
+
expect(generateSnapshotJs({ maxDepth: 999 })).toContain('MAX_DEPTH = 200');
|
|
75
|
+
expect(generateSnapshotJs({ maxDepth: 75 })).toContain('MAX_DEPTH = 75');
|
|
76
|
+
});
|
|
77
|
+
it('wraps output as an IIFE', () => {
|
|
78
|
+
const js = generateSnapshotJs();
|
|
79
|
+
expect(js.startsWith('(() =>')).toBe(true);
|
|
80
|
+
expect(js.trimEnd().endsWith(')()')).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it('embeds previousHashes for incremental diff', () => {
|
|
83
|
+
const hashes = JSON.stringify(['12345', '67890']);
|
|
84
|
+
const js = generateSnapshotJs({ previousHashes: hashes });
|
|
85
|
+
expect(js).toContain('new Set(["12345","67890"])');
|
|
86
|
+
});
|
|
87
|
+
it('includes all core features in generated code', () => {
|
|
88
|
+
const js = generateSnapshotJs();
|
|
89
|
+
// Tag filtering
|
|
90
|
+
expect(js).toContain('SKIP_TAGS');
|
|
91
|
+
expect(js).toContain("'script'");
|
|
92
|
+
expect(js).toContain("'style'");
|
|
93
|
+
// SVG collapsing
|
|
94
|
+
expect(js).toContain('SVG_CHILDREN');
|
|
95
|
+
// Interactive detection
|
|
96
|
+
expect(js).toContain('INTERACTIVE_TAGS');
|
|
97
|
+
expect(js).toContain('INTERACTIVE_ROLES');
|
|
98
|
+
expect(js).toContain('isInteractive');
|
|
99
|
+
// Visibility
|
|
100
|
+
expect(js).toContain('isVisibleByCSS');
|
|
101
|
+
expect(js).toContain('isInExpandedViewport');
|
|
102
|
+
// BBox dedup
|
|
103
|
+
expect(js).toContain('isContainedBy');
|
|
104
|
+
expect(js).toContain('PROPAGATING_TAGS');
|
|
105
|
+
// Shadow DOM
|
|
106
|
+
expect(js).toContain('shadowRoot');
|
|
107
|
+
expect(js).toContain('|shadow|');
|
|
108
|
+
// iframe
|
|
109
|
+
expect(js).toContain('walkIframe');
|
|
110
|
+
expect(js).toContain('|iframe|');
|
|
111
|
+
// Paint order
|
|
112
|
+
expect(js).toContain('isOccludedByOverlay');
|
|
113
|
+
expect(js).toContain('elementFromPoint');
|
|
114
|
+
// Ad filtering
|
|
115
|
+
expect(js).toContain('isAdElement');
|
|
116
|
+
expect(js).toContain('AD_PATTERNS');
|
|
117
|
+
// data-ref annotation
|
|
118
|
+
expect(js).toContain('data-opencli-ref');
|
|
119
|
+
// Hidden elements report
|
|
120
|
+
expect(js).toContain('hiddenInteractives');
|
|
121
|
+
expect(js).toContain('hidden_interactive');
|
|
122
|
+
// Incremental diff
|
|
123
|
+
expect(js).toContain('hashElement');
|
|
124
|
+
expect(js).toContain('currentHashes');
|
|
125
|
+
expect(js).toContain('__opencli_prev_hashes');
|
|
126
|
+
// Table serialization
|
|
127
|
+
expect(js).toContain('serializeTable');
|
|
128
|
+
expect(js).toContain('|table|');
|
|
129
|
+
// Synthetic attributes
|
|
130
|
+
expect(js).toContain("'YYYY-MM-DD'");
|
|
131
|
+
expect(js).toContain('value=••••');
|
|
132
|
+
// Page metadata
|
|
133
|
+
expect(js).toContain('location.href');
|
|
134
|
+
expect(js).toContain('document.title');
|
|
135
|
+
});
|
|
136
|
+
it('contains proper attribute whitelist', () => {
|
|
137
|
+
const js = generateSnapshotJs();
|
|
138
|
+
const expectedAttrs = [
|
|
139
|
+
'aria-label', 'aria-expanded', 'aria-checked', 'aria-selected',
|
|
140
|
+
'placeholder', 'href', 'role', 'data-testid', 'autocomplete',
|
|
141
|
+
];
|
|
142
|
+
for (const attr of expectedAttrs) {
|
|
143
|
+
expect(js).toContain(`'${attr}'`);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
it('includes scroll info formatting', () => {
|
|
147
|
+
const js = generateSnapshotJs();
|
|
148
|
+
expect(js).toContain('scrollHeight');
|
|
149
|
+
expect(js).toContain('scrollTop');
|
|
150
|
+
expect(js).toContain('|scroll|');
|
|
151
|
+
expect(js).toContain('page_scroll');
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('scrollToRefJs', () => {
|
|
155
|
+
it('generates valid JS', () => {
|
|
156
|
+
const js = scrollToRefJs('42');
|
|
157
|
+
expect(() => new Function(js)).not.toThrow();
|
|
158
|
+
});
|
|
159
|
+
it('targets data-opencli-ref', () => {
|
|
160
|
+
const js = scrollToRefJs('7');
|
|
161
|
+
expect(js).toContain('data-opencli-ref');
|
|
162
|
+
expect(js).toContain('scrollIntoView');
|
|
163
|
+
expect(js).toContain('"7"');
|
|
164
|
+
});
|
|
165
|
+
it('falls back to data-ref', () => {
|
|
166
|
+
const js = scrollToRefJs('3');
|
|
167
|
+
expect(js).toContain('data-ref');
|
|
168
|
+
});
|
|
169
|
+
it('returns scrolled info', () => {
|
|
170
|
+
const js = scrollToRefJs('1');
|
|
171
|
+
expect(js).toContain('scrolled: true');
|
|
172
|
+
expect(js).toContain('tag:');
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
describe('getFormStateJs', () => {
|
|
176
|
+
it('generates valid JS', () => {
|
|
177
|
+
const js = getFormStateJs();
|
|
178
|
+
expect(() => new Function(js)).not.toThrow();
|
|
179
|
+
});
|
|
180
|
+
it('collects form elements', () => {
|
|
181
|
+
const js = getFormStateJs();
|
|
182
|
+
expect(js).toContain('document.forms');
|
|
183
|
+
expect(js).toContain('form.elements');
|
|
184
|
+
});
|
|
185
|
+
it('collects orphan fields', () => {
|
|
186
|
+
const js = getFormStateJs();
|
|
187
|
+
expect(js).toContain('orphanFields');
|
|
188
|
+
expect(js).toContain('el.form');
|
|
189
|
+
});
|
|
190
|
+
it('handles different input types', () => {
|
|
191
|
+
const js = getFormStateJs();
|
|
192
|
+
expect(js).toContain('checkbox');
|
|
193
|
+
expect(js).toContain('radio');
|
|
194
|
+
expect(js).toContain('password');
|
|
195
|
+
expect(js).toContain('contenteditable');
|
|
196
|
+
});
|
|
197
|
+
it('extracts labels', () => {
|
|
198
|
+
const js = getFormStateJs();
|
|
199
|
+
expect(js).toContain('aria-label');
|
|
200
|
+
expect(js).toContain('label[for=');
|
|
201
|
+
expect(js).toContain('closest');
|
|
202
|
+
expect(js).toContain('placeholder');
|
|
203
|
+
});
|
|
204
|
+
it('masks passwords', () => {
|
|
205
|
+
const js = getFormStateJs();
|
|
206
|
+
expect(js).toContain('••••');
|
|
207
|
+
});
|
|
208
|
+
it('includes data-opencli-ref in output', () => {
|
|
209
|
+
const js = getFormStateJs();
|
|
210
|
+
expect(js).toContain('data-opencli-ref');
|
|
211
|
+
});
|
|
212
|
+
});
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { Page } from './page.js';
|
|
|
8
8
|
export { BrowserBridge, BrowserBridge as PlaywrightMCP } from './mcp.js';
|
|
9
9
|
export { CDPBridge } from './cdp.js';
|
|
10
10
|
export { isDaemonRunning } from './daemon-client.js';
|
|
11
|
+
export { generateSnapshotJs, scrollToRefJs, getFormStateJs } from './dom-snapshot.js';
|
|
12
|
+
export type { SnapshotOptions } from './dom-snapshot.js';
|
|
11
13
|
import { extractTabEntries, diffTabIndexes, appendLimited } from './tabs.js';
|
|
12
14
|
import { withTimeoutMs } from '../runtime.js';
|
|
13
15
|
export declare const __test__: {
|
package/dist/browser/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { Page } from './page.js';
|
|
|
8
8
|
export { BrowserBridge, BrowserBridge as PlaywrightMCP } from './mcp.js';
|
|
9
9
|
export { CDPBridge } from './cdp.js';
|
|
10
10
|
export { isDaemonRunning } from './daemon-client.js';
|
|
11
|
+
export { generateSnapshotJs, scrollToRefJs, getFormStateJs } from './dom-snapshot.js';
|
|
11
12
|
import { extractTabEntries, diffTabIndexes, appendLimited } from './tabs.js';
|
|
12
13
|
import { __test__ as cdpTest } from './cdp.js';
|
|
13
14
|
import { withTimeoutMs } from '../runtime.js';
|
package/dist/browser/page.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* where resolveTabId() in the extension picks a chrome:// or
|
|
10
10
|
* chrome-extension:// tab that can't be debugged.
|
|
11
11
|
*/
|
|
12
|
-
import type { IPage } from '../types.js';
|
|
12
|
+
import type { BrowserCookie, IPage, ScreenshotOptions, SnapshotOptions, WaitOptions } from '../types.js';
|
|
13
13
|
/**
|
|
14
14
|
* Page — implements IPage by talking to the daemon via HTTP.
|
|
15
15
|
*/
|
|
@@ -21,39 +21,37 @@ export declare class Page implements IPage {
|
|
|
21
21
|
/** Helper: spread tabId into command params if we have one */
|
|
22
22
|
private _tabOpt;
|
|
23
23
|
private _workspaceOpt;
|
|
24
|
-
goto(url: string
|
|
24
|
+
goto(url: string, options?: {
|
|
25
|
+
waitUntil?: 'load' | 'none';
|
|
26
|
+
settleMs?: number;
|
|
27
|
+
}): Promise<void>;
|
|
25
28
|
/** Close the automation window in the extension */
|
|
26
29
|
closeWindow(): Promise<void>;
|
|
27
|
-
evaluate(js: string): Promise<
|
|
30
|
+
evaluate(js: string): Promise<unknown>;
|
|
28
31
|
getCookies(opts?: {
|
|
29
32
|
domain?: string;
|
|
30
33
|
url?: string;
|
|
31
|
-
}): Promise<
|
|
32
|
-
snapshot(opts?:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
maxDepth?: number;
|
|
36
|
-
raw?: boolean;
|
|
37
|
-
}): Promise<any>;
|
|
34
|
+
}): Promise<BrowserCookie[]>;
|
|
35
|
+
snapshot(opts?: SnapshotOptions): Promise<unknown>;
|
|
36
|
+
/** Fallback basic snapshot — original buildTree approach */
|
|
37
|
+
private _basicSnapshot;
|
|
38
38
|
click(ref: string): Promise<void>;
|
|
39
39
|
typeText(ref: string, text: string): Promise<void>;
|
|
40
40
|
pressKey(key: string): Promise<void>;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}): Promise<void>;
|
|
46
|
-
tabs(): Promise<any>;
|
|
41
|
+
scrollTo(ref: string): Promise<unknown>;
|
|
42
|
+
getFormState(): Promise<Record<string, unknown>>;
|
|
43
|
+
wait(options: number | WaitOptions): Promise<void>;
|
|
44
|
+
tabs(): Promise<unknown[]>;
|
|
47
45
|
closeTab(index?: number): Promise<void>;
|
|
48
46
|
newTab(): Promise<void>;
|
|
49
47
|
selectTab(index: number): Promise<void>;
|
|
50
|
-
networkRequests(includeStatic?: boolean): Promise<
|
|
48
|
+
networkRequests(includeStatic?: boolean): Promise<unknown[]>;
|
|
51
49
|
/**
|
|
52
50
|
* Console messages are not available in lightweight daemon mode.
|
|
53
51
|
* Would require CDP Runtime.consoleAPICalled event listener.
|
|
54
52
|
* @returns Always returns empty array.
|
|
55
53
|
*/
|
|
56
|
-
consoleMessages(_level?: string): Promise<
|
|
54
|
+
consoleMessages(_level?: string): Promise<unknown[]>;
|
|
57
55
|
/**
|
|
58
56
|
* Capture a screenshot via CDP Page.captureScreenshot.
|
|
59
57
|
* @param options.format - 'png' (default) or 'jpeg'
|
|
@@ -61,17 +59,12 @@ export declare class Page implements IPage {
|
|
|
61
59
|
* @param options.fullPage - capture full scrollable page
|
|
62
60
|
* @param options.path - save to file path (returns base64 if omitted)
|
|
63
61
|
*/
|
|
64
|
-
screenshot(options?:
|
|
65
|
-
format?: 'png' | 'jpeg';
|
|
66
|
-
quality?: number;
|
|
67
|
-
fullPage?: boolean;
|
|
68
|
-
path?: string;
|
|
69
|
-
}): Promise<string>;
|
|
62
|
+
screenshot(options?: ScreenshotOptions): Promise<string>;
|
|
70
63
|
scroll(direction?: string, amount?: number): Promise<void>;
|
|
71
64
|
autoScroll(options?: {
|
|
72
65
|
times?: number;
|
|
73
66
|
delayMs?: number;
|
|
74
67
|
}): Promise<void>;
|
|
75
68
|
installInterceptor(pattern: string): Promise<void>;
|
|
76
|
-
getInterceptedRequests(): Promise<
|
|
69
|
+
getInterceptedRequests(): Promise<unknown[]>;
|
|
77
70
|
}
|
package/dist/browser/page.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { formatSnapshot } from '../snapshotFormatter.js';
|
|
13
13
|
import { sendCommand } from './daemon-client.js';
|
|
14
14
|
import { wrapForEval } from './utils.js';
|
|
15
|
+
import { generateSnapshotJs, scrollToRefJs, getFormStateJs } from './dom-snapshot.js';
|
|
15
16
|
import { clickJs, typeTextJs, pressKeyJs, waitForTextJs, scrollJs, autoScrollJs, networkRequestsJs, } from './dom-helpers.js';
|
|
16
17
|
/**
|
|
17
18
|
* Page — implements IPage by talking to the daemon via HTTP.
|
|
@@ -30,7 +31,7 @@ export class Page {
|
|
|
30
31
|
_workspaceOpt() {
|
|
31
32
|
return { workspace: this.workspace };
|
|
32
33
|
}
|
|
33
|
-
async goto(url) {
|
|
34
|
+
async goto(url, options) {
|
|
34
35
|
const result = await sendCommand('navigate', {
|
|
35
36
|
url,
|
|
36
37
|
...this._workspaceOpt(),
|
|
@@ -40,6 +41,12 @@ export class Page {
|
|
|
40
41
|
if (result?.tabId) {
|
|
41
42
|
this._tabId = result.tabId;
|
|
42
43
|
}
|
|
44
|
+
// Post-load settle: the extension already waits for tab.status === 'complete',
|
|
45
|
+
// but SPA frameworks (React/Vue) need extra time to render after DOM load.
|
|
46
|
+
if (options?.waitUntil !== 'none') {
|
|
47
|
+
const settleMs = options?.settleMs ?? 1000;
|
|
48
|
+
await new Promise(resolve => setTimeout(resolve, settleMs));
|
|
49
|
+
}
|
|
43
50
|
}
|
|
44
51
|
/** Close the automation window in the extension */
|
|
45
52
|
async closeWindow() {
|
|
@@ -59,6 +66,28 @@ export class Page {
|
|
|
59
66
|
return Array.isArray(result) ? result : [];
|
|
60
67
|
}
|
|
61
68
|
async snapshot(opts = {}) {
|
|
69
|
+
// Primary: use the advanced DOM snapshot engine with multi-layer pruning
|
|
70
|
+
const snapshotJs = generateSnapshotJs({
|
|
71
|
+
viewportExpand: opts.viewportExpand ?? 800,
|
|
72
|
+
maxDepth: Math.max(1, Math.min(Number(opts.maxDepth) || 50, 200)),
|
|
73
|
+
interactiveOnly: opts.interactive ?? false,
|
|
74
|
+
maxTextLength: opts.maxTextLength ?? 120,
|
|
75
|
+
includeScrollInfo: true,
|
|
76
|
+
bboxDedup: true,
|
|
77
|
+
});
|
|
78
|
+
try {
|
|
79
|
+
const result = await sendCommand('exec', { code: snapshotJs, ...this._workspaceOpt(), ...this._tabOpt() });
|
|
80
|
+
// The advanced engine already produces a clean, pruned, LLM-friendly output.
|
|
81
|
+
// Do NOT pass through formatSnapshot — its format is incompatible.
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Fallback: basic DOM snapshot (original implementation)
|
|
86
|
+
return this._basicSnapshot(opts);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Fallback basic snapshot — original buildTree approach */
|
|
90
|
+
async _basicSnapshot(opts = {}) {
|
|
62
91
|
const maxDepth = Math.max(1, Math.min(Number(opts.maxDepth) || 50, 200));
|
|
63
92
|
const code = `
|
|
64
93
|
(async () => {
|
|
@@ -72,7 +101,7 @@ export class Page {
|
|
|
72
101
|
|
|
73
102
|
let indent = ' '.repeat(depth);
|
|
74
103
|
let line = indent + role;
|
|
75
|
-
if (name) line += ' "' + name.replace(/"/g, '
|
|
104
|
+
if (name) line += ' "' + name.replace(/"/g, '\\\\\\"') + '"';
|
|
76
105
|
if (node.tagName?.toLowerCase() === 'a' && node.href) line += ' [' + node.href + ']';
|
|
77
106
|
if (node.tagName?.toLowerCase() === 'input') line += ' [' + (node.type || 'text') + ']';
|
|
78
107
|
|
|
@@ -106,6 +135,14 @@ export class Page {
|
|
|
106
135
|
const code = pressKeyJs(key);
|
|
107
136
|
await sendCommand('exec', { code, ...this._workspaceOpt(), ...this._tabOpt() });
|
|
108
137
|
}
|
|
138
|
+
async scrollTo(ref) {
|
|
139
|
+
const code = scrollToRefJs(ref);
|
|
140
|
+
return sendCommand('exec', { code, ...this._workspaceOpt(), ...this._tabOpt() });
|
|
141
|
+
}
|
|
142
|
+
async getFormState() {
|
|
143
|
+
const code = getFormStateJs();
|
|
144
|
+
return (await sendCommand('exec', { code, ...this._workspaceOpt(), ...this._tabOpt() }));
|
|
145
|
+
}
|
|
109
146
|
async wait(options) {
|
|
110
147
|
if (typeof options === 'number') {
|
|
111
148
|
await new Promise(resolve => setTimeout(resolve, options * 1000));
|
|
@@ -122,7 +159,8 @@ export class Page {
|
|
|
122
159
|
}
|
|
123
160
|
}
|
|
124
161
|
async tabs() {
|
|
125
|
-
|
|
162
|
+
const result = await sendCommand('tabs', { op: 'list', ...this._workspaceOpt() });
|
|
163
|
+
return Array.isArray(result) ? result : [];
|
|
126
164
|
}
|
|
127
165
|
async closeTab(index) {
|
|
128
166
|
await sendCommand('tabs', { op: 'close', ...this._workspaceOpt(), ...(index !== undefined ? { index } : {}) });
|
|
@@ -135,7 +173,8 @@ export class Page {
|
|
|
135
173
|
}
|
|
136
174
|
async networkRequests(includeStatic = false) {
|
|
137
175
|
const code = networkRequestsJs(includeStatic);
|
|
138
|
-
|
|
176
|
+
const result = await sendCommand('exec', { code, ...this._workspaceOpt(), ...this._tabOpt() });
|
|
177
|
+
return Array.isArray(result) ? result : [];
|
|
139
178
|
}
|
|
140
179
|
/**
|
|
141
180
|
* Console messages are not available in lightweight daemon mode.
|
|
@@ -192,7 +231,7 @@ export class Page {
|
|
|
192
231
|
const { generateReadInterceptedJs } = await import('../interceptor.js');
|
|
193
232
|
// Same as installInterceptor: must go through evaluate() for IIFE wrapping
|
|
194
233
|
const result = await this.evaluate(generateReadInterceptedJs('__opencli_xhr'));
|
|
195
|
-
return result
|
|
234
|
+
return Array.isArray(result) ? result : [];
|
|
196
235
|
}
|
|
197
236
|
}
|
|
198
237
|
// (End of file)
|
package/dist/build-manifest.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Usage: npx tsx src/build-manifest.ts
|
|
9
9
|
* Output: dist/cli-manifest.json
|
|
10
10
|
*/
|
|
11
|
-
interface ManifestEntry {
|
|
11
|
+
export interface ManifestEntry {
|
|
12
12
|
site: string;
|
|
13
13
|
name: string;
|
|
14
14
|
description: string;
|
|
@@ -18,20 +18,27 @@ interface ManifestEntry {
|
|
|
18
18
|
args: Array<{
|
|
19
19
|
name: string;
|
|
20
20
|
type?: string;
|
|
21
|
-
default?:
|
|
21
|
+
default?: unknown;
|
|
22
22
|
required?: boolean;
|
|
23
23
|
positional?: boolean;
|
|
24
24
|
help?: string;
|
|
25
25
|
choices?: string[];
|
|
26
26
|
}>;
|
|
27
27
|
columns?: string[];
|
|
28
|
-
pipeline?:
|
|
28
|
+
pipeline?: Record<string, unknown>[];
|
|
29
29
|
timeout?: number;
|
|
30
30
|
/** 'yaml' or 'ts' — determines how executeCommand loads the handler */
|
|
31
31
|
type: 'yaml' | 'ts';
|
|
32
32
|
/** Relative path from clis/ dir, e.g. 'bilibili/hot.yaml' or 'bilibili/search.js' */
|
|
33
33
|
modulePath?: string;
|
|
34
|
+
/** Pre-navigation control — see CliCommand.navigateBefore */
|
|
35
|
+
navigateBefore?: boolean | string;
|
|
34
36
|
}
|
|
35
37
|
export declare function parseTsArgsBlock(argsBlock: string): ManifestEntry['args'];
|
|
38
|
+
export declare function scanTs(filePath: string, site: string): ManifestEntry | null;
|
|
39
|
+
/**
|
|
40
|
+
* When both YAML and TS adapters exist for the same site/name,
|
|
41
|
+
* prefer the TS version (it self-registers and typically has richer logic).
|
|
42
|
+
*/
|
|
43
|
+
export declare function shouldReplaceManifestEntry(current: ManifestEntry, next: ManifestEntry): boolean;
|
|
36
44
|
export declare function buildManifest(): ManifestEntry[];
|
|
37
|
-
export {};
|
package/dist/build-manifest.js
CHANGED
|
@@ -15,6 +15,12 @@ import yaml from 'js-yaml';
|
|
|
15
15
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
16
16
|
const CLIS_DIR = path.resolve(__dirname, 'clis');
|
|
17
17
|
const OUTPUT = path.resolve(__dirname, '..', 'dist', 'cli-manifest.json');
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
function getErrorMessage(error) {
|
|
22
|
+
return error instanceof Error ? error.message : String(error);
|
|
23
|
+
}
|
|
18
24
|
function extractBalancedBlock(source, startIndex, openChar, closeChar) {
|
|
19
25
|
let depth = 0;
|
|
20
26
|
let quote = null;
|
|
@@ -116,60 +122,66 @@ function scanYaml(filePath, site) {
|
|
|
116
122
|
try {
|
|
117
123
|
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
118
124
|
const def = yaml.load(raw);
|
|
119
|
-
if (!def
|
|
125
|
+
if (!isRecord(def))
|
|
120
126
|
return null;
|
|
121
|
-
const
|
|
127
|
+
const cliDef = def;
|
|
128
|
+
const strategyStr = cliDef.strategy ?? (cliDef.browser === false ? 'public' : 'cookie');
|
|
122
129
|
const strategy = strategyStr.toUpperCase();
|
|
123
|
-
const browser =
|
|
130
|
+
const browser = cliDef.browser ?? (strategy !== 'PUBLIC');
|
|
124
131
|
const args = [];
|
|
125
|
-
if (
|
|
126
|
-
for (const [argName, argDef] of Object.entries(
|
|
132
|
+
if (cliDef.args && typeof cliDef.args === 'object') {
|
|
133
|
+
for (const [argName, argDef] of Object.entries(cliDef.args)) {
|
|
127
134
|
args.push({
|
|
128
135
|
name: argName,
|
|
129
136
|
type: argDef?.type ?? 'str',
|
|
130
137
|
default: argDef?.default,
|
|
131
138
|
required: argDef?.required ?? false,
|
|
139
|
+
positional: argDef?.positional === true || undefined,
|
|
132
140
|
help: argDef?.description ?? argDef?.help ?? '',
|
|
133
141
|
choices: argDef?.choices,
|
|
134
142
|
});
|
|
135
143
|
}
|
|
136
144
|
}
|
|
137
145
|
return {
|
|
138
|
-
site:
|
|
139
|
-
name:
|
|
140
|
-
description:
|
|
141
|
-
domain:
|
|
146
|
+
site: cliDef.site ?? site,
|
|
147
|
+
name: cliDef.name ?? path.basename(filePath, path.extname(filePath)),
|
|
148
|
+
description: cliDef.description ?? '',
|
|
149
|
+
domain: cliDef.domain,
|
|
142
150
|
strategy: strategy.toLowerCase(),
|
|
143
151
|
browser,
|
|
144
152
|
args,
|
|
145
|
-
columns:
|
|
146
|
-
pipeline:
|
|
147
|
-
timeout:
|
|
153
|
+
columns: cliDef.columns,
|
|
154
|
+
pipeline: cliDef.pipeline,
|
|
155
|
+
timeout: cliDef.timeout,
|
|
148
156
|
type: 'yaml',
|
|
157
|
+
navigateBefore: cliDef.navigateBefore,
|
|
149
158
|
};
|
|
150
159
|
}
|
|
151
160
|
catch (err) {
|
|
152
|
-
process.stderr.write(`Warning: failed to parse ${filePath}: ${err
|
|
161
|
+
process.stderr.write(`Warning: failed to parse ${filePath}: ${getErrorMessage(err)}\n`);
|
|
153
162
|
return null;
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
|
-
function scanTs(filePath, site) {
|
|
165
|
+
export function scanTs(filePath, site) {
|
|
157
166
|
// TS adapters self-register via cli() at import time.
|
|
158
167
|
// We statically parse the source to extract metadata for the manifest stub.
|
|
159
168
|
const baseName = path.basename(filePath, path.extname(filePath));
|
|
160
169
|
const relativePath = `${site}/${baseName}.js`;
|
|
161
|
-
const entry = {
|
|
162
|
-
site,
|
|
163
|
-
name: baseName,
|
|
164
|
-
description: '',
|
|
165
|
-
strategy: 'cookie',
|
|
166
|
-
browser: true,
|
|
167
|
-
args: [],
|
|
168
|
-
type: 'ts',
|
|
169
|
-
modulePath: relativePath,
|
|
170
|
-
};
|
|
171
170
|
try {
|
|
172
171
|
const src = fs.readFileSync(filePath, 'utf-8');
|
|
172
|
+
// Helper/test modules should not appear as CLI commands in the manifest.
|
|
173
|
+
if (!/\bcli\s*\(/.test(src))
|
|
174
|
+
return null;
|
|
175
|
+
const entry = {
|
|
176
|
+
site,
|
|
177
|
+
name: baseName,
|
|
178
|
+
description: '',
|
|
179
|
+
strategy: 'cookie',
|
|
180
|
+
browser: true,
|
|
181
|
+
args: [],
|
|
182
|
+
type: 'ts',
|
|
183
|
+
modulePath: relativePath,
|
|
184
|
+
};
|
|
173
185
|
// Extract description
|
|
174
186
|
const descMatch = src.match(/description\s*:\s*['"`]([^'"`]*)['"`]/);
|
|
175
187
|
if (descMatch)
|
|
@@ -198,14 +210,29 @@ function scanTs(filePath, site) {
|
|
|
198
210
|
if (argsBlock) {
|
|
199
211
|
entry.args = parseTsArgsBlock(argsBlock);
|
|
200
212
|
}
|
|
213
|
+
// Extract navigateBefore: false
|
|
214
|
+
const navMatch = src.match(/navigateBefore\s*:\s*(true|false)/);
|
|
215
|
+
if (navMatch)
|
|
216
|
+
entry.navigateBefore = navMatch[1] === 'true' ? true : false;
|
|
217
|
+
return entry;
|
|
201
218
|
}
|
|
202
|
-
catch {
|
|
203
|
-
// If parsing fails,
|
|
219
|
+
catch (err) {
|
|
220
|
+
// If parsing fails, log a warning (matching scanYaml behaviour) and skip the entry.
|
|
221
|
+
process.stderr.write(`Warning: failed to scan ${filePath}: ${getErrorMessage(err)}\n`);
|
|
222
|
+
return null;
|
|
204
223
|
}
|
|
205
|
-
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* When both YAML and TS adapters exist for the same site/name,
|
|
227
|
+
* prefer the TS version (it self-registers and typically has richer logic).
|
|
228
|
+
*/
|
|
229
|
+
export function shouldReplaceManifestEntry(current, next) {
|
|
230
|
+
if (current.type === next.type)
|
|
231
|
+
return true;
|
|
232
|
+
return current.type === 'yaml' && next.type === 'ts';
|
|
206
233
|
}
|
|
207
234
|
export function buildManifest() {
|
|
208
|
-
const manifest =
|
|
235
|
+
const manifest = new Map();
|
|
209
236
|
if (fs.existsSync(CLIS_DIR)) {
|
|
210
237
|
for (const site of fs.readdirSync(CLIS_DIR)) {
|
|
211
238
|
const siteDir = path.join(CLIS_DIR, site);
|
|
@@ -215,17 +242,35 @@ export function buildManifest() {
|
|
|
215
242
|
const filePath = path.join(siteDir, file);
|
|
216
243
|
if (file.endsWith('.yaml') || file.endsWith('.yml')) {
|
|
217
244
|
const entry = scanYaml(filePath, site);
|
|
218
|
-
if (entry)
|
|
219
|
-
|
|
245
|
+
if (entry) {
|
|
246
|
+
const key = `${entry.site}/${entry.name}`;
|
|
247
|
+
const existing = manifest.get(key);
|
|
248
|
+
if (!existing || shouldReplaceManifestEntry(existing, entry)) {
|
|
249
|
+
if (existing && existing.type !== entry.type) {
|
|
250
|
+
process.stderr.write(`⚠️ Duplicate adapter ${key}: ${existing.type} superseded by ${entry.type}\n`);
|
|
251
|
+
}
|
|
252
|
+
manifest.set(key, entry);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
220
255
|
}
|
|
221
|
-
else if ((file.endsWith('.ts') && !file.endsWith('.d.ts') && file !== 'index.ts') ||
|
|
222
|
-
(file.endsWith('.js') && !file.endsWith('.d.js') && file !== 'index.js')) {
|
|
223
|
-
|
|
256
|
+
else if ((file.endsWith('.ts') && !file.endsWith('.d.ts') && !file.endsWith('.test.ts') && file !== 'index.ts') ||
|
|
257
|
+
(file.endsWith('.js') && !file.endsWith('.d.js') && !file.endsWith('.test.js') && file !== 'index.js')) {
|
|
258
|
+
const entry = scanTs(filePath, site);
|
|
259
|
+
if (entry) {
|
|
260
|
+
const key = `${entry.site}/${entry.name}`;
|
|
261
|
+
const existing = manifest.get(key);
|
|
262
|
+
if (!existing || shouldReplaceManifestEntry(existing, entry)) {
|
|
263
|
+
if (existing && existing.type !== entry.type) {
|
|
264
|
+
process.stderr.write(`⚠️ Duplicate adapter ${key}: ${existing.type} superseded by ${entry.type}\n`);
|
|
265
|
+
}
|
|
266
|
+
manifest.set(key, entry);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
224
269
|
}
|
|
225
270
|
}
|
|
226
271
|
}
|
|
227
272
|
}
|
|
228
|
-
return manifest;
|
|
273
|
+
return [...manifest.values()];
|
|
229
274
|
}
|
|
230
275
|
function main() {
|
|
231
276
|
const manifest = buildManifest();
|