publishport-opencli 1.0.20 → 1.0.21
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/clis/12306/me.js +2 -2
- package/clis/12306/orders.js +3 -3
- package/clis/12306/passengers.js +3 -3
- package/clis/12306/price.js +1 -1
- package/clis/12306/stations.js +1 -1
- package/clis/12306/train.js +1 -1
- package/clis/12306/trains.js +1 -1
- package/clis/12306/utils.js +1 -1
- package/clis/1688/download.js +1 -1
- package/clis/1688/item.js +4 -4
- package/clis/1688/search.js +4 -4
- package/clis/1688/store.js +4 -4
- package/clis/1point3acres/forum.js +1 -1
- package/clis/1point3acres/forums.js +1 -1
- package/clis/1point3acres/notifications.js +1 -1
- package/clis/1point3acres/search.js +1 -1
- package/clis/1point3acres/thread.js +2 -2
- package/clis/1point3acres/user.js +1 -1
- package/clis/1point3acres/utils.js +2 -2
- package/clis/36kr/article.js +2 -2
- package/clis/36kr/hot.js +2 -2
- package/clis/36kr/news.js +1 -1
- package/clis/36kr/search.js +2 -2
- package/clis/51job/company.js +2 -2
- package/clis/51job/detail.js +2 -2
- package/clis/51job/hot.js +1 -1
- package/clis/51job/search.js +1 -1
- package/clis/51job/utils.js +7 -7
- package/clis/_atlassian/shared.js +9 -9
- package/clis/_shared/article/auth.js +4 -4
- package/clis/_shared/article/douban-md2draft.js +4 -4
- package/clis/_shared/article/format.js +1 -1
- package/clis/_shared/article/images.js +7 -7
- package/clis/_shared/article/login.js +1 -1
- package/clis/_shared/article/publish.js +11 -11
- package/clis/_shared/common.js +1 -1
- package/clis/_shared/content-guard.js +1 -1
- package/clis/_shared/desktop-commands.js +1 -1
- package/clis/_shared/file-inject.js +12 -12
- package/clis/_shared/self-hosted-sites.js +2 -2
- package/clis/_shared/site-auth.js +1 -1
- package/clis/_shared/token-auth.js +2 -2
- package/clis/_shared/video-publish.js +9 -9
- package/clis/amazon/offer.js +3 -3
- package/clis/amazon/product.js +5 -5
- package/clis/amazon/shared.js +6 -6
- package/clis/antigravity/_actions.js +13 -13
- package/clis/antigravity/audit-extras.js +10 -10
- package/clis/antigravity/delete.js +1 -1
- package/clis/antigravity/model.js +6 -6
- package/clis/antigravity/new.js +2 -2
- package/clis/antigravity/read.js +2 -2
- package/clis/antigravity/rename.js +1 -1
- package/clis/antigravity/send.js +3 -3
- package/clis/antigravity/serve.js +17 -17
- package/clis/antigravity/storage.js +6 -6
- package/clis/antigravity/watch.js +2 -2
- package/clis/apple-podcasts/episodes.js +1 -1
- package/clis/apple-podcasts/top.js +1 -1
- package/clis/apple-podcasts/utils.js +1 -1
- package/clis/archive/item.js +1 -1
- package/clis/archive/search.js +1 -1
- package/clis/archive/snapshots.js +1 -1
- package/clis/archive/wayback.js +1 -1
- package/clis/arxiv/author.js +1 -1
- package/clis/arxiv/utils.js +1 -1
- package/clis/autohome/brand.js +1 -1
- package/clis/autohome/score.js +1 -1
- package/clis/autohome/utils.js +1 -1
- package/clis/baijiahao/article.js +1 -1
- package/clis/baijiahao/lists.js +1 -1
- package/clis/baijiahao/login.js +1 -1
- package/clis/baijiahao/publish.js +9 -9
- package/clis/baijiahao/stats.js +1 -1
- package/clis/baijiahao/whoami.js +1 -1
- package/clis/band/bands.js +2 -2
- package/clis/band/mentions.js +2 -2
- package/clis/band/post.js +4 -4
- package/clis/band/posts.js +3 -3
- package/clis/barchart/flow.js +3 -3
- package/clis/barchart/greeks.js +2 -2
- package/clis/barchart/quote.js +3 -3
- package/clis/bbc/news.js +1 -1
- package/clis/bbc/topic.js +1 -1
- package/clis/bbc/utils.js +1 -1
- package/clis/bilibili/article.js +1 -1
- package/clis/bilibili/categories.js +1 -1
- package/clis/bilibili/coin.js +1 -1
- package/clis/bilibili/comment-del.js +1 -1
- package/clis/bilibili/comment-like.js +1 -1
- package/clis/bilibili/comment.js +1 -1
- package/clis/bilibili/comments.js +1 -1
- package/clis/bilibili/dm-list.js +1 -1
- package/clis/bilibili/dm-read.js +1 -1
- package/clis/bilibili/dm-send.js +1 -1
- package/clis/bilibili/download.js +2 -2
- package/clis/bilibili/drafts.js +1 -1
- package/clis/bilibili/dynamic-post.js +3 -3
- package/clis/bilibili/favorite-add.js +1 -1
- package/clis/bilibili/favorite.js +1 -1
- package/clis/bilibili/feed.js +2 -2
- package/clis/bilibili/follow.js +1 -1
- package/clis/bilibili/following.js +1 -1
- package/clis/bilibili/like.js +1 -1
- package/clis/bilibili/partitions.js +1 -1
- package/clis/bilibili/stats.js +1 -1
- package/clis/bilibili/subtitle.js +3 -3
- package/clis/bilibili/summary.js +1 -1
- package/clis/bilibili/topics.js +1 -1
- package/clis/bilibili/unfollow.js +1 -1
- package/clis/bilibili/upload.js +1 -1
- package/clis/bilibili/utils.js +10 -10
- package/clis/bilibili/video-drafts.js +1 -1
- package/clis/bilibili/video.js +1 -1
- package/clis/bloomberg/businessweek.js +4 -4
- package/clis/bloomberg/news.js +2 -2
- package/clis/bloomberg/utils.js +13 -13
- package/clis/bluesky/post.js +1 -1
- package/clis/bluesky/shared.js +11 -11
- package/clis/bluesky/whoami.js +1 -1
- package/clis/booking/search.js +2 -2
- package/clis/boss/accept.js +1 -1
- package/clis/boss/applied.js +1 -1
- package/clis/boss/auth.js +1 -1
- package/clis/boss/batchgreet.js +1 -1
- package/clis/boss/bossinfo.js +1 -1
- package/clis/boss/chatlist.js +1 -1
- package/clis/boss/chatmsg.js +1 -1
- package/clis/boss/cities.js +1 -1
- package/clis/boss/detail.js +1 -1
- package/clis/boss/exchange.js +1 -1
- package/clis/boss/greet.js +1 -1
- package/clis/boss/interviews.js +1 -1
- package/clis/boss/invite.js +1 -1
- package/clis/boss/joblist.js +1 -1
- package/clis/boss/mark.js +1 -1
- package/clis/boss/me.js +2 -2
- package/clis/boss/recommend.js +1 -1
- package/clis/boss/resumedelete.js +1 -1
- package/clis/boss/resumelist.js +1 -1
- package/clis/boss/resumeupload.js +11 -11
- package/clis/boss/search.js +1 -1
- package/clis/boss/send.js +1 -1
- package/clis/boss/sendresume.js +1 -1
- package/clis/boss/stats.js +1 -1
- package/clis/boss/unread.js +1 -1
- package/clis/boss/utils.js +13 -13
- package/clis/chaoxing/assignments.js +1 -1
- package/clis/chaoxing/exams.js +1 -1
- package/clis/chaoxing/utils.js +9 -9
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/auth.js +2 -2
- package/clis/chatgpt/detail.js +1 -1
- package/clis/chatgpt/image.js +1 -1
- package/clis/chatgpt/read.js +1 -1
- package/clis/chatgpt/send.js +1 -1
- package/clis/chatgpt/utils.js +59 -59
- package/clis/chatgpt-app/ask.js +1 -1
- package/clis/chatgpt-app/send.js +1 -1
- package/clis/chatwise/model.js +6 -6
- package/clis/chess/analyze.js +1 -1
- package/clis/chess/game.js +1 -1
- package/clis/chess/games.js +1 -1
- package/clis/chess/stats.js +1 -1
- package/clis/chess/utils.js +1 -1
- package/clis/claude/ask.js +2 -2
- package/clis/claude/detail.js +1 -1
- package/clis/claude/new.js +1 -1
- package/clis/claude/read.js +1 -1
- package/clis/claude/send.js +1 -1
- package/clis/claude/utils.js +23 -23
- package/clis/cnblogs/article.js +1 -1
- package/clis/cnblogs/login.js +1 -1
- package/clis/cnblogs/stats.js +7 -7
- package/clis/cnblogs/whoami.js +1 -1
- package/clis/codex/_actions.js +3 -3
- package/clis/codex/archive.js +1 -1
- package/clis/codex/ask.js +6 -6
- package/clis/codex/model.js +8 -8
- package/clis/codex/pin.js +1 -1
- package/clis/codex/rename.js +4 -4
- package/clis/codex/send.js +3 -3
- package/clis/codex/sidebar.js +1 -1
- package/clis/coingecko/categories.js +1 -1
- package/clis/coingecko/coin.js +1 -1
- package/clis/coingecko/derivatives.js +1 -1
- package/clis/coingecko/exchanges.js +1 -1
- package/clis/coingecko/global.js +1 -1
- package/clis/coingecko/trending.js +1 -1
- package/clis/confluence/search.js +1 -1
- package/clis/coupang/product.js +3 -3
- package/clis/coupang/utils.js +1 -1
- package/clis/crates/crate.js +1 -1
- package/clis/crates/search.js +1 -1
- package/clis/crates/utils.js +1 -1
- package/clis/csdn/article.js +13 -13
- package/clis/csdn/columns.js +1 -1
- package/clis/csdn/login.js +1 -1
- package/clis/csdn/stats.js +4 -4
- package/clis/csdn/whoami.js +1 -1
- package/clis/cto51/article.js +1 -1
- package/clis/cto51/whoami.js +1 -1
- package/clis/ctrip/flight.js +2 -2
- package/clis/ctrip/hotel-search.js +3 -3
- package/clis/ctrip/hotel-suggest.js +1 -1
- package/clis/ctrip/search.js +1 -1
- package/clis/ctrip/utils.js +6 -6
- package/clis/cursor/ask.js +5 -5
- package/clis/cursor/composer.js +2 -2
- package/clis/cursor/model.js +4 -4
- package/clis/cursor/send.js +2 -2
- package/clis/dblp/author.js +1 -1
- package/clis/dblp/paper.js +1 -1
- package/clis/dblp/search.js +1 -1
- package/clis/dblp/utils.js +1 -1
- package/clis/dblp/venue.js +1 -1
- package/clis/deepseek/ask.js +1 -1
- package/clis/deepseek/auth.js +2 -2
- package/clis/deepseek/detail.js +1 -1
- package/clis/deepseek/new.js +1 -1
- package/clis/deepseek/read.js +1 -1
- package/clis/deepseek/send.js +7 -7
- package/clis/deepseek/utils.js +25 -25
- package/clis/defillama/protocol.js +1 -1
- package/clis/defillama/protocols.js +1 -1
- package/clis/defillama/utils.js +1 -1
- package/clis/devto/auth.js +2 -2
- package/clis/devto/latest.js +1 -1
- package/clis/devto/publish.js +5 -5
- package/clis/devto/read.js +2 -2
- package/clis/devto/stats.js +3 -3
- package/clis/dianping/auth.js +2 -2
- package/clis/dianping/cityResolver.js +2 -2
- package/clis/dianping/search.js +1 -1
- package/clis/dianping/shop.js +1 -1
- package/clis/dianping/utils.js +1 -1
- package/clis/discord-app/delete.js +3 -3
- package/clis/discord-app/read.js +1 -1
- package/clis/discord-app/thread-read.js +1 -1
- package/clis/discord-web/auth.js +2 -2
- package/clis/discord-web/send.js +5 -5
- package/clis/dockerhub/image.js +1 -1
- package/clis/dockerhub/search.js +1 -1
- package/clis/dockerhub/utils.js +1 -1
- package/clis/dongchedi/koubei.js +1 -1
- package/clis/dongchedi/models.js +1 -1
- package/clis/dongchedi/score.js +1 -1
- package/clis/dongchedi/search.js +1 -1
- package/clis/dongchedi/series.js +1 -1
- package/clis/dongchedi/specs.js +1 -1
- package/clis/dongchedi/utils.js +1 -1
- package/clis/douban/article.js +3 -3
- package/clis/douban/auth.js +2 -2
- package/clis/douban/download.js +1 -1
- package/clis/douban/utils.js +23 -23
- package/clis/doubao/auth.js +3 -3
- package/clis/doubao/utils.js +39 -39
- package/clis/doubao-app/ask.js +1 -1
- package/clis/doubao-app/utils.js +4 -4
- package/clis/douyin/_shared/browser-fetch.js +7 -7
- package/clis/douyin/_shared/draft-cache.js +1 -1
- package/clis/douyin/_shared/imagex-upload.js +1 -1
- package/clis/douyin/_shared/sts2.js +1 -1
- package/clis/douyin/_shared/text-extra.js +1 -1
- package/clis/douyin/_shared/tos-upload.js +4 -4
- package/clis/douyin/_shared/transcode.js +1 -1
- package/clis/douyin/_shared/vod-upload.js +4 -4
- package/clis/douyin/draft.js +18 -18
- package/clis/douyin/drafts.js +1 -1
- package/clis/douyin/publish-image.js +12 -12
- package/clis/douyin/publish.js +9 -9
- package/clis/douyin/search.js +3 -3
- package/clis/douyin/videos.js +1 -1
- package/clis/eastmoney/_secid.js +1 -1
- package/clis/eastmoney/announcement.js +1 -1
- package/clis/eastmoney/article.js +1 -1
- package/clis/eastmoney/convertible.js +1 -1
- package/clis/eastmoney/etf.js +1 -1
- package/clis/eastmoney/holders.js +1 -1
- package/clis/eastmoney/index-board.js +1 -1
- package/clis/eastmoney/kline.js +1 -1
- package/clis/eastmoney/kuaixun.js +1 -1
- package/clis/eastmoney/longhu.js +1 -1
- package/clis/eastmoney/money-flow.js +1 -1
- package/clis/eastmoney/northbound.js +1 -1
- package/clis/eastmoney/quote.js +1 -1
- package/clis/eastmoney/rank.js +1 -1
- package/clis/eastmoney/sectors.js +1 -1
- package/clis/endoflife/product.js +1 -1
- package/clis/endoflife/utils.js +1 -1
- package/clis/facebook/comment.js +8 -8
- package/clis/facebook/feed.js +4 -4
- package/clis/facebook/like.js +5 -5
- package/clis/facebook/notifications.js +3 -3
- package/clis/facebook/post.js +11 -11
- package/clis/facebook/search.js +3 -3
- package/clis/flathub/app.js +1 -1
- package/clis/flathub/search.js +1 -1
- package/clis/flathub/utils.js +1 -1
- package/clis/flomo/memos.js +1 -1
- package/clis/gemini/deep-research-result.js +4 -4
- package/clis/gemini/deep-research.js +1 -1
- package/clis/gemini/detail.js +1 -1
- package/clis/gemini/history.js +1 -1
- package/clis/gemini/image.js +2 -2
- package/clis/gemini/status.js +1 -1
- package/clis/gemini/utils.js +43 -43
- package/clis/geogebra/hexagon.js +1 -1
- package/clis/geogebra/info.js +3 -3
- package/clis/geogebra/triangle.js +1 -1
- package/clis/geogebra/utils.js +11 -11
- package/clis/ghost/login.js +1 -1
- package/clis/ghost/shared.js +2 -2
- package/clis/gitee/auth.js +2 -2
- package/clis/github-trending/repos.js +1 -1
- package/clis/google/news.js +1 -1
- package/clis/google/search.js +2 -2
- package/clis/google/suggest.js +1 -1
- package/clis/google/trends.js +1 -1
- package/clis/google/utils.js +1 -1
- package/clis/goproxy/module.js +1 -1
- package/clis/goproxy/utils.js +1 -1
- package/clis/goproxy/versions.js +1 -1
- package/clis/gov-policy/recent.js +2 -2
- package/clis/gov-policy/search.js +2 -2
- package/clis/grok/ask.js +1 -1
- package/clis/grok/detail.js +1 -1
- package/clis/grok/image.js +8 -8
- package/clis/grok/pin.js +1 -1
- package/clis/grok/send.js +1 -1
- package/clis/grok/status.js +1 -1
- package/clis/grok/utils.js +21 -21
- package/clis/guazi/browse.js +1 -1
- package/clis/guazi/car.js +1 -1
- package/clis/guazi/utils.js +1 -1
- package/clis/hackernews/auth.js +2 -2
- package/clis/hackernews/comment.js +8 -8
- package/clis/hackernews/read.js +7 -7
- package/clis/hackernews/submit.js +7 -7
- package/clis/hashnode/auth.js +3 -3
- package/clis/hashnode/publish.js +14 -14
- package/clis/hf/auth.js +2 -2
- package/clis/hf/models.js +1 -1
- package/clis/hf/paper.js +1 -1
- package/clis/hf/spaces.js +1 -1
- package/clis/hf/top.js +1 -1
- package/clis/homebrew/cask.js +1 -1
- package/clis/homebrew/formula.js +1 -1
- package/clis/homebrew/popular.js +1 -1
- package/clis/homebrew/utils.js +1 -1
- package/clis/huodongxing/events.js +1 -1
- package/clis/hupu/detail.js +4 -4
- package/clis/hupu/hot.js +3 -3
- package/clis/hupu/reply.js +1 -1
- package/clis/hupu/search.js +1 -1
- package/clis/hupu/unlike.js +1 -1
- package/clis/hupu/utils.js +10 -10
- package/clis/imdb/person.js +2 -2
- package/clis/imdb/reviews.js +3 -3
- package/clis/imdb/search.js +2 -2
- package/clis/imdb/title.js +1 -1
- package/clis/imdb/top.js +1 -1
- package/clis/imdb/trending.js +1 -1
- package/clis/imdb/utils.js +13 -13
- package/clis/imooc/article.js +6 -6
- package/clis/imooc/login.js +1 -1
- package/clis/imooc/whoami.js +1 -1
- package/clis/indeed/job.js +2 -2
- package/clis/indeed/search.js +2 -2
- package/clis/indeed/utils.js +1 -1
- package/clis/infoq/article.js +2 -2
- package/clis/infoq/login.js +1 -1
- package/clis/infoq/whoami.js +1 -1
- package/clis/instagram/_shared/private-publish.js +4 -4
- package/clis/instagram/_shared/protocol-capture.js +9 -9
- package/clis/instagram/detail.js +3 -3
- package/clis/instagram/post.js +25 -25
- package/clis/instagram/reel.js +18 -18
- package/clis/instagram/story.js +4 -4
- package/clis/instagram/user.js +2 -2
- package/clis/jd/item.js +65 -65
- package/clis/jianshu/article.js +1 -1
- package/clis/jianshu/login.js +1 -1
- package/clis/jianshu/notebooks.js +1 -1
- package/clis/jianshu/whoami.js +1 -1
- package/clis/jianyu/search.js +6 -6
- package/clis/jianyu/shared/procurement-contract.js +1 -1
- package/clis/jike/api.js +6 -6
- package/clis/jike/auth.js +3 -3
- package/clis/jike/comment.js +1 -1
- package/clis/jike/create.js +6 -6
- package/clis/jike/feed.js +3 -3
- package/clis/jike/like.js +1 -1
- package/clis/jike/notifications.js +3 -3
- package/clis/jike/repost.js +13 -13
- package/clis/jike/search.js +3 -3
- package/clis/jimeng/auth.js +2 -2
- package/clis/jimeng/generate.js +10 -10
- package/clis/jira/shared.js +1 -1
- package/clis/juejin/article.js +4 -4
- package/clis/juejin/categories.js +1 -1
- package/clis/juejin/hot.js +1 -1
- package/clis/juejin/login.js +1 -1
- package/clis/juejin/recommend.js +1 -1
- package/clis/juejin/stats.js +3 -3
- package/clis/juejin/tags.js +1 -1
- package/clis/juejin/utils.js +1 -1
- package/clis/juejin/whoami.js +1 -1
- package/clis/ke/utils.js +4 -4
- package/clis/kimi/_utils.js +7 -7
- package/clis/kimi/audit-extras.js +14 -14
- package/clis/kimi/auth.js +3 -3
- package/clis/kimi/chat.js +15 -15
- package/clis/kimi/storage.js +5 -5
- package/clis/kimi/ui.js +13 -13
- package/clis/kimi/usage.js +3 -3
- package/clis/kuaishou/auth.js +1 -1
- package/clis/kuaishou/publish.js +6 -6
- package/clis/lesswrong/_helpers.js +5 -5
- package/clis/lesswrong/comments.js +5 -5
- package/clis/lichess/top.js +1 -1
- package/clis/lichess/user.js +1 -1
- package/clis/lichess/utils.js +1 -1
- package/clis/linkedin/comment.js +1 -1
- package/clis/linkedin/connect.js +11 -11
- package/clis/linkedin/create.js +5 -5
- package/clis/linkedin/follow.js +1 -1
- package/clis/linkedin/inbox.js +1 -1
- package/clis/linkedin/job-detail.js +3 -3
- package/clis/linkedin/like.js +1 -1
- package/clis/linkedin/notifications.js +1 -1
- package/clis/linkedin/people-search.js +1 -1
- package/clis/linkedin/post-comments.js +1 -1
- package/clis/linkedin/post-detail.js +1 -1
- package/clis/linkedin/profile-analytics.js +1 -1
- package/clis/linkedin/profile-api.js +13 -13
- package/clis/linkedin/profile-experience.js +1 -1
- package/clis/linkedin/profile-projects.js +1 -1
- package/clis/linkedin/profile-read.js +3 -3
- package/clis/linkedin/reply.js +1 -1
- package/clis/linkedin/repost.js +1 -1
- package/clis/linkedin/safe-send.js +8 -8
- package/clis/linkedin/salesnav-inbox.js +5 -5
- package/clis/linkedin/salesnav-message.js +3 -3
- package/clis/linkedin/salesnav-search.js +4 -4
- package/clis/linkedin/salesnav-thread.js +1 -1
- package/clis/linkedin/search-api.js +3 -3
- package/clis/linkedin/search.js +8 -8
- package/clis/linkedin/social-api.js +31 -31
- package/clis/linkedin/timeline.js +3 -3
- package/clis/linkedin-learning/search.js +2 -2
- package/clis/linkedin-learning/trending.js +2 -2
- package/clis/linux-do/feed.js +4 -4
- package/clis/linux-do/topic-content.js +8 -8
- package/clis/lobsters/domain.js +1 -1
- package/clis/lobsters/read.js +7 -7
- package/clis/maimai/auth.js +2 -2
- package/clis/maimai/search-talents.js +4 -4
- package/clis/manus/_utils.js +1 -1
- package/clis/mastodon/login.js +1 -1
- package/clis/mastodon/post.js +1 -1
- package/clis/mastodon/shared.js +12 -12
- package/clis/mastodon/whoami.js +1 -1
- package/clis/maven/artifact.js +1 -1
- package/clis/maven/search.js +1 -1
- package/clis/maven/utils.js +1 -1
- package/clis/mdn/search.js +1 -1
- package/clis/medium/article.js +5 -5
- package/clis/medium/login.js +1 -1
- package/clis/medium/stats.js +3 -3
- package/clis/medium/tag.js +1 -1
- package/clis/medium/whoami.js +1 -1
- package/clis/mubu/notes.js +1 -1
- package/clis/mubu/utils.js +15 -15
- package/clis/note/auth.js +2 -2
- package/clis/note/note-utils.js +2 -2
- package/clis/note/publish.js +8 -8
- package/clis/notebooklm/add-source.js +8 -8
- package/clis/notebooklm/create.js +1 -1
- package/clis/notebooklm/generate-slides.js +1 -1
- package/clis/notebooklm/notes-get.js +1 -1
- package/clis/notebooklm/rpc.js +8 -8
- package/clis/notebooklm/source-fulltext.js +1 -1
- package/clis/notebooklm/utils.js +10 -10
- package/clis/nowcoder/auth.js +2 -2
- package/clis/nowcoder/comment.js +1 -1
- package/clis/nowcoder/comments.js +1 -1
- package/clis/nowcoder/dm-list.js +1 -1
- package/clis/nowcoder/dm-read.js +1 -1
- package/clis/nowcoder/dm-send.js +1 -1
- package/clis/nowcoder/drafts.js +1 -1
- package/clis/nowcoder/inbox.js +1 -1
- package/clis/nowcoder/like.js +1 -1
- package/clis/nowcoder/my.js +1 -1
- package/clis/nowcoder/post.js +1 -1
- package/clis/nowcoder/utils.js +13 -13
- package/clis/npm/downloads.js +1 -1
- package/clis/npm/package.js +1 -1
- package/clis/npm/search.js +1 -1
- package/clis/npm/utils.js +1 -1
- package/clis/nuget/package.js +1 -1
- package/clis/nuget/search.js +1 -1
- package/clis/nuget/utils.js +1 -1
- package/clis/nvd/cve.js +1 -1
- package/clis/oeis/search.js +1 -1
- package/clis/oeis/sequence.js +1 -1
- package/clis/oeis/utils.js +1 -1
- package/clis/ones/common.js +6 -6
- package/clis/ones/enrich-tasks.js +1 -1
- package/clis/ones/my-tasks.js +1 -1
- package/clis/ones/resolve-labels.js +1 -1
- package/clis/ones/task-helpers.js +1 -1
- package/clis/ones/task.js +1 -1
- package/clis/ones/worklog.js +7 -7
- package/clis/openalex/search.js +1 -1
- package/clis/openalex/utils.js +1 -1
- package/clis/openalex/work.js +1 -1
- package/clis/openfda/drug-label.js +1 -1
- package/clis/openfda/food-recall.js +1 -1
- package/clis/openfda/utils.js +1 -1
- package/clis/openreview/author.js +1 -1
- package/clis/openreview/paper.js +1 -1
- package/clis/openreview/reviews.js +3 -3
- package/clis/openreview/search.js +1 -1
- package/clis/openreview/utils.js +1 -1
- package/clis/openreview/venue.js +1 -1
- package/clis/oschina/article.js +1 -1
- package/clis/oschina/catalogs.js +1 -1
- package/clis/oschina/login.js +1 -1
- package/clis/oschina/stats.js +6 -6
- package/clis/oschina/whoami.js +1 -1
- package/clis/osv/query.js +1 -1
- package/clis/osv/utils.js +1 -1
- package/clis/osv/vulnerability.js +1 -1
- package/clis/packagist/package.js +1 -1
- package/clis/packagist/search.js +1 -1
- package/clis/packagist/utils.js +1 -1
- package/clis/pinterest/api.js +1 -1
- package/clis/pinterest/auth.js +1 -1
- package/clis/pinterest/boards.js +1 -1
- package/clis/pinterest/client.js +6 -6
- package/clis/pinterest/publish.js +5 -5
- package/clis/pixiv/auth.js +2 -2
- package/clis/pixiv/download.js +1 -1
- package/clis/pixiv/illusts.js +1 -1
- package/clis/pixiv/search.js +1 -1
- package/clis/pixiv/utils.js +3 -3
- package/clis/powerchina/auth.js +2 -2
- package/clis/powerchina/search.js +1 -1
- package/clis/producthunt/browse.js +2 -2
- package/clis/producthunt/hot.js +2 -2
- package/clis/producthunt/posts.js +1 -1
- package/clis/producthunt/today.js +1 -1
- package/clis/producthunt/utils.js +1 -1
- package/clis/pypi/downloads.js +1 -1
- package/clis/pypi/package.js +1 -1
- package/clis/pypi/utils.js +1 -1
- package/clis/qiita/auth.js +1 -1
- package/clis/qiita/gql.js +6 -6
- package/clis/qiita/publish.js +4 -4
- package/clis/qiita/stats.js +4 -4
- package/clis/qoder/_utils.js +16 -16
- package/clis/qoder/composer.js +1 -1
- package/clis/qoder/quest.js +1 -1
- package/clis/qoder/ui.js +14 -14
- package/clis/quark/auth.js +2 -2
- package/clis/quark/utils.js +2 -2
- package/clis/quora/answer-comments.js +3 -3
- package/clis/quora/create-answer.js +4 -4
- package/clis/quora/create-question.js +3 -3
- package/clis/quora/shared.js +17 -17
- package/clis/quora/whoami.js +1 -1
- package/clis/qwen/ask.js +1 -1
- package/clis/qwen/auth.js +3 -3
- package/clis/qwen/detail.js +1 -1
- package/clis/qwen/image.js +5 -5
- package/clis/qwen/status.js +1 -1
- package/clis/qwen/utils.js +16 -16
- package/clis/reddit/home.js +3 -3
- package/clis/reddit/read.js +10 -10
- package/clis/reddit/reply.js +4 -4
- package/clis/reddit/submit.js +11 -11
- package/clis/reddit/subreddit-info.js +3 -3
- package/clis/reddit/subscribed.js +4 -4
- package/clis/reddit/whoami.js +2 -2
- package/clis/rednote/comments.js +1 -1
- package/clis/rednote/download.js +1 -1
- package/clis/rednote/feed.js +1 -1
- package/clis/rednote/note.js +1 -1
- package/clis/rednote/notifications.js +2 -2
- package/clis/rednote/search.js +2 -2
- package/clis/rest-countries/country.js +1 -1
- package/clis/rest-countries/region.js +1 -1
- package/clis/rest-countries/utils.js +1 -1
- package/clis/reuters/article-detail.js +1 -1
- package/clis/reuters/auth.js +3 -3
- package/clis/reuters/search.js +1 -1
- package/clis/reuters/utils.js +4 -4
- package/clis/rfc/rfc.js +1 -1
- package/clis/rfc/utils.js +1 -1
- package/clis/rubygems/gem.js +1 -1
- package/clis/rubygems/search.js +1 -1
- package/clis/rubygems/utils.js +1 -1
- package/clis/segmentfault/article.js +3 -3
- package/clis/segmentfault/channels.js +1 -1
- package/clis/segmentfault/login.js +1 -1
- package/clis/segmentfault/stats.js +4 -4
- package/clis/segmentfault/tags.js +1 -1
- package/clis/segmentfault/whoami.js +1 -1
- package/clis/semanticscholar/citations.js +1 -1
- package/clis/semanticscholar/paper.js +1 -1
- package/clis/semanticscholar/recommendations.js +1 -1
- package/clis/semanticscholar/search.js +1 -1
- package/clis/semanticscholar/utils.js +1 -1
- package/clis/sinafinance/news.js +1 -1
- package/clis/sinafinance/stock-rank.js +1 -1
- package/clis/sinafinance/stock.js +1 -1
- package/clis/slock/attachment-download.js +1 -1
- package/clis/slock/attachment-upload.js +7 -7
- package/clis/slock/attachment-url.js +1 -1
- package/clis/slock/auth-verify.js +1 -1
- package/clis/slock/bookmark-add.js +1 -1
- package/clis/slock/bookmark-remove.js +1 -1
- package/clis/slock/channel-action.js +1 -1
- package/clis/slock/channel-create.js +1 -1
- package/clis/slock/channel-files.js +1 -1
- package/clis/slock/channel-list.js +1 -1
- package/clis/slock/channel-mark.js +1 -1
- package/clis/slock/channel-members.js +1 -1
- package/clis/slock/channel-unarchive.js +1 -1
- package/clis/slock/dm-list.js +1 -1
- package/clis/slock/errors.js +1 -1
- package/clis/slock/in-page.js +28 -28
- package/clis/slock/inbox-done.js +5 -5
- package/clis/slock/inbox.js +1 -1
- package/clis/slock/message-read.js +22 -22
- package/clis/slock/message-search.js +10 -10
- package/clis/slock/message-send.js +25 -25
- package/clis/slock/reaction-add.js +1 -1
- package/clis/slock/reaction-remove.js +1 -1
- package/clis/slock/resolve.js +1 -1
- package/clis/slock/server-list.js +2 -2
- package/clis/slock/task-claim.js +4 -4
- package/clis/slock/task-convert.js +13 -13
- package/clis/slock/task-create.js +1 -1
- package/clis/slock/task-delete.js +5 -5
- package/clis/slock/task-get.js +5 -5
- package/clis/slock/task-list-server.js +4 -4
- package/clis/slock/task-list.js +5 -5
- package/clis/slock/task-status.js +3 -3
- package/clis/slock/task-unclaim.js +3 -3
- package/clis/slock/thread-follow.js +1 -1
- package/clis/slock/thread-state.js +1 -1
- package/clis/slock/unread-summary.js +5 -5
- package/clis/slock/whoami.js +1 -1
- package/clis/smzdm/search.js +3 -3
- package/clis/sohu/article.js +1 -1
- package/clis/sohu/attributes.js +1 -1
- package/clis/sohu/categories.js +1 -1
- package/clis/sohu/channels.js +1 -1
- package/clis/sohu/columns.js +1 -1
- package/clis/sohu/login.js +1 -1
- package/clis/sohu/stats.js +3 -3
- package/clis/sohu/topics.js +1 -1
- package/clis/sohu/whoami.js +1 -1
- package/clis/spotify/spotify.js +1 -1
- package/clis/stackoverflow/read.js +6 -6
- package/clis/stackoverflow/related.js +1 -1
- package/clis/stackoverflow/tag.js +1 -1
- package/clis/stackoverflow/user.js +1 -1
- package/clis/stackoverflow/utils.js +1 -1
- package/clis/steam/app.js +1 -1
- package/clis/steam/search.js +1 -1
- package/clis/steam/utils.js +1 -1
- package/clis/substack/auth.js +2 -2
- package/clis/substack/post-utils.js +2 -2
- package/clis/substack/publish.js +5 -5
- package/clis/suno/auth.js +2 -2
- package/clis/suno/download.js +5 -5
- package/clis/suno/generate.js +3 -3
- package/clis/suno/list.js +1 -1
- package/clis/suno/status.js +1 -1
- package/clis/suno/utils.js +29 -29
- package/clis/telegram/send.js +7 -7
- package/clis/telegram/shared.js +2 -2
- package/clis/telegram/whoami.js +1 -1
- package/clis/test-utils.js +1 -1
- package/clis/threads/post.js +23 -23
- package/clis/threads/shared.js +3 -3
- package/clis/threads/whoami.js +1 -1
- package/clis/tieba/hot.js +3 -3
- package/clis/tieba/posts.js +1 -1
- package/clis/tieba/read.js +2 -2
- package/clis/tieba/search.js +3 -3
- package/clis/tieba/utils.js +1 -1
- package/clis/tiktok/comment.js +2 -2
- package/clis/tiktok/creator-videos.js +3 -3
- package/clis/tiktok/explore.js +3 -3
- package/clis/tiktok/follow.js +8 -8
- package/clis/tiktok/following.js +4 -4
- package/clis/tiktok/friends.js +7 -7
- package/clis/tiktok/live.js +3 -3
- package/clis/tiktok/notifications.js +6 -6
- package/clis/tiktok/publish.js +17 -17
- package/clis/tiktok/unfollow.js +4 -4
- package/clis/tiktok/user.js +2 -2
- package/clis/tiktok/utils.js +1 -1
- package/clis/toutiao/article.js +1 -1
- package/clis/toutiao/articles.js +2 -2
- package/clis/toutiao/auth.js +2 -2
- package/clis/toutiao/hot.js +1 -1
- package/clis/toutiao/recommend.js +1 -1
- package/clis/toutiao/utils.js +2 -2
- package/clis/trae-solo/_actions.js +4 -4
- package/clis/trae-solo/_fs.js +5 -5
- package/clis/trae-solo/_state.js +2 -2
- package/clis/trae-solo/automation.js +4 -4
- package/clis/trae-solo/mode.js +4 -4
- package/clis/trae-solo/model.js +4 -4
- package/clis/trae-solo/renderer-storage.js +4 -4
- package/clis/trae-solo/settings.js +1 -1
- package/clis/trae-solo/skill-fs.js +1 -1
- package/clis/trae-solo/skill.js +12 -12
- package/clis/trae-solo/state-fs.js +2 -2
- package/clis/trae-solo/task-fs.js +5 -5
- package/clis/trae-solo/workspaces-fs.js +1 -1
- package/clis/tumblr/auth.js +2 -2
- package/clis/tumblr/publish.js +3 -3
- package/clis/tvmaze/search.js +1 -1
- package/clis/tvmaze/show.js +1 -1
- package/clis/tvmaze/utils.js +1 -1
- package/clis/twitter/accept.js +7 -7
- package/clis/twitter/article.js +7 -7
- package/clis/twitter/bookmark-folder.js +3 -3
- package/clis/twitter/bookmark-folders.js +3 -3
- package/clis/twitter/bookmarks.js +4 -4
- package/clis/twitter/delete.js +5 -5
- package/clis/twitter/device-follow.js +3 -3
- package/clis/twitter/dm-list.js +1 -1
- package/clis/twitter/dm-read.js +1 -1
- package/clis/twitter/dm-send.js +5 -5
- package/clis/twitter/dm-shared.js +3 -3
- package/clis/twitter/download.js +6 -6
- package/clis/twitter/followers.js +5 -5
- package/clis/twitter/following.js +2 -2
- package/clis/twitter/like.js +3 -3
- package/clis/twitter/likes.js +8 -8
- package/clis/twitter/list-add-core.js +9 -9
- package/clis/twitter/list-create.js +5 -5
- package/clis/twitter/list-remove-core.js +9 -9
- package/clis/twitter/list-tweets.js +7 -7
- package/clis/twitter/lists.js +6 -6
- package/clis/twitter/notifications.js +2 -2
- package/clis/twitter/post.js +24 -24
- package/clis/twitter/profile.js +7 -7
- package/clis/twitter/quote.js +7 -7
- package/clis/twitter/reply-dm.js +7 -7
- package/clis/twitter/reply.js +12 -12
- package/clis/twitter/retweet.js +3 -3
- package/clis/twitter/scheduled-delete.js +3 -3
- package/clis/twitter/scheduled-list.js +2 -2
- package/clis/twitter/scheduled-utils.js +3 -3
- package/clis/twitter/search.js +5 -5
- package/clis/twitter/shared.js +6 -6
- package/clis/twitter/thread.js +4 -4
- package/clis/twitter/timeline.js +3 -3
- package/clis/twitter/trending.js +2 -2
- package/clis/twitter/tweets.js +11 -11
- package/clis/twitter/unlike.js +3 -3
- package/clis/twitter/unretweet.js +3 -3
- package/clis/twitter/utils.js +6 -6
- package/clis/upwork/detail.js +2 -2
- package/clis/upwork/feed.js +2 -2
- package/clis/upwork/search.js +2 -2
- package/clis/upwork/utils.js +1 -1
- package/clis/v2ex/auth.js +2 -2
- package/clis/v2ex/daily.js +3 -3
- package/clis/v2ex/me.js +2 -2
- package/clis/v2ex/notifications.js +2 -2
- package/clis/vk/post.js +1 -1
- package/clis/vk/shared.js +2 -2
- package/clis/vk/whoami.js +1 -1
- package/clis/web/read.js +8 -8
- package/clis/wechat-channels/auth.js +2 -2
- package/clis/wechat-channels/publish.js +30 -30
- package/clis/weibo/article.js +1 -1
- package/clis/weibo/auth.js +3 -3
- package/clis/weibo/comments.js +1 -1
- package/clis/weibo/delete.js +2 -2
- package/clis/weibo/feed.js +3 -3
- package/clis/weibo/hot.js +1 -1
- package/clis/weibo/publish.js +10 -10
- package/clis/weibo/search.js +2 -2
- package/clis/weibo/user-posts.js +3 -3
- package/clis/weibo/user.js +2 -2
- package/clis/weibo/utils.js +3 -3
- package/clis/weixin/article.js +1 -1
- package/clis/weixin/create-draft.js +26 -26
- package/clis/weixin/download.js +2 -2
- package/clis/weixin/login.js +1 -1
- package/clis/weixin/search.js +2 -2
- package/clis/weixin/stats.js +3 -3
- package/clis/weixin/whoami.js +1 -1
- package/clis/weread/ai-outline.js +2 -2
- package/clis/weread/book-search.js +2 -2
- package/clis/weread/book.js +2 -2
- package/clis/weread/notebooks.js +1 -1
- package/clis/weread/search.js +1 -1
- package/clis/weread/shelf.js +1 -1
- package/clis/weread/utils.js +6 -6
- package/clis/weread-official/book.js +1 -1
- package/clis/weread-official/discover.js +1 -1
- package/clis/weread-official/list-apis.js +1 -1
- package/clis/weread-official/notes.js +1 -1
- package/clis/weread-official/readdata.js +1 -1
- package/clis/weread-official/review.js +1 -1
- package/clis/weread-official/search.js +1 -1
- package/clis/weread-official/shelf.js +1 -1
- package/clis/weread-official/utils.js +1 -1
- package/clis/wikidata/entity.js +1 -1
- package/clis/wikidata/search.js +1 -1
- package/clis/wikidata/utils.js +1 -1
- package/clis/wikipedia/page.js +1 -1
- package/clis/wikipedia/trending.js +1 -1
- package/clis/wikipedia/utils.js +1 -1
- package/clis/wordpress/login.js +1 -1
- package/clis/wordpress/publish.js +1 -1
- package/clis/wordpress/shared.js +3 -3
- package/clis/wordpress/whoami.js +1 -1
- package/clis/woshipm/article.js +1 -1
- package/clis/woshipm/login.js +1 -1
- package/clis/woshipm/stats.js +4 -4
- package/clis/woshipm/whoami.js +1 -1
- package/clis/wttr/current.js +1 -1
- package/clis/wttr/forecast.js +1 -1
- package/clis/wttr/utils.js +1 -1
- package/clis/xianyu/collect.js +1 -1
- package/clis/xianyu/inbox.js +1 -1
- package/clis/xianyu/item-stats.js +2 -2
- package/clis/xianyu/location.js +1 -1
- package/clis/xianyu/manage.js +1 -1
- package/clis/xianyu/messages.js +1 -1
- package/clis/xianyu/mtop.js +5 -5
- package/clis/xianyu/order.js +1 -1
- package/clis/xianyu/promote-stats.js +2 -2
- package/clis/xianyu/publish.js +17 -17
- package/clis/xianyu/rate.js +1 -1
- package/clis/xianyu/reply.js +1 -1
- package/clis/xianyu/search.js +8 -8
- package/clis/xianyu/seller-data.js +1 -1
- package/clis/xianyu/seller-list.js +1 -1
- package/clis/xianyu/user.js +1 -1
- package/clis/xiaoe/catalog.js +2 -2
- package/clis/xiaoe/content.js +2 -2
- package/clis/xiaoe/courses.js +2 -2
- package/clis/xiaohongshu/ask.js +6 -6
- package/clis/xiaohongshu/comments.js +6 -6
- package/clis/xiaohongshu/creator-note-detail.js +7 -7
- package/clis/xiaohongshu/creator-notes-summary.js +1 -1
- package/clis/xiaohongshu/creator-notes.js +13 -13
- package/clis/xiaohongshu/creator-profile.js +2 -2
- package/clis/xiaohongshu/creator-stats.js +2 -2
- package/clis/xiaohongshu/delete-note.js +7 -7
- package/clis/xiaohongshu/download.js +4 -4
- package/clis/xiaohongshu/feed.js +2 -2
- package/clis/xiaohongshu/follow.js +3 -3
- package/clis/xiaohongshu/human.js +3 -3
- package/clis/xiaohongshu/note-helpers.js +1 -1
- package/clis/xiaohongshu/note.js +2 -2
- package/clis/xiaohongshu/notifications.js +1 -1
- package/clis/xiaohongshu/publish-video.js +8 -8
- package/clis/xiaohongshu/publish.js +59 -59
- package/clis/xiaohongshu/search.js +8 -8
- package/clis/xiaohongshu/unfollow.js +4 -4
- package/clis/xiaohongshu/user-helpers.js +1 -1
- package/clis/xiaohongshu/user.js +2 -2
- package/clis/xiaoyuzhou/auth.js +3 -3
- package/clis/xiaoyuzhou/download.js +1 -1
- package/clis/xiaoyuzhou/utils.js +1 -1
- package/clis/xueqiu/article.js +4 -4
- package/clis/xueqiu/comments.js +4 -4
- package/clis/xueqiu/danjuan-utils.js +4 -4
- package/clis/xueqiu/earnings-date.js +1 -1
- package/clis/xueqiu/events.js +3 -3
- package/clis/xueqiu/hashtags.js +3 -3
- package/clis/xueqiu/stocks.js +3 -3
- package/clis/xueqiu/users.js +3 -3
- package/clis/xueqiu/utils.js +3 -3
- package/clis/yahoo-finance/quote.js +1 -1
- package/clis/yollomi/background.js +1 -1
- package/clis/yollomi/edit.js +1 -1
- package/clis/yollomi/face-swap.js +1 -1
- package/clis/yollomi/generate.js +1 -1
- package/clis/yollomi/object-remover.js +1 -1
- package/clis/yollomi/remove-bg.js +1 -1
- package/clis/yollomi/restore.js +1 -1
- package/clis/yollomi/try-on.js +1 -1
- package/clis/yollomi/upload.js +4 -4
- package/clis/yollomi/upscale.js +1 -1
- package/clis/yollomi/utils.js +4 -4
- package/clis/yollomi/video.js +1 -1
- package/clis/youtube/channel.js +4 -4
- package/clis/youtube/feed.js +2 -2
- package/clis/youtube/like.js +5 -5
- package/clis/youtube/playlist.js +7 -7
- package/clis/youtube/publish.js +11 -11
- package/clis/youtube/search.js +3 -3
- package/clis/youtube/subscribe.js +7 -7
- package/clis/youtube/subscriptions.js +1 -1
- package/clis/youtube/transcript-group.js +2 -2
- package/clis/youtube/transcript.js +13 -13
- package/clis/youtube/unlike.js +5 -5
- package/clis/youtube/unsubscribe.js +7 -7
- package/clis/youtube/utils.js +3 -3
- package/clis/youtube/video.js +4 -4
- package/clis/youtube/watch-later.js +2 -2
- package/clis/yuanbao/ask.js +18 -18
- package/clis/yuanbao/detail.js +1 -1
- package/clis/yuanbao/read.js +1 -1
- package/clis/yuanbao/shared.js +9 -9
- package/clis/yuanbao/status.js +1 -1
- package/clis/yuque/article.js +1 -1
- package/clis/yuque/whoami.js +1 -1
- package/clis/zhihu/answer-comments.js +2 -2
- package/clis/zhihu/answer-detail.js +3 -3
- package/clis/zhihu/answer.js +1 -1
- package/clis/zhihu/article-transform.js +1 -1
- package/clis/zhihu/article.js +1 -1
- package/clis/zhihu/auth.js +2 -2
- package/clis/zhihu/collection.js +3 -3
- package/clis/zhihu/collections.js +3 -3
- package/clis/zhihu/download.js +2 -2
- package/clis/zhihu/image-profile.js +6 -6
- package/clis/zhihu/paginate.js +3 -3
- package/clis/zhihu/pin.js +4 -4
- package/clis/zhihu/question.js +3 -3
- package/clis/zhihu/recommend.js +3 -3
- package/clis/zhihu/search.js +3 -3
- package/clis/zhihu/stats.js +3 -3
- package/clis/zhihu/user-arg.js +1 -1
- package/clis/zhihu/write-shared.js +7 -7
- package/clis/zlibrary/utils.js +6 -6
- package/clis/zsxq/auth.js +3 -3
- package/clis/zsxq/search.js +1 -1
- package/clis/zsxq/topic.js +1 -1
- package/clis/zsxq/utils.js +5 -5
- package/dist/src/adapter-source.js +1 -1
- package/dist/src/browser/analyze.js +1 -1
- package/dist/src/browser/article-extract.js +2 -2
- package/dist/src/browser/ax-snapshot.js +2 -2
- package/dist/src/browser/base-page.js +25 -25
- package/dist/src/browser/bridge.js +1 -1
- package/dist/src/browser/cdp.js +1 -1
- package/dist/src/browser/daemon-client.js +1 -1
- package/dist/src/browser/daemon-lifecycle.js +7 -7
- package/dist/src/browser/dom-helpers.js +35 -35
- package/dist/src/browser/dom-snapshot.js +19 -19
- package/dist/src/browser/errors.js +3 -3
- package/dist/src/browser/extract.js +5 -5
- package/dist/src/browser/find.js +13 -13
- package/dist/src/browser/fingerprint.js +2 -2
- package/dist/src/browser/html-tree.js +6 -6
- package/dist/src/browser/managed-chrome.js +1 -1
- package/dist/src/browser/network-cache.js +1 -1
- package/dist/src/browser/network-key.js +1 -1
- package/dist/src/browser/page.js +7 -7
- package/dist/src/browser/profile.js +2 -2
- package/dist/src/browser/proxy-test.js +8 -8
- package/dist/src/browser/shape-filter.js +1 -1
- package/dist/src/browser/shape.js +1 -1
- package/dist/src/browser/stealth.js +3 -3
- package/dist/src/browser/tabs.js +2 -2
- package/dist/src/browser/target-errors.js +1 -1
- package/dist/src/browser/target-resolver.js +23 -23
- package/dist/src/browser/trace.js +2 -2
- package/dist/src/browser/utils.js +1 -1
- package/dist/src/browser/verify-fixture.js +2 -2
- package/dist/src/browser-session-lock.js +1 -1
- package/dist/src/build-manifest.js +11 -11
- package/dist/src/capabilityRouting.js +1 -1
- package/dist/src/cli-argv-preprocess.js +1 -1
- package/dist/src/cli.js +32 -32
- package/dist/src/commanderAdapter.js +3 -3
- package/dist/src/commands/auth.js +3 -3
- package/dist/src/commands/daemon.js +1 -1
- package/dist/src/completion-fast.js +1 -1
- package/dist/src/completion.js +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/convention-audit.js +2 -2
- package/dist/src/daemon-utils.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/discovery.js +2 -2
- package/dist/src/doctor.js +9 -9
- package/dist/src/download/article-download.js +15 -15
- package/dist/src/download/index.js +4 -4
- package/dist/src/download/media-download.js +1 -1
- package/dist/src/download/progress.js +3 -3
- package/dist/src/electron-apps.js +1 -1
- package/dist/src/errors.js +2 -2
- package/dist/src/execution.js +2 -2
- package/dist/src/external.js +1 -1
- package/dist/src/help.js +8 -8
- package/dist/src/hooks.js +1 -1
- package/dist/src/interceptor.js +21 -21
- package/dist/src/launcher.js +7 -7
- package/dist/src/logger.js +8 -8
- package/dist/src/main.js +7 -7
- package/dist/src/observation/artifact.js +5 -5
- package/dist/src/observation/retention.js +1 -1
- package/dist/src/output.js +2 -2
- package/dist/src/package-paths.js +1 -1
- package/dist/src/pipeline/executor.js +1 -1
- package/dist/src/pipeline/registry.js +1 -1
- package/dist/src/pipeline/steps/browser.js +1 -1
- package/dist/src/pipeline/steps/download.js +1 -1
- package/dist/src/pipeline/steps/fetch.js +6 -6
- package/dist/src/pipeline/steps/intercept.js +1 -1
- package/dist/src/pipeline/steps/tap.js +17 -17
- package/dist/src/pipeline/steps/transform.js +1 -1
- package/dist/src/pipeline/template.js +1 -1
- package/dist/src/plugin-manifest.js +1 -1
- package/dist/src/plugin-scaffold.js +19 -19
- package/dist/src/plugin.js +12 -12
- package/dist/src/rate-limit.js +1 -1
- package/dist/src/registry.js +1 -1
- package/dist/src/runtime-detect.js +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/scripts/framework.js +1 -1
- package/dist/src/scripts/interact.js +1 -1
- package/dist/src/scripts/store.js +1 -1
- package/dist/src/serialization.js +2 -2
- package/dist/src/session-lease.js +1 -1
- package/dist/src/snapshotFormatter.js +2 -2
- package/dist/src/tui.js +12 -12
- package/dist/src/user-runtime.js +1 -1
- package/dist/src/utils.d.ts +12 -0
- package/dist/src/utils.js +4 -4
- package/dist/src/validate.js +2 -2
- package/dist/src/verify.js +2 -2
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{generateSnapshotJs as
|
|
1
|
+
import{generateSnapshotJs as x,getFormStateJs as I}from"./dom-snapshot.js";import{buildAxSnapshotFromTrees as M,findAxRefReplacement as E}from"./ax-snapshot.js";import{pressKeyJs as C,waitForTextJs as A,waitForCaptureJs as T,waitForSelectorJs as R,scrollJs as S,autoScrollJs as N,networkRequestsJs as O,waitForDomStableJs as D}from"./dom-helpers.js";import{resolveTargetJs as F,boundingRectResolvedJs as w,clickResolvedJs as J,typeResolvedJs as m,prepareNativeTypeResolvedJs as y,verifyFilledResolvedJs as v,scrollResolvedJs as U}from"./target-resolver.js";import{TargetError as h}from"./target-errors.js";import{CliError as f}from"../errors.js";import{formatSnapshot as q}from"../snapshotFormatter.js";import{installVisualRefOverlayJs as P,removeVisualRefOverlayJs as B}from"./visual-refs.js";async function d(e,t,a={}){const r=await e.evaluate(F(t,a));if(!r.ok)throw new h({code:r.code,message:r.message,hint:r.hint,candidates:r.candidates,matches_n:r.matches_n});return{matches_n:r.matches_n,match_level:r.match_level}}function g(e){const t=(e??"").replace(/\s+/g," ").trim().slice(0,300);return t?`Response preview: ${t}`:void 0}function L(e){const t=e.split("+").map((n)=>n.trim()).filter(Boolean);if(t.length<=1)return{key:e,modifiers:[]};const a=[];for(const n of t.slice(0,-1)){const i=n.toLowerCase();if(i==="ctrl"||i==="control")a.push("Ctrl");else if(i==="cmd"||i==="command"||i==="meta")a.push("Meta");else if(i==="option"||i==="alt")a.push("Alt");else if(i==="shift")a.push("Shift");else return{key:e,modifiers:[]}}const r=t.at(-1);return r?{key:r,modifiers:a}:{key:e,modifiers:[]}}export class BasePage{_lastUrl=null;_prevSnapshotHashes=null;_cdpTargetMarkerSeq=0;_axRefs=new Map;async evaluateWithArgs(e,t){const a=Object.entries(t).map(([r,n])=>{if(!/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(r))throw Error(`evaluateWithArgs: invalid key "${r}"`);return`const ${r} = ${JSON.stringify(n)};`}).join(`
|
|
2
2
|
`);return this.evaluate(`{
|
|
3
|
-
${
|
|
4
|
-
${
|
|
5
|
-
}`)}async fetchJson(
|
|
3
|
+
${a}
|
|
4
|
+
${e}
|
|
5
|
+
}`)}async fetchJson(e,t={}){const a={url:e,method:t.method??"GET",headers:t.headers??{},body:t.body,hasBody:t.body!==void 0,timeoutMs:t.timeoutMs??15000},r=await this.evaluateWithArgs(`
|
|
6
6
|
(async () => {
|
|
7
7
|
const ctrl = new AbortController();
|
|
8
8
|
const timer = setTimeout(() => ctrl.abort(), request.timeoutMs);
|
|
@@ -44,12 +44,12 @@ ${G}
|
|
|
44
44
|
clearTimeout(timer);
|
|
45
45
|
}
|
|
46
46
|
})()
|
|
47
|
-
`,{request:
|
|
47
|
+
`,{request:a}),n=r.url||e;if(r.error)throw new f("FETCH_ERROR",`Browser fetch failed for ${n}: ${r.error}`,"Check that the page is reachable and the current browser profile has access.");if(!r.ok)throw new f("FETCH_ERROR",`HTTP ${r.status??0}${r.statusText?` ${r.statusText}`:""} from ${n}`,g(r.text));const i=r.text??"";if(!i.trim())return null;try{return JSON.parse(i)}catch{const s=r.contentType?` (${r.contentType})`:"";throw new f("FETCH_ERROR",`Expected JSON from ${n}${s}`,g(i))}}async annotatedScreenshot(e={}){await this.snapshot({source:"dom",viewportExpand:0});try{await this.evaluate(P());return await this.screenshot({...e,annotate:!1})}finally{await this.evaluate(B()).catch(()=>{})}}async click(e,t={}){const a=await this.tryClickAxRef(e);if(a)return a;const r=await d(this,e,t),n=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded"),i=await this.evaluate(w({skipScroll:n,forClick:!0})),s={hit:i?.hit,retargeted:i?.retargeted};if(i?.visible===!0&&(i.hit==="target"||i.hit==="ancestor")){if(await this.tryNativeClick(i.x,i.y))return{...r,click_method:"cdp",...s}}const l=await this.evaluate(J({skipScroll:n}));if(typeof l==="string"||l==null)return{...r,click_method:"js",...s};if(l.status==="clicked")return{...r,click_method:"js",...s};if(l.x!=null&&l.y!=null){if(await this.tryNativeClick(l.x,l.y))return{...r,click_method:"cdp",...s}}throw Error(`Click failed: ${l.error??"JS click and CDP fallback both failed"}`)}async tryNativeClick(e,t){const a=this.nativeClick;if(typeof a!=="function")return!1;try{await a.call(this,e,t);return!0}catch{return!1}}async tryNativeMouseMove(e,t){const a=this.cdp;if(typeof a!=="function")return!1;try{await a.call(this,"Input.dispatchMouseEvent",{type:"mouseMoved",x:e,y:t});return!0}catch{return!1}}async tryNativeDoubleClick(e,t){const a=this.cdp;if(typeof a!=="function")return!1;try{await a.call(this,"Input.dispatchMouseEvent",{type:"mouseMoved",x:e,y:t});await a.call(this,"Input.dispatchMouseEvent",{type:"mousePressed",x:e,y:t,button:"left",clickCount:1});await a.call(this,"Input.dispatchMouseEvent",{type:"mouseReleased",x:e,y:t,button:"left",clickCount:1});await a.call(this,"Input.dispatchMouseEvent",{type:"mousePressed",x:e,y:t,button:"left",clickCount:2});await a.call(this,"Input.dispatchMouseEvent",{type:"mouseReleased",x:e,y:t,button:"left",clickCount:2});return!0}catch{return!1}}async tryNativeDrag(e,t){const a=this.cdp;if(typeof a!=="function")return!1;const r=Math.round((e.x+t.x)/2),n=Math.round((e.y+t.y)/2);try{await a.call(this,"Input.dispatchMouseEvent",{type:"mouseMoved",x:e.x,y:e.y});await a.call(this,"Input.dispatchMouseEvent",{type:"mousePressed",x:e.x,y:e.y,button:"left",clickCount:1});await a.call(this,"Input.dispatchMouseEvent",{type:"mouseMoved",x:r,y:n,button:"left",buttons:1});await a.call(this,"Input.dispatchMouseEvent",{type:"mouseMoved",x:t.x,y:t.y,button:"left",buttons:1});await a.call(this,"Input.dispatchMouseEvent",{type:"mouseReleased",x:t.x,y:t.y,button:"left",clickCount:1});return!0}catch{return!1}}async tryClickAxRef(e){if(!/^\d+$/.test(e))return null;const t=this._axRefs.get(e);if(!t)return null;const a=this.nativeClick;if(typeof a!=="function")return null;const r=await this.resolveAxRefPoint(t);if(!r)return null;try{await a.call(this,r.x,r.y);return{matches_n:1,match_level:r.matchLevel,click_method:"ax"}}catch{return null}}async resolveAxRefPoint(e){const t=this.cdp;if(typeof t!=="function")return null;if(e.backendNodeId!=null){const i=await this.axBoxCenter(e.backendNodeId,e.frame).catch(()=>null);if(i)return{...i,matchLevel:"exact"}}await t.call(this,"Accessibility.enable",k(e.frame));const a=await t.call(this,"Accessibility.getFullAXTree",b(e.frame)).catch(()=>null),r=E(a,e);if(!r?.backendNodeId)return null;this._axRefs.set(e.ref,r);const n=await this.axBoxCenter(r.backendNodeId,r.frame).catch(()=>null);return n?{...n,matchLevel:"reidentified"}:null}async axBoxCenter(e,t){const a=this.cdp;if(typeof a!=="function")return null;const r=await a.call(this,"DOM.getBoxModel",{backendNodeId:e,...t?.sessionId?{frameId:t.frameId,sessionId:t.sessionId,...t.targetUrl?{targetUrl:t.targetUrl}:{}}:{}}),n=Array.isArray(r?.model?.content)&&r.model.content.length>=8?r.model.content:Array.isArray(r?.model?.border)&&r.model.border.length>=8?r.model.border:null;if(!n)return null;const i=n.slice(0,8).map((s)=>typeof s==="number"?s:Number(s));if(i.some((s)=>!Number.isFinite(s)))return null;return{x:Math.round((i[0]+i[2]+i[4]+i[6])/4),y:Math.round((i[1]+i[3]+i[5]+i[7])/4)}}async tryNativeType(e){const t=this.nativeType;if(typeof t==="function")try{await t.call(this,e);return!0}catch{}const a=this.insertText;if(typeof a!=="function")return!1;try{await a.call(this,e);return!0}catch{return!1}}async tryNativeKeyPress(e,t){const a=this.nativeKeyPress;if(typeof a!=="function")return!1;try{await a.call(this,e,t);return!0}catch{return!1}}async isResolvedFocused(){try{return await this.evaluate(`
|
|
48
48
|
(() => {
|
|
49
49
|
const el = window.__resolved;
|
|
50
50
|
return !!el && (document.activeElement === el || (typeof el.matches === 'function' && el.matches(':focus')));
|
|
51
51
|
})()
|
|
52
|
-
`)}catch{return!1}}async tryCdpOnResolvedElement(
|
|
52
|
+
`)}catch{return!1}}async tryCdpOnResolvedElement(e){const t=this.cdp;if(typeof t!=="function")return!1;const a="data-opencli-cdp-target",r=`${Date.now().toString(36)}-${++this._cdpTargetMarkerSeq}`,n=`[${a}="${r}"]`;let i=!1;try{i=(await this.evaluateWithArgs(`
|
|
53
53
|
(() => {
|
|
54
54
|
const el = window.__resolved;
|
|
55
55
|
if (!el || el.nodeType !== 1 || typeof el.setAttribute !== 'function') {
|
|
@@ -58,17 +58,17 @@ ${G}
|
|
|
58
58
|
el.setAttribute(markerAttr, markerValue);
|
|
59
59
|
return { ok: true };
|
|
60
60
|
})()
|
|
61
|
-
`,{markerAttr:
|
|
61
|
+
`,{markerAttr:a,markerValue:r}))?.ok===!0;if(!i)return!1;await t.call(this,"DOM.enable",{}).catch(()=>{return});const o=(await t.call(this,"DOM.getDocument",{}))?.root?.nodeId;if(typeof o!=="number")return!1;const c=(await t.call(this,"DOM.querySelector",{nodeId:o,selector:n}))?.nodeId;if(typeof c!=="number"||c<=0)return!1;await t.call(this,e,{nodeId:c});return!0}catch{return!1}finally{if(i)await this.evaluateWithArgs(`
|
|
62
62
|
(() => {
|
|
63
63
|
for (const el of document.querySelectorAll(selector)) {
|
|
64
64
|
el.removeAttribute(markerAttr);
|
|
65
65
|
}
|
|
66
66
|
})()
|
|
67
|
-
`,{selector:
|
|
67
|
+
`,{selector:n,markerAttr:a}).catch(()=>{return})}}async typeText(e,t,a={}){const r=await d(this,e,a);let n=!1,i=!1,s=!1;if(typeof this.nativeType==="function"||typeof this.insertText==="function")try{i=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded");s=await this.tryCdpOnResolvedElement("DOM.focus");n=(await this.evaluate(y({skipScroll:i,skipFocus:s})))?.ok===!0&&await this.tryNativeType(t)}catch{}if(!n)await this.evaluate(m(t));return r}async hover(e,t={}){const a=await d(this,e,t),r=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded"),n=await this.evaluate(w({skipScroll:r}));if(n?.visible===!0&&await this.tryNativeMouseMove(n.x,n.y))return a;await this.evaluate(`
|
|
68
68
|
(() => {
|
|
69
69
|
const el = window.__resolved;
|
|
70
70
|
if (!el) throw new Error('No resolved element');
|
|
71
|
-
if (${
|
|
71
|
+
if (${r?"false":"true"}) el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
72
72
|
const rect = el.getBoundingClientRect();
|
|
73
73
|
const init = {
|
|
74
74
|
bubbles: true,
|
|
@@ -82,18 +82,18 @@ ${G}
|
|
|
82
82
|
el.dispatchEvent(new MouseEvent('mouseover', init));
|
|
83
83
|
el.dispatchEvent(new MouseEvent('mousemove', init));
|
|
84
84
|
})()
|
|
85
|
-
`);return
|
|
85
|
+
`);return a}async focus(e,t={}){const a=await d(this,e,t);let r=await this.tryCdpOnResolvedElement("DOM.focus")&&await this.isResolvedFocused();if(!r)r=await this.evaluate(`
|
|
86
86
|
(() => {
|
|
87
87
|
const el = window.__resolved;
|
|
88
88
|
if (!el || typeof el.focus !== 'function') return false;
|
|
89
89
|
try { el.focus({ preventScroll: true }); } catch (_) { try { el.focus(); } catch (_) {} }
|
|
90
90
|
return document.activeElement === el || (typeof el.matches === 'function' && el.matches(':focus'));
|
|
91
91
|
})()
|
|
92
|
-
`);return{...
|
|
92
|
+
`);return{...a,focused:!!r}}async dblClick(e,t={}){const a=await d(this,e,t),r=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded"),n=await this.evaluate(w({skipScroll:r}));if(n?.visible===!0&&await this.tryNativeDoubleClick(n.x,n.y))return a;await this.evaluate(`
|
|
93
93
|
(() => {
|
|
94
94
|
const el = window.__resolved;
|
|
95
95
|
if (!el) throw new Error('No resolved element');
|
|
96
|
-
if (${
|
|
96
|
+
if (${r?"false":"true"}) el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
97
97
|
const rect = el.getBoundingClientRect();
|
|
98
98
|
const init = {
|
|
99
99
|
bubbles: true,
|
|
@@ -106,7 +106,7 @@ ${G}
|
|
|
106
106
|
};
|
|
107
107
|
el.dispatchEvent(new MouseEvent('dblclick', init));
|
|
108
108
|
})()
|
|
109
|
-
`);return
|
|
109
|
+
`);return a}async readCheckableState(){return await this.evaluate(`
|
|
110
110
|
(() => {
|
|
111
111
|
const el = window.__resolved;
|
|
112
112
|
if (!el || el.nodeType !== 1) return { ok: false, reason: 'not_checkable' };
|
|
@@ -132,7 +132,7 @@ ${G}
|
|
|
132
132
|
}
|
|
133
133
|
return { ok: false, reason: 'not_checkable', tag, role };
|
|
134
134
|
})()
|
|
135
|
-
`)}async setChecked(
|
|
135
|
+
`)}async setChecked(e,t,a={}){const r=await d(this,e,a),n=await this.readCheckableState();if(n?.ok!==!0)throw new h({code:"not_checkable",message:`Target "${e}" is not a checkbox, radio, switch, or aria-checked control.`,hint:"Use `ppcli browser state` or `browser find` to pick an input[type=checkbox], input[type=radio], or role=checkbox/switch target."});if(n.disabled)throw new h({code:"not_checkable",message:`Target "${e}" is disabled and cannot be ${t?"checked":"unchecked"}.`,hint:"Pick an enabled control, or inspect the form state before retrying."});if((n.kind==="radio"||n.kind==="menuitemradio")&&!t)throw new h({code:"not_checkable",message:`Target "${e}" is a radio button and cannot be unchecked directly.`,hint:"Select another radio option in the same group instead."});if(n.checked===t)return{...r,checked:t,changed:!1,...n.kind?{kind:n.kind}:{}};const i=await this.click(e,a),s=await this.readCheckableState();if(s?.ok!==!0||s.checked!==t)throw new h({code:"not_checkable",message:`Target "${e}" did not become ${t?"checked":"unchecked"} after click.`,hint:"The control may be custom, disabled by app logic, or require a different target such as its visible label."});return{matches_n:i.matches_n,match_level:i.match_level,checked:t,changed:!0,...s.kind?{kind:s.kind}:{}}}async setFileInputBySelector(e,t){const a=this.setFileInput;if(typeof a==="function"){await a.call(this,e,t);return}const r=this.cdp;if(typeof r!=="function")throw Error("File upload requires setFileInput or CDP support from the active browser backend.");await r.call(this,"DOM.enable",{}).catch(()=>{return});const i=(await r.call(this,"DOM.getDocument",{}))?.root?.nodeId;if(typeof i!=="number")throw Error("DOM.getDocument returned no root node.");const l=(await r.call(this,"DOM.querySelector",{nodeId:i,selector:t}))?.nodeId;if(typeof l!=="number"||l<=0)throw Error(`No element found matching selector: ${t}`);await r.call(this,"DOM.setFileInputFiles",{files:e,nodeId:l})}async uploadFiles(e,t,a={}){if(!Array.isArray(t)||t.length===0)throw new h({code:"not_file_input",message:"No files were provided for upload.",hint:"Pass one or more local file paths after the target."});const r=await d(this,e,a),n="data-opencli-upload-target",i=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,s=`[${n}="${i}"]`;let l=!1,o=null;try{o=await this.evaluateWithArgs(`
|
|
136
136
|
(() => {
|
|
137
137
|
const el = window.__resolved;
|
|
138
138
|
if (!el || el.nodeType !== 1) return { ok: false, reason: 'not_file_input' };
|
|
@@ -146,7 +146,7 @@ ${G}
|
|
|
146
146
|
accept: el.getAttribute('accept') || '',
|
|
147
147
|
};
|
|
148
148
|
})()
|
|
149
|
-
`,{markerAttr:
|
|
149
|
+
`,{markerAttr:n,markerValue:i});l=o?.ok===!0;if(!l)throw new h({code:"not_file_input",message:`Target "${e}" is not an input[type=file].`,hint:'Use `ppcli browser find --css "input[type=file]"` or inspect `compound` output from browser state/find.'});if(t.length>1&&!o?.multiple)throw new h({code:"not_file_input",message:`Target "${e}" does not allow multiple files, but ${t.length} files were provided.`,hint:"Pass one file, or choose a file input with the multiple attribute."});await this.setFileInputBySelector(t,s);const u=await this.evaluate(`
|
|
150
150
|
(() => {
|
|
151
151
|
const el = window.__resolved;
|
|
152
152
|
const names = [];
|
|
@@ -157,18 +157,18 @@ ${G}
|
|
|
157
157
|
} catch (_) {}
|
|
158
158
|
return names;
|
|
159
159
|
})()
|
|
160
|
-
`),
|
|
160
|
+
`),c=Array.isArray(u)?u.map((p)=>String(p)):[];return{...r,uploaded:!0,files:c.length||t.length,file_names:c,target:e,multiple:!!o?.multiple,...o?.accept?{accept:o.accept}:{}}}finally{if(l)await this.evaluateWithArgs(`
|
|
161
161
|
(() => {
|
|
162
162
|
for (const el of document.querySelectorAll(selector)) {
|
|
163
163
|
el.removeAttribute(markerAttr);
|
|
164
164
|
}
|
|
165
165
|
})()
|
|
166
|
-
`,{selector
|
|
166
|
+
`,{selector:s,markerAttr:n}).catch(()=>{return})}}async drag(e,t,a={}){const r=await d(this,e,a.from??{}),n=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded");if((await this.evaluate(`
|
|
167
167
|
(() => {
|
|
168
168
|
const el = window.__resolved;
|
|
169
169
|
if (!el) throw new Error('No resolved drag source');
|
|
170
170
|
window.__opencli_drag_source = el;
|
|
171
|
-
if (${
|
|
171
|
+
if (${n?"false":"true"}) el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
172
172
|
const rect = el.getBoundingClientRect();
|
|
173
173
|
const w = Math.round(rect.width);
|
|
174
174
|
const h = Math.round(rect.height);
|
|
@@ -177,13 +177,13 @@ ${G}
|
|
|
177
177
|
const visible = w > 0 && h > 0 && x >= 0 && y >= 0 && x <= window.innerWidth && y <= window.innerHeight;
|
|
178
178
|
return { x, y, w, h, visible };
|
|
179
179
|
})()
|
|
180
|
-
`))?.visible!==!0)throw Error(`Drag source "${
|
|
180
|
+
`))?.visible!==!0)throw Error(`Drag source "${e}" has no visible bounding box.`);try{const s=await d(this,t,a.to??{}),l=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded"),o=await this.evaluate(`
|
|
181
181
|
(() => {
|
|
182
182
|
const sourceEl = window.__opencli_drag_source;
|
|
183
183
|
const targetEl = window.__resolved;
|
|
184
184
|
if (!sourceEl) throw new Error('No resolved drag source');
|
|
185
185
|
if (!targetEl) throw new Error('No resolved drag target');
|
|
186
|
-
if (${
|
|
186
|
+
if (${l?"false":"true"}) targetEl.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
187
187
|
const measure = (el) => {
|
|
188
188
|
const rect = el.getBoundingClientRect();
|
|
189
189
|
const w = Math.round(rect.width);
|
|
@@ -195,16 +195,16 @@ ${G}
|
|
|
195
195
|
};
|
|
196
196
|
return { source: measure(sourceEl), target: measure(targetEl) };
|
|
197
197
|
})()
|
|
198
|
-
`);if(
|
|
199
|
-
`);return this._basicSnapshot(
|
|
198
|
+
`);if(o?.source?.visible!==!0)throw Error(`Drag source "${e}" is not visible at drag time.`);if(o?.target?.visible!==!0)throw Error(`Drag target "${t}" has no visible bounding box.`);if(!await this.tryNativeDrag({x:o.source.x,y:o.source.y},{x:o.target.x,y:o.target.y}))throw Error("Native drag requires CDP Input.dispatchMouseEvent support.");return{dragged:!0,source:e,target:t,source_matches_n:r.matches_n,target_matches_n:s.matches_n,source_match_level:r.match_level,target_match_level:s.match_level}}finally{await this.evaluate("delete window.__opencli_drag_source").catch(()=>{})}}async fillText(e,t,a={}){const r=await d(this,e,a);let n=!1,i=!1;try{n=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded");i=await this.tryCdpOnResolvedElement("DOM.focus")}catch{}if((await this.evaluate(y({skipScroll:n,skipFocus:i})))?.ok!==!0)throw new h({code:"not_editable",message:`Target "${e}" is not a fillable input, textarea, or contenteditable element.`,hint:"Use `ppcli browser state` to pick an editable target, or use `browser type` for keyboard-like interactions."});const l=await this.tryNativeType(t);if(!l)await this.evaluate(m(t));let o=await this.evaluate(v(t));if(l&&o?.ok!==!0){await this.evaluate(m(t));o=await this.evaluate(v(t))}const u=o&&"actual"in o?o.actual:"",c=o&&"mode"in o?o.mode:void 0;return{...r,filled:!0,verified:o?.ok===!0,expected:t,actual:u,length:u.length,...c?{mode:c}:{}}}async pressKey(e){const t=L(e);if(!await this.tryNativeKeyPress(t.key,t.modifiers))await this.evaluate(C(t.key,t.modifiers))}async scrollTo(e,t={}){const a=await d(this,e,t),r=await this.tryCdpOnResolvedElement("DOM.scrollIntoViewIfNeeded"),n=await this.evaluate(U({skipScroll:r}));if(n&&typeof n==="object")return{...n,matches_n:a.matches_n,match_level:a.match_level};return{matches_n:a.matches_n,match_level:a.match_level}}async getFormState(){return await this.evaluate(I())}async scroll(e="down",t=500){await this.evaluate(S(e,t))}async autoScroll(e){const t=e?.times??3,a=e?.delayMs??2000;await this.evaluate(N(t,a))}async networkRequests(e=!1){const t=await this.evaluate(O(e));return Array.isArray(t)?t:[]}async consoleMessages(e="info"){return[]}async wait(e){if(typeof e==="number"){if(e>=1)try{const t=e*1000;await this.evaluate(D(t,Math.min(500,t)));return}catch{}await new Promise((t)=>setTimeout(t,e*1000));return}if(typeof e.time==="number"){await new Promise((t)=>setTimeout(t,e.time*1000));return}if(e.selector){const t=(e.timeout??10)*1000;await this.evaluate(R(e.selector,t));return}if(e.text){const t=(e.timeout??30)*1000;await this.evaluate(A(e.text,t))}}async snapshot(e={}){if(e.source==="ax"){const a=this.cdp;if(typeof a!=="function")throw new f("BROWSER_AX_UNAVAILABLE","AX snapshot requires CDP support from the active browser backend.","Use the default DOM state, or update/reload the Browser Bridge extension.");const r=await this.collectAxSnapshotTrees(a),n=M(r,{maxDepth:e.maxDepth,interactiveOnly:e.interactive});this._axRefs=n.refs;return n.text}this._axRefs.clear();const t=x({viewportExpand:e.viewportExpand??2000,maxDepth:Math.max(1,Math.min(Number(e.maxDepth)||50,200)),interactiveOnly:e.interactive??!1,maxTextLength:e.maxTextLength??120,includeScrollInfo:!0,bboxDedup:!0,previousHashes:this._prevSnapshotHashes});try{const a=await this.evaluate(t);try{const r=await this.evaluate("window.__opencli_prev_hashes");this._prevSnapshotHashes=typeof r==="string"?r:null}catch{}return a}catch(a){if(process.env.DEBUG_SNAPSHOT)process.stderr.write(`[snapshot] DOM snapshot failed, falling back to accessibility tree: ${a?.message?.slice(0,200)}
|
|
199
|
+
`);return this._basicSnapshot(e)}}async collectAxSnapshotTrees(e){await e.call(this,"Accessibility.enable",{});const a=[{tree:await e.call(this,"Accessibility.getFullAXTree",{})}],r=await e.call(this,"Page.getFrameTree",{}).catch(()=>null),n=V(r);for(const i of n){if(i.sessionId)await e.call(this,"Accessibility.enable",k(i)).catch(()=>null);const s=await e.call(this,"Accessibility.getFullAXTree",b(i)).catch(()=>null);if(s)a.push({tree:s,frame:i})}return a}async getCurrentUrl(){if(this._lastUrl)return this._lastUrl;try{const e=await this.evaluate("window.location.href");if(typeof e==="string"&&e){this._lastUrl=e;return e}}catch{}return null}async installInterceptor(e){const{generateInterceptorJs:t}=await import("../interceptor.js");await this.evaluate(t(JSON.stringify(e),{arrayName:"__opencli_xhr",patchGuard:"__opencli_interceptor_patched"}))}async getInterceptedRequests(){const{generateReadInterceptedJs:e}=await import("../interceptor.js"),t=await this.evaluate(e("__opencli_xhr"));return Array.isArray(t)?t:[]}async waitForCapture(e=10){const t=e*1000;await this.evaluate(T(t))}async _basicSnapshot(e={}){const a=`
|
|
200
200
|
(async () => {
|
|
201
201
|
function buildTree(node, depth) {
|
|
202
|
-
if (depth > ${Math.max(1,Math.min(Number(
|
|
202
|
+
if (depth > ${Math.max(1,Math.min(Number(e.maxDepth)||50,200))}) return '';
|
|
203
203
|
const role = node.getAttribute?.('role') || node.tagName?.toLowerCase() || 'generic';
|
|
204
204
|
const name = node.getAttribute?.('aria-label') || node.getAttribute?.('alt') || node.textContent?.trim().slice(0, 80) || '';
|
|
205
205
|
const isInteractive = ['a', 'button', 'input', 'select', 'textarea'].includes(node.tagName?.toLowerCase()) || node.getAttribute?.('tabindex') != null;
|
|
206
206
|
|
|
207
|
-
${
|
|
207
|
+
${e.interactive?'if (!isInteractive && !node.children?.length) return "";':""}
|
|
208
208
|
|
|
209
209
|
let indent = ' '.repeat(depth);
|
|
210
210
|
let line = indent + role;
|
|
@@ -222,4 +222,4 @@ ${G}
|
|
|
222
222
|
}
|
|
223
223
|
return buildTree(document.body, 0);
|
|
224
224
|
})()
|
|
225
|
-
`,
|
|
225
|
+
`,r=await this.evaluate(a);if(e.raw)return r;if(typeof r==="string")return q(r,e);return r}}function b(e){return e?.frameId?{frameId:e.frameId,...e.sessionId?{sessionId:e.sessionId}:{},...e.targetUrl?{targetUrl:e.targetUrl}:{}}:{}}function k(e){return e?.frameId&&e.sessionId?{frameId:e.frameId,sessionId:e.sessionId,...e.targetUrl?{targetUrl:e.targetUrl}:{}}:{}}function V(e){const t=e?.frameTree,a=t?.frame?.url||t?.frame?.unreachableUrl||"",r=_(a);if(!t||!r)return[];const n=[];function i(s){for(const l of s?.childFrames??[]){const o=l.frame,u=o?.id,c=o?.url||o?.unreachableUrl||"",p=_(c);if(!u)continue;if(p===r){n.push({frameId:u,url:c});i(l)}else n.push({frameId:u,url:c,targetUrl:c,sessionId:"target"})}}i(t);return n}function _(e){try{return new URL(e).origin}catch{return null}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Page as
|
|
1
|
+
import{Page as i}from"./page.js";import{resolveProfileContextId as r}from"./profile.js";import{ensureBrowserBridgeReady as n}from"./daemon-lifecycle.js";const o=1e4;export class BrowserBridge{_state="idle";_page=null;_daemonProc=null;get state(){return this._state}async connect(e={}){if(this._state==="connected"&&this._page)return this._page;if(this._state==="connecting")throw Error("Already connecting");if(this._state==="closing")throw Error("Session is closing");if(this._state==="closed")throw Error("Session is closed");this._state="connecting";try{const t=e.contextId??r();await this._ensureDaemon(e.timeout,t);if(!e.session?.trim())throw Error("Browser session is required");this._page=new i(e.session.trim(),e.idleTimeout,t,e.windowMode,e.surface,e.siteSession);this._state="connected";return this._page}catch(t){this._state="idle";throw t}}async close(){if(this._state==="closed")return;this._state="closing";this._page=null;this._state="closed"}async _ensureDaemon(e,t){const s=await n({timeoutSeconds:e??Math.ceil(o/1000),contextId:t});this._daemonProc=s.spawnedProcess}}
|
package/dist/src/browser/cdp.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WebSocket as I}from"ws";import{request as W}from"node:http";import{request as F}from"node:https";import{buildEvaluateExpression as _}from"./utils.js";import{generateStealthJs as z}from"./stealth.js";import{waitForDomStableJs as S}from"./dom-helpers.js";import{isRecord as H,saveBase64ToFile as M}from"../utils.js";import{getAllElectronApps as w}from"../electron-apps.js";import{BasePage as E}from"./base-page.js";const R=30000;export const CDP_RESPONSE_BODY_CAPTURE_LIMIT=8388608;export class CDPBridge{_ws=null;_idCounter=0;_pending=new Map;_eventListeners=new Map;async connect(G){if(this._ws)throw Error("CDPBridge is already connected. Call close() before reconnecting.");const V=G?.cdpEndpoint??process.env.OPENCLI_CDP_ENDPOINT;if(!V)throw Error("CDP endpoint not provided (pass cdpEndpoint or set OPENCLI_CDP_ENDPOINT)");let Q=V;if(V.startsWith("http")){const K=await j(`${V.replace(/\/$/,"")}/json`),X=U(K);if(!X||!X.webSocketDebuggerUrl)throw Error("No inspectable targets found at CDP endpoint");Q=X.webSocketDebuggerUrl}return new Promise((K,X)=>{const Z=new I(Q),$=(G?.timeout??10)*1000,J=setTimeout(()=>{this._ws=null;Z.close();X(Error("CDP connect timeout"))},$);Z.on("open",async()=>{clearTimeout(J);this._ws=Z;try{await this.send("Page.enable");this.on("Page.javascriptDialogOpening",(Y)=>{if(Y?.type==="beforeunload")this.send("Page.handleJavaScriptDialog",{accept:!0}).catch(()=>{})});await this.send("Page.addScriptToEvaluateOnNewDocument",{source:z()});if(G?.initScript)await this.send("Page.addScriptToEvaluateOnNewDocument",{source:G.initScript});if(G?.windowMode==="background")await this.send("Emulation.setFocusEmulationEnabled",{enabled:!0}).catch(()=>{});else if(G?.windowMode==="foreground")await this.send("Page.bringToFront").catch(()=>{});if(G?.proxyAuth){this.on("Fetch.requestPaused",(Y)=>{const A=Y;if(A.requestId)this.send("Fetch.continueRequest",{requestId:A.requestId}).catch(()=>{})});this.on("Fetch.authRequired",(Y)=>{const A=Y;if(!A.requestId)return;this.send("Fetch.continueWithAuth",{requestId:A.requestId,authChallengeResponse:{response:"ProvideCredentials",username:G.proxyAuth.username,password:G.proxyAuth.password}}).catch(()=>{})});await this.send("Fetch.enable",{handleAuthRequests:!0})}}catch(Y){Z.close();X(Y instanceof Error?Y:Error(String(Y)));return}const L=new O(this);if(G?.session)L.session=G.session;if(G?.contextId)L.contextId=G.contextId;K(L)});Z.on("error",(L)=>{clearTimeout(J);X(L)});Z.on("message",(L)=>{try{const Y=JSON.parse(L.toString());if(Y.id&&this._pending.has(Y.id)){const A=this._pending.get(Y.id);clearTimeout(A.timer);this._pending.delete(Y.id);if(Y.error)A.reject(Error(Y.error.message));else A.resolve(Y.result)}if(Y.method){const A=this._eventListeners.get(Y.method);if(A)for(const B of A)B(Y.params)}}catch(Y){if(process.env.OPENCLI_VERBOSE)console.error("[cdp] Failed to parse WebSocket message:",Y instanceof Error?Y.message:Y)}})})}async close(){if(this._ws){this._ws.close();this._ws=null}for(const G of this._pending.values()){clearTimeout(G.timer);G.reject(Error("CDP connection closed"))}this._pending.clear();this._eventListeners.clear()}async send(G,V={},Q=R){if(!this._ws||this._ws.readyState!==I.OPEN)throw Error("CDP connection is not open");const K=++this._idCounter;return new Promise((X,Z)=>{const $=setTimeout(()=>{this._pending.delete(K);const J=G.startsWith("Page.")?"(页面可能被 JS 弹窗挡住:试 `ppcli browser dialog accept`;托管 profile 可 `ppcli profile stop <name>` 关闭后重跑命令自动重启会话)":"";Z(Error(`CDP command '${G}' timed out after ${Q/1000}s${J}`))},Q);this._pending.set(K,{resolve:X,reject:Z,timer:$});this._ws.send(JSON.stringify({id:K,method:G,params:V}))})}on(G,V){let Q=this._eventListeners.get(G);if(!Q){Q=new Set;this._eventListeners.set(G,Q)}Q.add(V)}off(G,V){this._eventListeners.get(G)?.delete(V)}waitForEvent(G,V=15000){return new Promise((Q,K)=>{const X=setTimeout(()=>{this.off(G,Z);K(Error(`Timed out waiting for CDP event '${G}'`))},V),Z=($)=>{clearTimeout(X);this.off(G,Z);Q($)};this.on(G,Z)})}}class O extends E{bridge;session;contextId;_pageEnabled=!1;_networkCapturing=!1;_networkCapturePattern="";_networkEntries=[];_pendingRequests=new Map;_pendingBodyFetches=new Set;_consoleMessages=[];_consoleCapturing=!1;constructor(G){super();this.bridge=G}async goto(G,V){if(!this._pageEnabled){await this.bridge.send("Page.enable");this._pageEnabled=!0}const Q=this.bridge.waitForEvent("Page.loadEventFired",30000).catch(()=>{});await this.bridge.send("Page.navigate",{url:G});await Q;this._lastUrl=G;if(V?.waitUntil!=="none"){const K=V?.settleMs??1000;await this.evaluate(S(K,Math.min(500,K)))}}async evaluate(G,...V){const Q=_(G,V),K=await this.bridge.send("Runtime.evaluate",{expression:Q,returnByValue:!0,awaitPromise:!0});if(K.exceptionDetails)throw Error("Evaluate error: "+(K.exceptionDetails.exception?.description||"Unknown exception"));return K.result?.value}async getCookies(G={}){let V;try{const K=await this.bridge.send("Storage.getCookies");V=H(K)&&Array.isArray(K.cookies)?K.cookies:[]}catch{const K=await this.bridge.send("Network.getCookies",G.url?{urls:[G.url]}:{});V=H(K)&&Array.isArray(K.cookies)?K.cookies:[]}const Q=G.domain??(G.url?T(G.url):void 0);return Q?V.filter((K)=>N(K)&&C(K.domain,Q)):V.filter(N)}async screenshot(G={}){const V=G.fullPage===!0,Q=G.width&&G.width>0?Math.ceil(G.width):void 0,K=!V&&G.height&&G.height>0?Math.ceil(G.height):void 0,X=Q!==void 0||K!==void 0;if(X){if(Q!==void 0&&V)await this.bridge.send("Emulation.setDeviceMetricsOverride",{mobile:!1,width:Q,height:0,deviceScaleFactor:1});let Z=Q??0,$=K??0;if(V){const J=await this.bridge.send("Page.getLayoutMetrics"),L=H(J)?J:{},Y=H(L.cssContentSize)?L.cssContentSize:void 0,A=H(L.contentSize)?L.contentSize:void 0,B=Y??A;if(B&&typeof B.width==="number"&&typeof B.height==="number"){if(Z===0)Z=Math.ceil(B.width);$=Math.ceil(B.height)}}await this.bridge.send("Emulation.setDeviceMetricsOverride",{mobile:!1,width:Z,height:$,deviceScaleFactor:1})}try{const Z=await this.bridge.send("Page.captureScreenshot",{format:G.format??"png",quality:G.format==="jpeg"?G.quality??80:void 0,captureBeyondViewport:!X&&V}),$=H(Z)&&typeof Z.data==="string"?Z.data:"";if(G.path)await M($,G.path);return $}finally{if(X)await this.bridge.send("Emulation.clearDeviceMetricsOverride").catch(()=>{})}}async startNetworkCapture(G=""){this._networkCapturePattern=G;if(!this._networkCapturing){this._networkEntries=[];this._pendingRequests.clear();this._pendingBodyFetches.clear();await this.bridge.send("Network.enable");this.bridge.on("Network.requestWillBeSent",(V)=>{const Q=V;if(!this._networkCapturePattern||Q.request.url.includes(this._networkCapturePattern)){const K=this._networkEntries.push({url:Q.request.url,method:Q.request.method,timestamp:Date.now()})-1;this._pendingRequests.set(Q.requestId,K)}});this.bridge.on("Network.responseReceived",(V)=>{const Q=V,K=this._pendingRequests.get(Q.requestId);if(K!==void 0){this._networkEntries[K].responseStatus=Q.response.status;this._networkEntries[K].responseContentType=Q.response.mimeType||""}});this.bridge.on("Network.loadingFinished",(V)=>{const Q=V,K=this._pendingRequests.get(Q.requestId);if(K!==void 0){const X=this.bridge.send("Network.getResponseBody",{requestId:Q.requestId}).then((Z)=>{const $=Z;if(typeof $?.body==="string"){const J=$.body.length,L=J>CDP_RESPONSE_BODY_CAPTURE_LIMIT,Y=L?$.body.slice(0,CDP_RESPONSE_BODY_CAPTURE_LIMIT):$.body;this._networkEntries[K].responsePreview=$.base64Encoded?`base64:${Y}`:Y;this._networkEntries[K].responseBodyFullSize=J;this._networkEntries[K].responseBodyTruncated=L}}).catch((Z)=>{if(process.env.OPENCLI_VERBOSE)console.error(`[cdp] getResponseBody failed for ${Q.requestId}:`,Z instanceof Error?Z.message:Z)}).finally(()=>{this._pendingBodyFetches.delete(X)});this._pendingBodyFetches.add(X);this._pendingRequests.delete(Q.requestId)}});this._networkCapturing=!0}return!0}async readNetworkCapture(){if(this._pendingBodyFetches.size>0)await Promise.all([...this._pendingBodyFetches]);const G=[...this._networkEntries];this._networkEntries=[];return G}async consoleMessages(G="all"){if(!this._consoleCapturing){await this.bridge.send("Runtime.enable");this.bridge.on("Runtime.consoleAPICalled",(V)=>{const Q=V,K=(Q.args||[]).map((X)=>X.value!==void 0?String(X.value):X.description||"").join(" ");this._consoleMessages.push({type:Q.type,text:K,timestamp:Date.now()});if(this._consoleMessages.length>500)this._consoleMessages.shift()});this.bridge.on("Runtime.exceptionThrown",(V)=>{const Q=V,K=Q.exceptionDetails?.exception?.description||Q.exceptionDetails?.text||"Unknown exception";this._consoleMessages.push({type:"error",text:K,timestamp:Date.now()});if(this._consoleMessages.length>500)this._consoleMessages.shift()});this._consoleCapturing=!0}if(G==="all")return[...this._consoleMessages];if(G==="error")return this._consoleMessages.filter((V)=>V.type==="error"||V.type==="warning");return this._consoleMessages.filter((V)=>V.type===G)}async tabs(){return[]}async selectTab(G){}async cdp(G,V={}){return this.bridge.send(G,V)}async handleJavaScriptDialog(G,V){await this.cdp("Page.handleJavaScriptDialog",{accept:G,...V!==void 0&&{promptText:V}})}async nativeClick(G,V){await this.cdp("Input.dispatchMouseEvent",{type:"mouseMoved",x:G,y:V});await this.cdp("Input.dispatchMouseEvent",{type:"mousePressed",x:G,y:V,button:"left",clickCount:1});await this.cdp("Input.dispatchMouseEvent",{type:"mouseReleased",x:G,y:V,button:"left",clickCount:1})}async nativeType(G){await this.cdp("Input.insertText",{text:G})}async insertText(G){await this.nativeType(G)}async nativeKeyPress(G,V=[]){let Q=0;for(const K of V){if(K==="Alt")Q|=1;if(K==="Ctrl"||K==="Control")Q|=2;if(K==="Meta")Q|=4;if(K==="Shift")Q|=8}await this.cdp("Input.dispatchKeyEvent",{type:"keyDown",key:G,modifiers:Q});await this.cdp("Input.dispatchKeyEvent",{type:"keyUp",key:G,modifiers:Q})}}function T(G){try{return new URL(G).hostname}catch{return}}function N(G){return H(G)&&typeof G.name==="string"&&typeof G.value==="string"&&typeof G.domain==="string"}function C(G,V){const Q=G.replace(/^\./,"").toLowerCase(),K=V.replace(/^\./,"").toLowerCase();return K===Q||K.endsWith(`.${Q}`)}function U(G){const V=b(process.env.OPENCLI_CDP_TARGET);return G.map((K,X)=>({target:K,index:X,score:q(K,V)})).filter(({score:K})=>Number.isFinite(K)).sort((K,X)=>{if(X.score!==K.score)return X.score-K.score;return K.index-X.index})[0]?.target}function q(G,V){if(!G.webSocketDebuggerUrl)return Number.NEGATIVE_INFINITY;const Q=(G.type??"").toLowerCase(),K=(G.url??"").toLowerCase(),X=(G.title??"").toLowerCase(),Z=`${X} ${K}`;if(!Z.trim()&&!Q)return Number.NEGATIVE_INFINITY;if(Z.includes("devtools"))return Number.NEGATIVE_INFINITY;if(Q==="background_page"||Q==="service_worker")return Number.NEGATIVE_INFINITY;let $=0;if(V&&V.test(Z))$+=1000;if(Q==="app")$+=120;else if(Q==="webview")$+=100;else if(Q==="page")$+=80;else if(Q==="iframe")$+=20;if(K.startsWith("http://localhost")||K.startsWith("https://localhost"))$+=90;if(K.startsWith("file://"))$+=60;if(K.startsWith("http://127.0.0.1")||K.startsWith("https://127.0.0.1"))$+=50;if(K.startsWith("about:blank"))$-=120;if(K===""||K==="about:blank")$-=40;if(X&&X!=="devtools")$+=25;const J=Object.values(w()).map((L)=>(L.displayName??L.processName).toLowerCase());for(const L of J)if(X.includes(L)){$+=120;break}for(const L of J)if(K.includes(L)){$+=100;break}return $}function b(G){const V=G?.trim();if(!V)return;return new RegExp(D(V.toLowerCase()))}function D(G){return G.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export const __test__={selectCDPTarget:U,scoreCDPTarget:q};function j(G){return new Promise((V,Q)=>{const K=new URL(G),X=(K.protocol==="https:"?F:W)(K,(Z)=>{const $=Z.statusCode??0;if($<200||$>=300){Z.resume();Q(Error(`Failed to fetch CDP targets: HTTP ${$}`));return}const J=[];Z.on("data",(L)=>J.push(Buffer.isBuffer(L)?L:Buffer.from(L)));Z.on("end",()=>{try{V(JSON.parse(Buffer.concat(J).toString("utf8")))}catch(L){Q(L instanceof Error?L:Error(String(L)))}})});X.on("error",Q);X.setTimeout(1e4,()=>X.destroy(Error("Timed out fetching CDP targets")));X.end()})}
|
|
1
|
+
import{WebSocket as p}from"ws";import{request as _}from"node:http";import{request as y}from"node:https";import{buildEvaluateExpression as E}from"./utils.js";import{generateStealthJs as b}from"./stealth.js";import{waitForDomStableJs as C}from"./dom-helpers.js";import{isRecord as l,saveBase64ToFile as P}from"../utils.js";import{getAllElectronApps as k}from"../electron-apps.js";import{BasePage as v}from"./base-page.js";const I=30000;export const CDP_RESPONSE_BODY_CAPTURE_LIMIT=8388608;export class CDPBridge{_ws=null;_idCounter=0;_pending=new Map;_eventListeners=new Map;async connect(e){if(this._ws)throw Error("CDPBridge is already connected. Call close() before reconnecting.");const n=e?.cdpEndpoint??process.env.OPENCLI_CDP_ENDPOINT;if(!n)throw Error("CDP endpoint not provided (pass cdpEndpoint or set OPENCLI_CDP_ENDPOINT)");let s=n;if(n.startsWith("http")){const t=await q(`${n.replace(/\/$/,"")}/json`),i=g(t);if(!i||!i.webSocketDebuggerUrl)throw Error("No inspectable targets found at CDP endpoint");s=i.webSocketDebuggerUrl}return new Promise((t,i)=>{const r=new p(s),o=(e?.timeout??10)*1000,d=setTimeout(()=>{this._ws=null;r.close();i(Error("CDP connect timeout"))},o);r.on("open",async()=>{clearTimeout(d);this._ws=r;try{await this.send("Page.enable");this.on("Page.javascriptDialogOpening",(c)=>{if(c?.type==="beforeunload")this.send("Page.handleJavaScriptDialog",{accept:!0}).catch(()=>{})});await this.send("Page.addScriptToEvaluateOnNewDocument",{source:b()});if(e?.initScript)await this.send("Page.addScriptToEvaluateOnNewDocument",{source:e.initScript});if(e?.windowMode==="background")await this.send("Emulation.setFocusEmulationEnabled",{enabled:!0}).catch(()=>{});else if(e?.windowMode==="foreground")await this.send("Page.bringToFront").catch(()=>{});if(e?.proxyAuth){this.on("Fetch.requestPaused",(c)=>{const u=c;if(u.requestId)this.send("Fetch.continueRequest",{requestId:u.requestId}).catch(()=>{})});this.on("Fetch.authRequired",(c)=>{const u=c;if(!u.requestId)return;this.send("Fetch.continueWithAuth",{requestId:u.requestId,authChallengeResponse:{response:"ProvideCredentials",username:e.proxyAuth.username,password:e.proxyAuth.password}}).catch(()=>{})});await this.send("Fetch.enable",{handleAuthRequests:!0})}}catch(c){r.close();i(c instanceof Error?c:Error(String(c)));return}const a=new m(this);if(e?.session)a.session=e.session;if(e?.contextId)a.contextId=e.contextId;t(a)});r.on("error",(a)=>{clearTimeout(d);i(a)});r.on("message",(a)=>{try{const c=JSON.parse(a.toString());if(c.id&&this._pending.has(c.id)){const u=this._pending.get(c.id);clearTimeout(u.timer);this._pending.delete(c.id);if(c.error)u.reject(Error(c.error.message));else u.resolve(c.result)}if(c.method){const u=this._eventListeners.get(c.method);if(u)for(const h of u)h(c.params)}}catch(c){if(process.env.OPENCLI_VERBOSE)console.error("[cdp] Failed to parse WebSocket message:",c instanceof Error?c.message:c)}})})}async close(){if(this._ws){this._ws.close();this._ws=null}for(const e of this._pending.values()){clearTimeout(e.timer);e.reject(Error("CDP connection closed"))}this._pending.clear();this._eventListeners.clear()}async send(e,n={},s=I){if(!this._ws||this._ws.readyState!==p.OPEN)throw Error("CDP connection is not open");const t=++this._idCounter;return new Promise((i,r)=>{const o=setTimeout(()=>{this._pending.delete(t);const d=e.startsWith("Page.")?"(页面可能被 JS 弹窗挡住:试 `ppcli browser dialog accept`;托管 profile 可 `ppcli profile stop <name>` 关闭后重跑命令自动重启会话)":"";r(Error(`CDP command '${e}' timed out after ${s/1000}s${d}`))},s);this._pending.set(t,{resolve:i,reject:r,timer:o});this._ws.send(JSON.stringify({id:t,method:e,params:n}))})}on(e,n){let s=this._eventListeners.get(e);if(!s){s=new Set;this._eventListeners.set(e,s)}s.add(n)}off(e,n){this._eventListeners.get(e)?.delete(n)}waitForEvent(e,n=15000){return new Promise((s,t)=>{const i=setTimeout(()=>{this.off(e,r);t(Error(`Timed out waiting for CDP event '${e}'`))},n),r=(o)=>{clearTimeout(i);this.off(e,r);s(o)};this.on(e,r)})}}class m extends v{bridge;session;contextId;_pageEnabled=!1;_networkCapturing=!1;_networkCapturePattern="";_networkEntries=[];_pendingRequests=new Map;_pendingBodyFetches=new Set;_consoleMessages=[];_consoleCapturing=!1;constructor(e){super();this.bridge=e}async goto(e,n){if(!this._pageEnabled){await this.bridge.send("Page.enable");this._pageEnabled=!0}const s=this.bridge.waitForEvent("Page.loadEventFired",30000).catch(()=>{});await this.bridge.send("Page.navigate",{url:e});await s;this._lastUrl=e;if(n?.waitUntil!=="none"){const t=n?.settleMs??1000;await this.evaluate(C(t,Math.min(500,t)))}}async evaluate(e,...n){const s=E(e,n),t=await this.bridge.send("Runtime.evaluate",{expression:s,returnByValue:!0,awaitPromise:!0});if(t.exceptionDetails)throw Error("Evaluate error: "+(t.exceptionDetails.exception?.description||"Unknown exception"));return t.result?.value}async getCookies(e={}){let n;try{const t=await this.bridge.send("Storage.getCookies");n=l(t)&&Array.isArray(t.cookies)?t.cookies:[]}catch{const t=await this.bridge.send("Network.getCookies",e.url?{urls:[e.url]}:{});n=l(t)&&Array.isArray(t.cookies)?t.cookies:[]}const s=e.domain??(e.url?D(e.url):void 0);return s?n.filter((t)=>f(t)&&N(t.domain,s)):n.filter(f)}async screenshot(e={}){const n=e.fullPage===!0,s=e.width&&e.width>0?Math.ceil(e.width):void 0,t=!n&&e.height&&e.height>0?Math.ceil(e.height):void 0,i=s!==void 0||t!==void 0;if(i){if(s!==void 0&&n)await this.bridge.send("Emulation.setDeviceMetricsOverride",{mobile:!1,width:s,height:0,deviceScaleFactor:1});let r=s??0,o=t??0;if(n){const d=await this.bridge.send("Page.getLayoutMetrics"),a=l(d)?d:{},c=l(a.cssContentSize)?a.cssContentSize:void 0,u=l(a.contentSize)?a.contentSize:void 0,h=c??u;if(h&&typeof h.width==="number"&&typeof h.height==="number"){if(r===0)r=Math.ceil(h.width);o=Math.ceil(h.height)}}await this.bridge.send("Emulation.setDeviceMetricsOverride",{mobile:!1,width:r,height:o,deviceScaleFactor:1})}try{const r=await this.bridge.send("Page.captureScreenshot",{format:e.format??"png",quality:e.format==="jpeg"?e.quality??80:void 0,captureBeyondViewport:!i&&n}),o=l(r)&&typeof r.data==="string"?r.data:"";if(e.path)await P(o,e.path);return o}finally{if(i)await this.bridge.send("Emulation.clearDeviceMetricsOverride").catch(()=>{})}}async startNetworkCapture(e=""){this._networkCapturePattern=e;if(!this._networkCapturing){this._networkEntries=[];this._pendingRequests.clear();this._pendingBodyFetches.clear();await this.bridge.send("Network.enable");this.bridge.on("Network.requestWillBeSent",(n)=>{const s=n;if(!this._networkCapturePattern||s.request.url.includes(this._networkCapturePattern)){const t=this._networkEntries.push({url:s.request.url,method:s.request.method,timestamp:Date.now()})-1;this._pendingRequests.set(s.requestId,t)}});this.bridge.on("Network.responseReceived",(n)=>{const s=n,t=this._pendingRequests.get(s.requestId);if(t!==void 0){this._networkEntries[t].responseStatus=s.response.status;this._networkEntries[t].responseContentType=s.response.mimeType||""}});this.bridge.on("Network.loadingFinished",(n)=>{const s=n,t=this._pendingRequests.get(s.requestId);if(t!==void 0){const i=this.bridge.send("Network.getResponseBody",{requestId:s.requestId}).then((r)=>{const o=r;if(typeof o?.body==="string"){const d=o.body.length,a=d>CDP_RESPONSE_BODY_CAPTURE_LIMIT,c=a?o.body.slice(0,CDP_RESPONSE_BODY_CAPTURE_LIMIT):o.body;this._networkEntries[t].responsePreview=o.base64Encoded?`base64:${c}`:c;this._networkEntries[t].responseBodyFullSize=d;this._networkEntries[t].responseBodyTruncated=a}}).catch((r)=>{if(process.env.OPENCLI_VERBOSE)console.error(`[cdp] getResponseBody failed for ${s.requestId}:`,r instanceof Error?r.message:r)}).finally(()=>{this._pendingBodyFetches.delete(i)});this._pendingBodyFetches.add(i);this._pendingRequests.delete(s.requestId)}});this._networkCapturing=!0}return!0}async readNetworkCapture(){if(this._pendingBodyFetches.size>0)await Promise.all([...this._pendingBodyFetches]);const e=[...this._networkEntries];this._networkEntries=[];return e}async consoleMessages(e="all"){if(!this._consoleCapturing){await this.bridge.send("Runtime.enable");this.bridge.on("Runtime.consoleAPICalled",(n)=>{const s=n,t=(s.args||[]).map((i)=>i.value!==void 0?String(i.value):i.description||"").join(" ");this._consoleMessages.push({type:s.type,text:t,timestamp:Date.now()});if(this._consoleMessages.length>500)this._consoleMessages.shift()});this.bridge.on("Runtime.exceptionThrown",(n)=>{const s=n,t=s.exceptionDetails?.exception?.description||s.exceptionDetails?.text||"Unknown exception";this._consoleMessages.push({type:"error",text:t,timestamp:Date.now()});if(this._consoleMessages.length>500)this._consoleMessages.shift()});this._consoleCapturing=!0}if(e==="all")return[...this._consoleMessages];if(e==="error")return this._consoleMessages.filter((n)=>n.type==="error"||n.type==="warning");return this._consoleMessages.filter((n)=>n.type===e)}async tabs(){return[]}async selectTab(e){}async cdp(e,n={}){return this.bridge.send(e,n)}async handleJavaScriptDialog(e,n){await this.cdp("Page.handleJavaScriptDialog",{accept:e,...n!==void 0&&{promptText:n}})}async nativeClick(e,n){await this.cdp("Input.dispatchMouseEvent",{type:"mouseMoved",x:e,y:n});await this.cdp("Input.dispatchMouseEvent",{type:"mousePressed",x:e,y:n,button:"left",clickCount:1});await this.cdp("Input.dispatchMouseEvent",{type:"mouseReleased",x:e,y:n,button:"left",clickCount:1})}async nativeType(e){await this.cdp("Input.insertText",{text:e})}async insertText(e){await this.nativeType(e)}async nativeKeyPress(e,n=[]){let s=0;for(const t of n){if(t==="Alt")s|=1;if(t==="Ctrl"||t==="Control")s|=2;if(t==="Meta")s|=4;if(t==="Shift")s|=8}await this.cdp("Input.dispatchKeyEvent",{type:"keyDown",key:e,modifiers:s});await this.cdp("Input.dispatchKeyEvent",{type:"keyUp",key:e,modifiers:s})}}function D(e){try{return new URL(e).hostname}catch{return}}function f(e){return l(e)&&typeof e.name==="string"&&typeof e.value==="string"&&typeof e.domain==="string"}function N(e,n){const s=e.replace(/^\./,"").toLowerCase(),t=n.replace(/^\./,"").toLowerCase();return t===s||t.endsWith(`.${s}`)}function g(e){const n=S(process.env.OPENCLI_CDP_TARGET);return e.map((t,i)=>({target:t,index:i,score:w(t,n)})).filter(({score:t})=>Number.isFinite(t)).sort((t,i)=>{if(i.score!==t.score)return i.score-t.score;return t.index-i.index})[0]?.target}function w(e,n){if(!e.webSocketDebuggerUrl)return Number.NEGATIVE_INFINITY;const s=(e.type??"").toLowerCase(),t=(e.url??"").toLowerCase(),i=(e.title??"").toLowerCase(),r=`${i} ${t}`;if(!r.trim()&&!s)return Number.NEGATIVE_INFINITY;if(r.includes("devtools"))return Number.NEGATIVE_INFINITY;if(s==="background_page"||s==="service_worker")return Number.NEGATIVE_INFINITY;let o=0;if(n&&n.test(r))o+=1000;if(s==="app")o+=120;else if(s==="webview")o+=100;else if(s==="page")o+=80;else if(s==="iframe")o+=20;if(t.startsWith("http://localhost")||t.startsWith("https://localhost"))o+=90;if(t.startsWith("file://"))o+=60;if(t.startsWith("http://127.0.0.1")||t.startsWith("https://127.0.0.1"))o+=50;if(t.startsWith("about:blank"))o-=120;if(t===""||t==="about:blank")o-=40;if(i&&i!=="devtools")o+=25;const d=Object.values(k()).map((a)=>(a.displayName??a.processName).toLowerCase());for(const a of d)if(i.includes(a)){o+=120;break}for(const a of d)if(t.includes(a)){o+=100;break}return o}function S(e){const n=e?.trim();if(!n)return;return new RegExp(T(n.toLowerCase()))}function T(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export const __test__={selectCDPTarget:g,scoreCDPTarget:w};function q(e){return new Promise((n,s)=>{const t=new URL(e),i=(t.protocol==="https:"?y:_)(t,(r)=>{const o=r.statusCode??0;if(o<200||o>=300){r.resume();s(Error(`Failed to fetch CDP targets: HTTP ${o}`));return}const d=[];r.on("data",(a)=>d.push(Buffer.isBuffer(a)?a:Buffer.from(a)));r.on("end",()=>{try{n(JSON.parse(Buffer.concat(d).toString("utf8")))}catch(a){s(a instanceof Error?a:Error(String(a)))}})});i.on("error",s);i.setTimeout(1e4,()=>i.destroy(Error("Timed out fetching CDP targets")));i.end()})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sleep as
|
|
1
|
+
import{sleep as b}from"../utils.js";import{BrowserConnectError as g,SessionBusyError as C}from"../errors.js";import{COMMAND_RESULT_UNKNOWN_CODE as l,COMMAND_RESULT_UNKNOWN_HINT as h}from"../daemon-utils.js";import{classifyBrowserError as A}from"./errors.js";import{resolveProfileContextId as v}from"./profile.js";import{DEFAULT_BROWSER_CONNECT_TIMEOUT as P}from"./config.js";import{ensureBrowserBridgeReady as H}from"./daemon-lifecycle.js";import{isPreDispatchError as L}from"./bridge-readiness.js";import{fetchDaemonStatus,getDaemonHealth,requestDaemon as M,requestDaemonShutdown}from"./daemon-transport.js";let S=0;function p(){return`cmd_${process.pid}_${Date.now()}_${++S}`}export function generateRunId(){return`run_${process.pid}_${Date.now()}_${++S}`}let c=null;export function setDaemonRunContext(e){c=e}export function clearDaemonRunContext(e){if(c?.runId===e)c=null}export async function releaseSiteSessionLease(e){try{await M("/command",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:p(),action:"lease-release",runId:e.runId,session:e.session,surface:e.surface}),timeout:2000})}catch{}}const W=120,k=15000,F=1e4;let x=null;export function setDaemonCommandTimeoutSeconds(e){x=typeof e==="number"&&e>0?Math.ceil(e):null}function j(e){const t=x??W;if(typeof e.timeoutMs==="number"&&e.timeoutMs>0)return Math.max(t,Math.ceil((e.timeoutMs+k)/1000));return t}const J="1.1.0";function q(e,t){if(!e)return!1;const n=e.replace(/^v/,"").split("-")[0].split(".").map(Number),r=t.split(".").map(Number);if(n.length<3||n.some(Number.isNaN))return!1;for(let s=0;s<3;s++){const a=n[s]-(r[s]??0);if(a!==0)return a>0}return!0}const D=new Set(["command_result_unknown","command_lost","result_evicted"]);export function isUnknownOutcomeError(e){const t=new Set;let n=e;while(n&&typeof n==="object"&&!t.has(n)){t.add(n);const r=n.code;if(typeof r==="string"&&D.has(r))return!0;n=n.cause}return!1}const B=4,K=new Set(["ECONNREFUSED","UND_ERR_CONNECT_TIMEOUT","EHOSTUNREACH","ENETUNREACH","ENOTFOUND"]);function X(e){const t=[e],n=new Set;while(t.length){const r=t.pop();if(!r||typeof r!=="object"||n.has(r))continue;n.add(r);const{code:s,cause:a,errors:u}=r;if(typeof s==="string"&&K.has(s))return!0;if(a)t.push(a);if(Array.isArray(u))t.push(...u)}return!1}export class BrowserCommandError extends Error{code;hint;constructor(e,t,n){super(e);this.code=t;this.hint=n;this.name="BrowserCommandError"}}export{fetchDaemonStatus,getDaemonHealth,requestDaemonShutdown};async function R(e,t){const n=j(t),r=Date.now()+n*1000,s=process.env.OPENCLI_WINDOW,a=s==="foreground"||s==="background"?s:void 0,u=t.contextId??v(),T=t.windowMode??a,I=e==="navigate";let E=!1,w=p(),m=!1,O=!1,_=null;const f=async()=>{const d=Math.ceil((r-Date.now())/1000),N=await H({timeoutSeconds:Math.max(1,Math.min(P,d)),contextId:u,verbose:!1});_=q(N.health.status?.extensionVersion,J)};for(let d=1;d<=B;d++){if(d>1&&Date.now()>=r)throw new BrowserCommandError("Browser command deadline exhausted across transport retries.",l,h);const N=Math.max(1000,r-Date.now()),U={id:w,action:e,...t,timeout:n,deadlineAt:r,...u&&{contextId:u},...T&&{windowMode:T},...c&&{runId:c.runId,command:c.command,access:c.access}};try{const o=await(await M("/command",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(U),timeout:N+F})).json();if(o.ok)return o;if(o.errorCode==="session_busy")throw new C(o.error??"The site session is busy.",o.errorHint);if(o.errorCode&&D.has(o.errorCode)){if(I&&!E){E=!0;w=p();await f();continue}throw new BrowserCommandError(o.error??"Browser command result is unknown",o.errorCode,o.errorHint)}if(L(o.errorCode)&&!m){m=!0;await f();continue}if(o.errorCode==="daemon_shutting_down"&&!m){m=!0;await f();if(_)continue;throw new BrowserCommandError(o.error??"Daemon shut down mid-command; the command may have already been applied.",l,h)}const y=A(new BrowserCommandError(o.error??"",o.errorCode));if(y.kind==="extension-transient"&&!O){O=!0;w=p();await b(y.delayMs);continue}throw new BrowserCommandError(o.error??"Daemon command failed",o.errorCode,o.errorHint)}catch(i){if(i instanceof BrowserCommandError||i instanceof g||i instanceof C)throw i;if(i instanceof Error&&i.name==="AbortError")throw new BrowserCommandError("Browser command timed out client-side; the page may still have applied it.",l,h);if(i instanceof TypeError){await f();if(_||X(i))continue;throw new BrowserCommandError("Connection to the daemon was lost mid-command; it may have already been applied.",l,h)}throw i}}throw new BrowserCommandError("sendCommand: max attempts exhausted","max_attempts_exhausted")}export async function sendCommand(e,t={}){return(await R(e,t)).data}export async function sendCommandFull(e,t={}){const n=await R(e,t);return{data:n.data,page:n.page}}export async function bindTab(e,t={}){return sendCommand("bind",{session:e,surface:"browser",...t})}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{spawn as
|
|
2
|
-
`);let
|
|
3
|
-
Run manually: ppcli daemon stop`,"daemon-not-running");
|
|
4
|
-
`);
|
|
1
|
+
import{spawn as y}from"node:child_process";import{fileURLToPath as g}from"node:url";import*as v from"node:fs";import*as d from"node:path";import{DEFAULT_DAEMON_PORT}from"../constants.js";import{BrowserConnectError as i}from"../errors.js";import{PKG_VERSION as w}from"../version.js";import{waitForBridgeReady as E}from"./bridge-readiness.js";import{fetchDaemonStatus as P,getDaemonHealth as h,requestDaemonShutdown as D}from"./daemon-transport.js";export function resolveDaemonLaunchSpec(){const e=d.dirname(g(import.meta.url)),t=d.resolve(e,".."),o=d.join(t,"daemon.ts"),s=d.join(t,"daemon.js"),r=v.existsSync(o),n=r?o:s,a=!!process.versions?.bun,p=r&&!a;return{binary:process.execPath,args:p?["--import","tsx/esm",n]:[n],scriptPath:n}}export function spawnDaemonProcess(){const e=resolveDaemonLaunchSpec(),t=y(e.binary,e.args,{detached:!0,stdio:"ignore",env:{...process.env}});t.unref();return t}export async function waitForDaemonStop(e){const t=Date.now()+e;while(Date.now()<t){await b(200);if((await h()).state==="stopped")return!0}return!1}export async function waitForDaemonStatus(e){const t=Date.now()+e;while(Date.now()<t){const o=await P({timeout:Math.min(1000,Math.max(100,t-Date.now()))});if(o)return o;await b(200)}return null}export const daemonLifecycleHooks={requestDaemonShutdown:D,spawnDaemonProcess,waitForDaemonStop};export async function restartDaemon(e={}){const t=await P();let o=t===null;if(t){o=await D()&&await waitForDaemonStop(e.stopTimeoutMs??3000);if(!o)return{previousStatus:t,status:t,stopped:!1,spawned:!1}}spawnDaemonProcess();const s=await waitForDaemonStatus(e.startTimeoutMs??5000);return{previousStatus:t,status:s,stopped:o,spawned:!0}}export async function ensureBrowserBridgeReady(e={}){const o=(e.timeoutSeconds&&e.timeoutSeconds>0?e.timeoutSeconds:10)*1000,s=e.verbose??!0,r=e.contextId,n=await h({contextId:r}),a=n.status?.daemonVersion,p=!!n.status&&(!a||a!==w);let c=!1,m=null;if(p){const S=a?`v${a} ≠ v${w}`:`pre-version daemon, CLI is v${w}`;if(s&&(process.env.OPENCLI_VERBOSE||process.stderr.isTTY))process.stderr.write(`⚠️ Stale daemon detected (${S}). Restarting...
|
|
2
|
+
`);let f=await daemonLifecycleHooks.requestDaemonShutdown()&&await daemonLifecycleHooks.waitForDaemonStop(3000);if(!f){const u=n.status?.pid;if(typeof u==="number"&&Number.isInteger(u)&&u>0){try{process.kill(u,"SIGKILL")}catch{}f=await daemonLifecycleHooks.waitForDaemonStop(2000)}}if(!f)throw new i("Stale daemon could not be replaced",`A stale daemon (${S}) is running but did not shut down (graceful + SIGKILL both failed).
|
|
3
|
+
Run manually: ppcli daemon stop`,"daemon-not-running");c=!0}if(!c&&n.state==="ready")return{health:n,spawnedProcess:m};if(!c&&n.state==="profile-required")throw x(n,r);if(c||n.state==="stopped"){if(s&&(process.env.OPENCLI_VERBOSE||process.stderr.isTTY))process.stderr.write(`⏳ Starting daemon...
|
|
4
|
+
`);m=daemonLifecycleHooks.spawnDaemonProcess()}else if(s&&(process.env.OPENCLI_VERBOSE||process.stderr.isTTY)){process.stderr.write(`⏳ Waiting for Chrome/Chromium extension to connect...
|
|
5
5
|
`);process.stderr.write(` Make sure Chrome or Chromium is open and the ppcli extension is enabled.
|
|
6
|
-
`)}const
|
|
7
|
-
Run ppcli profile list to see connected profiles.`,"profile-required");if(
|
|
6
|
+
`)}const l=await E(h,{timeoutMs:o,contextId:r});if(l.state==="ready")return{health:l,spawnedProcess:m};throw x(l,r)}function x(e,t){if(e.state==="profile-required")return new i("Multiple Browser Bridge profiles are connected",`Select one with --profile <name>, OPENCLI_PROFILE=<name>, or ppcli profile use <name>.
|
|
7
|
+
Run ppcli profile list to see connected profiles.`,"profile-required");if(e.state==="profile-disconnected"){const o=t??e.status.contextId??"unknown";return new i(`浏览器环境 "${o}" 未连接`,`这台机器上名为 "${o}" 的浏览器环境当前没连上。请用户打开 PublishPort 客户端,`+"在「高级设置 → 环境」里确认该环境已启动;或改用其它环境(--profile <名字>),"+"不带 --profile 则用默认环境。这是设备侧环境问题,重试同一条命令不会好转,请先告知用户。","profile-disconnected")}if(e.state==="no-extension")return new i("浏览器桥未连接","这台机器上的 PublishPort 托管浏览器当前没在运行(或浏览器插件被禁用了)。"+"请用户打开 PublishPort 客户端,在平台列表里点一次「检测登录」,客户端会把托管浏览器拉起来;"+"若仍不行,重启一次 PublishPort 客户端。这是设备侧环境问题,重试同一条命令不会好转,请先告知用户。","extension-not-connected");return new i("Failed to start ppcli daemon",`Try running manually:
|
|
8
8
|
node ${resolveDaemonLaunchSpec().scriptPath}
|
|
9
|
-
Make sure port ${DEFAULT_DAEMON_PORT} is available.`,"daemon-not-running")}function
|
|
9
|
+
Make sure port ${DEFAULT_DAEMON_PORT} is available.`,"daemon-not-running")}function b(e){return new Promise((t)=>setTimeout(t,e))}export{DEFAULT_DAEMON_PORT};
|