@jackwener/opencli 1.6.1 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -49
- package/README.zh-CN.md +37 -39
- package/dist/browser/cdp.d.ts +1 -40
- package/dist/browser/cdp.js +2 -314
- package/dist/browser/page.d.ts +1 -57
- package/dist/browser/page.js +2 -222
- package/dist/browser/utils.d.ts +1 -10
- package/dist/browser/utils.js +2 -27
- package/dist/cli-manifest.json +1846 -351
- package/dist/clis/1688/item.d.ts +70 -0
- package/dist/clis/1688/item.js +187 -0
- package/dist/clis/1688/item.test.js +67 -0
- package/dist/clis/1688/search.d.ts +56 -0
- package/dist/clis/1688/search.js +309 -0
- package/dist/clis/1688/search.test.js +75 -0
- package/dist/clis/1688/shared.d.ts +112 -0
- package/dist/clis/1688/shared.js +514 -0
- package/dist/clis/1688/shared.test.js +57 -0
- package/dist/clis/1688/store.d.ts +45 -0
- package/dist/clis/1688/store.js +226 -0
- package/dist/clis/1688/store.test.js +62 -0
- package/dist/clis/36kr/article.js +2 -2
- package/dist/clis/36kr/hot.js +12 -6
- package/dist/clis/36kr/news.js +1 -1
- package/dist/clis/36kr/search.js +12 -6
- package/dist/clis/_shared/desktop-commands.d.ts +5 -5
- package/dist/clis/_shared/desktop-commands.js +1 -1
- package/dist/clis/amazon/bestsellers.d.ts +0 -20
- package/dist/clis/amazon/bestsellers.js +6 -129
- package/dist/clis/amazon/bestsellers.test.js +12 -3
- package/dist/clis/amazon/discussion.js +2 -2
- package/dist/clis/amazon/movers-shakers.js +7 -0
- package/dist/clis/amazon/new-releases.js +7 -0
- package/dist/clis/amazon/offer.js +2 -2
- package/dist/clis/amazon/product.js +2 -2
- package/dist/clis/amazon/rankings.d.ts +59 -0
- package/dist/clis/amazon/rankings.js +226 -0
- package/dist/clis/amazon/rankings.test.js +41 -0
- package/dist/clis/amazon/search.js +2 -2
- package/dist/clis/amazon/shared.d.ts +12 -1
- package/dist/clis/amazon/shared.js +122 -12
- package/dist/clis/amazon/shared.test.js +11 -0
- package/dist/clis/antigravity/dump.d.ts +1 -1
- package/dist/clis/antigravity/dump.js +1 -1
- package/dist/clis/antigravity/extract-code.d.ts +1 -1
- package/dist/clis/antigravity/extract-code.js +1 -1
- package/dist/clis/antigravity/model.d.ts +1 -1
- package/dist/clis/antigravity/model.js +1 -1
- package/dist/clis/antigravity/new.d.ts +1 -1
- package/dist/clis/antigravity/new.js +1 -1
- package/dist/clis/antigravity/read.d.ts +1 -1
- package/dist/clis/antigravity/read.js +1 -1
- package/dist/clis/antigravity/send.d.ts +1 -1
- package/dist/clis/antigravity/send.js +1 -1
- package/dist/clis/antigravity/serve.js +2 -2
- package/dist/clis/antigravity/status.d.ts +1 -1
- package/dist/clis/antigravity/status.js +1 -1
- package/dist/clis/antigravity/watch.d.ts +1 -1
- package/dist/clis/antigravity/watch.js +1 -1
- package/dist/clis/apple-podcasts/commands.test.js +1 -1
- package/dist/clis/apple-podcasts/episodes.js +2 -2
- package/dist/clis/apple-podcasts/search.js +2 -2
- package/dist/clis/apple-podcasts/top.js +2 -2
- package/dist/clis/apple-podcasts/utils.js +1 -1
- package/dist/clis/arxiv/paper.js +2 -2
- package/dist/clis/arxiv/search.js +2 -2
- package/dist/clis/arxiv/utils.js +1 -1
- package/dist/clis/band/bands.js +2 -2
- package/dist/clis/band/mentions.js +2 -2
- package/dist/clis/band/post.js +2 -2
- package/dist/clis/band/posts.js +2 -2
- package/dist/clis/barchart/flow.js +1 -1
- package/dist/clis/barchart/greeks.js +1 -1
- package/dist/clis/barchart/options.js +1 -1
- package/dist/clis/barchart/quote.js +1 -1
- package/dist/clis/bbc/news.js +1 -1
- package/dist/clis/bilibili/comments.js +3 -3
- package/dist/clis/bilibili/comments.test.js +4 -3
- package/dist/clis/bilibili/download.js +3 -2
- package/dist/clis/bilibili/dynamic.js +1 -1
- package/dist/clis/bilibili/dynamic.test.js +1 -1
- package/dist/clis/bilibili/favorite.js +1 -1
- package/dist/clis/bilibili/feed.js +1 -1
- package/dist/clis/bilibili/following.js +2 -2
- package/dist/clis/bilibili/history.js +1 -1
- package/dist/clis/bilibili/me.js +1 -1
- package/dist/clis/bilibili/ranking.js +1 -1
- package/dist/clis/bilibili/search.js +1 -1
- package/dist/clis/bilibili/subtitle.js +6 -5
- package/dist/clis/bilibili/subtitle.test.js +4 -3
- package/dist/clis/bilibili/user-videos.js +1 -1
- package/dist/clis/bilibili/utils.d.ts +6 -1
- package/dist/clis/bilibili/utils.js +31 -1
- package/dist/clis/bilibili/utils.test.js +17 -0
- package/dist/clis/bloomberg/businessweek.js +1 -1
- package/dist/clis/bloomberg/economics.js +1 -1
- package/dist/clis/bloomberg/feeds.js +1 -1
- package/dist/clis/bloomberg/industries.js +1 -1
- package/dist/clis/bloomberg/main.js +1 -1
- package/dist/clis/bloomberg/markets.js +1 -1
- package/dist/clis/bloomberg/news.js +2 -2
- package/dist/clis/bloomberg/opinions.js +1 -1
- package/dist/clis/bloomberg/politics.js +1 -1
- package/dist/clis/bloomberg/tech.js +1 -1
- package/dist/clis/bloomberg/utils.js +1 -1
- package/dist/clis/boss/batchgreet.js +1 -1
- package/dist/clis/boss/chatlist.js +1 -1
- package/dist/clis/boss/chatmsg.js +1 -1
- package/dist/clis/boss/detail.js +1 -1
- package/dist/clis/boss/exchange.js +1 -1
- package/dist/clis/boss/greet.js +1 -1
- package/dist/clis/boss/invite.js +1 -1
- package/dist/clis/boss/joblist.js +1 -1
- package/dist/clis/boss/mark.js +2 -2
- package/dist/clis/boss/recommend.js +1 -1
- package/dist/clis/boss/resume.js +1 -1
- package/dist/clis/boss/search.js +1 -1
- package/dist/clis/boss/send.js +2 -2
- package/dist/clis/boss/stats.js +1 -1
- package/dist/clis/boss/utils.d.ts +1 -1
- package/dist/clis/chaoxing/assignments.js +2 -2
- package/dist/clis/chaoxing/exams.js +1 -1
- package/dist/clis/chaoxing/utils.d.ts +1 -1
- package/dist/clis/chatgpt/ask.d.ts +1 -1
- package/dist/clis/chatgpt/ask.js +2 -2
- package/dist/clis/chatgpt/model.d.ts +1 -1
- package/dist/clis/chatgpt/model.js +2 -2
- package/dist/clis/chatgpt/new.d.ts +1 -1
- package/dist/clis/chatgpt/new.js +2 -2
- package/dist/clis/chatgpt/read.d.ts +1 -1
- package/dist/clis/chatgpt/read.js +2 -2
- package/dist/clis/chatgpt/send.d.ts +1 -1
- package/dist/clis/chatgpt/send.js +2 -2
- package/dist/clis/chatgpt/status.d.ts +1 -1
- package/dist/clis/chatgpt/status.js +2 -2
- package/dist/clis/chatwise/ask.d.ts +1 -1
- package/dist/clis/chatwise/ask.js +2 -2
- package/dist/clis/chatwise/export.d.ts +1 -1
- package/dist/clis/chatwise/export.js +1 -1
- package/dist/clis/chatwise/history.d.ts +1 -1
- package/dist/clis/chatwise/history.js +1 -1
- package/dist/clis/chatwise/model.d.ts +1 -1
- package/dist/clis/chatwise/model.js +2 -2
- package/dist/clis/chatwise/new.d.ts +1 -1
- package/dist/clis/chatwise/read.d.ts +1 -1
- package/dist/clis/chatwise/read.js +1 -1
- package/dist/clis/chatwise/screenshot.d.ts +1 -1
- package/dist/clis/chatwise/send.d.ts +1 -1
- package/dist/clis/chatwise/send.js +2 -2
- package/dist/clis/chatwise/status.d.ts +1 -1
- package/dist/clis/codex/ask.d.ts +1 -1
- package/dist/clis/codex/ask.js +2 -2
- package/dist/clis/codex/dump.d.ts +1 -1
- package/dist/clis/codex/export.d.ts +1 -1
- package/dist/clis/codex/export.js +1 -1
- package/dist/clis/codex/extract-diff.d.ts +1 -1
- package/dist/clis/codex/extract-diff.js +1 -1
- package/dist/clis/codex/history.d.ts +1 -1
- package/dist/clis/codex/history.js +1 -1
- package/dist/clis/codex/model.d.ts +1 -1
- package/dist/clis/codex/model.js +1 -1
- package/dist/clis/codex/new.d.ts +1 -1
- package/dist/clis/codex/read.d.ts +1 -1
- package/dist/clis/codex/read.js +1 -1
- package/dist/clis/codex/screenshot.d.ts +1 -1
- package/dist/clis/codex/send.d.ts +1 -1
- package/dist/clis/codex/send.js +2 -2
- package/dist/clis/codex/status.d.ts +1 -1
- package/dist/clis/coupang/add-to-cart.js +1 -1
- package/dist/clis/coupang/search.js +1 -1
- package/dist/clis/ctrip/search.js +2 -2
- package/dist/clis/ctrip/search.test.js +1 -1
- package/dist/clis/cursor/ask.d.ts +1 -1
- package/dist/clis/cursor/ask.js +2 -2
- package/dist/clis/cursor/composer.d.ts +1 -1
- package/dist/clis/cursor/composer.js +2 -2
- package/dist/clis/cursor/dump.d.ts +1 -1
- package/dist/clis/cursor/export.d.ts +1 -1
- package/dist/clis/cursor/export.js +1 -1
- package/dist/clis/cursor/extract-code.d.ts +1 -1
- package/dist/clis/cursor/extract-code.js +1 -1
- package/dist/clis/cursor/history.d.ts +1 -1
- package/dist/clis/cursor/history.js +1 -1
- package/dist/clis/cursor/model.d.ts +1 -1
- package/dist/clis/cursor/model.js +1 -1
- package/dist/clis/cursor/new.d.ts +1 -1
- package/dist/clis/cursor/read.d.ts +1 -1
- package/dist/clis/cursor/read.js +2 -2
- package/dist/clis/cursor/screenshot.d.ts +1 -1
- package/dist/clis/cursor/send.d.ts +1 -1
- package/dist/clis/cursor/send.js +2 -2
- package/dist/clis/cursor/status.d.ts +1 -1
- package/dist/clis/discord-app/channels.d.ts +1 -1
- package/dist/clis/discord-app/channels.js +1 -1
- package/dist/clis/discord-app/members.d.ts +1 -1
- package/dist/clis/discord-app/members.js +1 -1
- package/dist/clis/discord-app/read.d.ts +1 -1
- package/dist/clis/discord-app/read.js +1 -1
- package/dist/clis/discord-app/search.d.ts +1 -1
- package/dist/clis/discord-app/search.js +1 -1
- package/dist/clis/discord-app/send.d.ts +1 -1
- package/dist/clis/discord-app/send.js +1 -1
- package/dist/clis/discord-app/servers.d.ts +1 -1
- package/dist/clis/discord-app/servers.js +1 -1
- package/dist/clis/discord-app/status.d.ts +1 -1
- package/dist/clis/discord-app/status.js +1 -1
- package/dist/clis/douban/book-hot.js +1 -1
- package/dist/clis/douban/download.js +2 -2
- package/dist/clis/douban/download.test.js +1 -1
- package/dist/clis/douban/marks.js +2 -2
- package/dist/clis/douban/movie-hot.js +1 -1
- package/dist/clis/douban/photos.js +1 -1
- package/dist/clis/douban/reviews.js +1 -1
- package/dist/clis/douban/search.js +1 -1
- package/dist/clis/douban/subject.yaml +50 -19
- package/dist/clis/douban/utils.d.ts +1 -1
- package/dist/clis/douban/utils.js +1 -1
- package/dist/clis/doubao/ask.d.ts +1 -1
- package/dist/clis/doubao/ask.js +1 -1
- package/dist/clis/doubao/detail.d.ts +1 -1
- package/dist/clis/doubao/detail.js +1 -1
- package/dist/clis/doubao/detail.test.js +1 -1
- package/dist/clis/doubao/history.d.ts +1 -1
- package/dist/clis/doubao/history.js +1 -1
- package/dist/clis/doubao/history.test.js +1 -1
- package/dist/clis/doubao/meeting-summary.d.ts +1 -1
- package/dist/clis/doubao/meeting-summary.js +1 -1
- package/dist/clis/doubao/meeting-transcript.d.ts +1 -1
- package/dist/clis/doubao/meeting-transcript.js +1 -1
- package/dist/clis/doubao/new.d.ts +1 -1
- package/dist/clis/doubao/new.js +1 -1
- package/dist/clis/doubao/read.d.ts +1 -1
- package/dist/clis/doubao/read.js +1 -1
- package/dist/clis/doubao/send.d.ts +1 -1
- package/dist/clis/doubao/send.js +1 -1
- package/dist/clis/doubao/status.d.ts +1 -1
- package/dist/clis/doubao/status.js +1 -1
- package/dist/clis/doubao/utils.d.ts +1 -1
- package/dist/clis/doubao/utils.js +32 -12
- package/dist/clis/doubao-app/ask.d.ts +1 -1
- package/dist/clis/doubao-app/ask.js +1 -1
- package/dist/clis/doubao-app/dump.d.ts +1 -1
- package/dist/clis/doubao-app/dump.js +1 -1
- package/dist/clis/doubao-app/new.d.ts +1 -1
- package/dist/clis/doubao-app/new.js +1 -1
- package/dist/clis/doubao-app/read.d.ts +1 -1
- package/dist/clis/doubao-app/read.js +1 -1
- package/dist/clis/doubao-app/screenshot.d.ts +1 -1
- package/dist/clis/doubao-app/screenshot.js +1 -1
- package/dist/clis/doubao-app/send.d.ts +1 -1
- package/dist/clis/doubao-app/send.js +1 -1
- package/dist/clis/doubao-app/status.d.ts +1 -1
- package/dist/clis/doubao-app/status.js +1 -1
- package/dist/clis/douyin/_shared/browser-fetch.d.ts +1 -1
- package/dist/clis/douyin/_shared/browser-fetch.js +1 -1
- package/dist/clis/douyin/_shared/browser-fetch.test.js +0 -1
- package/dist/clis/douyin/_shared/imagex-upload.js +1 -1
- package/dist/clis/douyin/_shared/imagex-upload.test.js +1 -1
- package/dist/clis/douyin/_shared/public-api.d.ts +1 -1
- package/dist/clis/douyin/_shared/sts2.d.ts +1 -1
- package/dist/clis/douyin/_shared/sts2.js +1 -1
- package/dist/clis/douyin/_shared/sts2.test.js +1 -1
- package/dist/clis/douyin/_shared/tos-upload-short-read.test.js +1 -1
- package/dist/clis/douyin/_shared/tos-upload.js +1 -1
- package/dist/clis/douyin/_shared/transcode.d.ts +1 -1
- package/dist/clis/douyin/_shared/transcode.js +1 -1
- package/dist/clis/douyin/_shared/transcode.test.js +1 -3
- package/dist/clis/douyin/activities.js +1 -1
- package/dist/clis/douyin/activities.test.js +1 -1
- package/dist/clis/douyin/collections.js +1 -1
- package/dist/clis/douyin/collections.test.js +1 -1
- package/dist/clis/douyin/delete.js +1 -1
- package/dist/clis/douyin/delete.test.js +1 -1
- package/dist/clis/douyin/draft.js +2 -2
- package/dist/clis/douyin/draft.test.js +1 -3
- package/dist/clis/douyin/drafts.js +1 -1
- package/dist/clis/douyin/drafts.test.js +1 -1
- package/dist/clis/douyin/hashtag.js +2 -2
- package/dist/clis/douyin/hashtag.test.js +1 -1
- package/dist/clis/douyin/location.js +1 -1
- package/dist/clis/douyin/location.test.js +1 -1
- package/dist/clis/douyin/profile.js +2 -2
- package/dist/clis/douyin/profile.test.js +1 -1
- package/dist/clis/douyin/publish.js +2 -2
- package/dist/clis/douyin/publish.test.js +1 -1
- package/dist/clis/douyin/stats.js +1 -1
- package/dist/clis/douyin/stats.test.js +1 -1
- package/dist/clis/douyin/update.js +2 -2
- package/dist/clis/douyin/update.test.js +1 -1
- package/dist/clis/douyin/user-videos.js +1 -1
- package/dist/clis/douyin/user-videos.test.js +1 -1
- package/dist/clis/douyin/videos.js +1 -1
- package/dist/clis/douyin/videos.test.js +1 -1
- package/dist/clis/facebook/search.test.js +0 -2
- package/dist/clis/gemini/ask.d.ts +1 -1
- package/dist/clis/gemini/ask.js +10 -4
- package/dist/clis/gemini/ask.test.js +100 -0
- package/dist/clis/gemini/deep-research-result.d.ts +1 -0
- package/dist/clis/gemini/deep-research-result.js +91 -0
- package/dist/clis/gemini/deep-research-result.test.js +154 -0
- package/dist/clis/gemini/deep-research.d.ts +1 -0
- package/dist/clis/gemini/deep-research.js +98 -0
- package/dist/clis/gemini/deep-research.test.js +184 -0
- package/dist/clis/gemini/image.d.ts +1 -1
- package/dist/clis/gemini/image.js +2 -2
- package/dist/clis/gemini/new.d.ts +1 -1
- package/dist/clis/gemini/new.js +1 -1
- package/dist/clis/gemini/reply-state.test.js +671 -0
- package/dist/clis/gemini/utils.d.ts +74 -2
- package/dist/clis/gemini/utils.js +1540 -61
- package/dist/clis/gemini/utils.test.js +169 -2
- package/dist/clis/google/news.js +2 -2
- package/dist/clis/google/search.js +2 -2
- package/dist/clis/google/suggest.js +2 -2
- package/dist/clis/google/trends.js +2 -2
- package/dist/clis/grok/ask.d.ts +2 -2
- package/dist/clis/grok/ask.js +1 -1
- package/dist/clis/hf/top.js +2 -2
- package/dist/clis/hupu/detail.js +72 -0
- package/dist/clis/hupu/hot.yaml +43 -0
- package/dist/clis/hupu/like.js +75 -0
- package/dist/clis/hupu/mentions.js +159 -0
- package/dist/clis/hupu/reply.js +71 -0
- package/dist/clis/hupu/search.js +59 -0
- package/dist/clis/hupu/unlike.js +75 -0
- package/dist/clis/hupu/utils.d.ts +20 -0
- package/dist/clis/hupu/utils.js +319 -0
- package/dist/clis/imdb/person.js +2 -2
- package/dist/clis/imdb/reviews.js +2 -2
- package/dist/clis/imdb/search.js +2 -2
- package/dist/clis/imdb/title.js +2 -2
- package/dist/clis/imdb/top.js +2 -2
- package/dist/clis/imdb/trending.js +2 -2
- package/dist/clis/imdb/utils.d.ts +1 -1
- package/dist/clis/imdb/utils.js +1 -1
- package/dist/clis/instagram/_shared/private-publish.d.ts +138 -0
- package/dist/clis/instagram/_shared/private-publish.js +1030 -0
- package/dist/clis/instagram/_shared/private-publish.test.js +705 -0
- package/dist/clis/instagram/_shared/protocol-capture.d.ts +26 -0
- package/dist/clis/instagram/_shared/protocol-capture.js +282 -0
- package/dist/clis/instagram/_shared/protocol-capture.test.js +114 -0
- package/dist/clis/instagram/_shared/runtime-info.d.ts +9 -0
- package/dist/clis/instagram/_shared/runtime-info.js +81 -0
- package/dist/clis/instagram/download.js +2 -2
- package/dist/clis/instagram/download.test.js +2 -2
- package/dist/clis/instagram/note.js +222 -0
- package/dist/clis/instagram/note.test.d.ts +1 -0
- package/dist/clis/instagram/note.test.js +81 -0
- package/dist/clis/instagram/post.d.ts +4 -0
- package/dist/clis/instagram/post.js +1496 -0
- package/dist/clis/instagram/post.test.d.ts +1 -0
- package/dist/clis/instagram/post.test.js +1647 -0
- package/dist/clis/instagram/reel.js +826 -0
- package/dist/clis/instagram/reel.test.d.ts +1 -0
- package/dist/clis/instagram/reel.test.js +167 -0
- package/dist/clis/instagram/story.js +115 -0
- package/dist/clis/instagram/story.test.d.ts +1 -0
- package/dist/clis/instagram/story.test.js +167 -0
- package/dist/clis/jd/item.js +1 -1
- package/dist/clis/jd/item.test.js +1 -1
- package/dist/clis/jike/comment.js +1 -1
- package/dist/clis/jike/create.js +1 -1
- package/dist/clis/jike/feed.js +1 -1
- package/dist/clis/jike/like.js +1 -1
- package/dist/clis/jike/notifications.js +1 -1
- package/dist/clis/jike/repost.js +1 -1
- package/dist/clis/jike/search.js +1 -1
- package/dist/clis/lesswrong/_helpers.d.ts +15 -0
- package/dist/clis/lesswrong/_helpers.js +75 -0
- package/dist/clis/lesswrong/comments.js +64 -0
- package/dist/clis/lesswrong/curated.js +30 -0
- package/dist/clis/lesswrong/frontpage.js +30 -0
- package/dist/clis/lesswrong/new.js +30 -0
- package/dist/clis/lesswrong/read.js +45 -0
- package/dist/clis/lesswrong/sequences.d.ts +1 -0
- package/dist/clis/lesswrong/sequences.js +27 -0
- package/dist/clis/lesswrong/shortform.d.ts +1 -0
- package/dist/clis/lesswrong/shortform.js +30 -0
- package/dist/clis/lesswrong/tag.d.ts +1 -0
- package/dist/clis/lesswrong/tag.js +45 -0
- package/dist/clis/lesswrong/tags.d.ts +1 -0
- package/dist/clis/lesswrong/tags.js +27 -0
- package/dist/clis/lesswrong/top-month.d.ts +1 -0
- package/dist/clis/lesswrong/top-month.js +30 -0
- package/dist/clis/lesswrong/top-week.d.ts +1 -0
- package/dist/clis/lesswrong/top-week.js +30 -0
- package/dist/clis/lesswrong/top-year.d.ts +1 -0
- package/dist/clis/lesswrong/top-year.js +30 -0
- package/dist/clis/lesswrong/top.d.ts +1 -0
- package/dist/clis/lesswrong/top.js +30 -0
- package/dist/clis/lesswrong/user-posts.d.ts +1 -0
- package/dist/clis/lesswrong/user-posts.js +41 -0
- package/dist/clis/lesswrong/user.d.ts +1 -0
- package/dist/clis/lesswrong/user.js +44 -0
- package/dist/clis/linkedin/search.js +2 -2
- package/dist/clis/linkedin/timeline.js +2 -2
- package/dist/clis/linkedin/timeline.test.js +1 -1
- package/dist/clis/linux-do/category.js +1 -1
- package/dist/clis/linux-do/feed.d.ts +2 -2
- package/dist/clis/linux-do/feed.js +2 -2
- package/dist/clis/linux-do/hot.js +1 -1
- package/dist/clis/linux-do/latest.js +1 -1
- package/dist/clis/medium/feed.js +1 -1
- package/dist/clis/medium/search.js +1 -1
- package/dist/clis/medium/user.js +1 -1
- package/dist/clis/medium/utils.d.ts +1 -1
- package/dist/clis/medium/utils.js +1 -1
- package/dist/clis/notebooklm/compat.test.js +1 -1
- package/dist/clis/notebooklm/current.js +2 -2
- package/dist/clis/notebooklm/get.js +2 -2
- package/dist/clis/notebooklm/history.js +2 -2
- package/dist/clis/notebooklm/history.test.js +1 -1
- package/dist/clis/notebooklm/list.js +2 -2
- package/dist/clis/notebooklm/note-list.js +2 -2
- package/dist/clis/notebooklm/note-list.test.js +1 -1
- package/dist/clis/notebooklm/notes-get.js +2 -2
- package/dist/clis/notebooklm/notes-get.test.js +1 -1
- package/dist/clis/notebooklm/open.js +2 -2
- package/dist/clis/notebooklm/open.test.js +1 -1
- package/dist/clis/notebooklm/rpc.d.ts +1 -1
- package/dist/clis/notebooklm/rpc.js +1 -1
- package/dist/clis/notebooklm/rpc.test.js +1 -1
- package/dist/clis/notebooklm/source-fulltext.js +2 -2
- package/dist/clis/notebooklm/source-fulltext.test.js +1 -1
- package/dist/clis/notebooklm/source-get.js +2 -2
- package/dist/clis/notebooklm/source-get.test.js +1 -1
- package/dist/clis/notebooklm/source-guide.js +2 -2
- package/dist/clis/notebooklm/source-guide.test.js +1 -1
- package/dist/clis/notebooklm/source-list.js +2 -2
- package/dist/clis/notebooklm/status.js +1 -1
- package/dist/clis/notebooklm/summary.js +2 -2
- package/dist/clis/notebooklm/summary.test.js +1 -1
- package/dist/clis/notebooklm/utils.d.ts +1 -1
- package/dist/clis/notebooklm/utils.js +1 -1
- package/dist/clis/notion/export.d.ts +1 -1
- package/dist/clis/notion/export.js +1 -1
- package/dist/clis/notion/favorites.d.ts +1 -1
- package/dist/clis/notion/favorites.js +1 -1
- package/dist/clis/notion/new.d.ts +1 -1
- package/dist/clis/notion/new.js +1 -1
- package/dist/clis/notion/read.d.ts +1 -1
- package/dist/clis/notion/read.js +1 -1
- package/dist/clis/notion/search.d.ts +1 -1
- package/dist/clis/notion/search.js +1 -1
- package/dist/clis/notion/sidebar.d.ts +1 -1
- package/dist/clis/notion/sidebar.js +1 -1
- package/dist/clis/notion/status.d.ts +1 -1
- package/dist/clis/notion/status.js +1 -1
- package/dist/clis/notion/write.d.ts +1 -1
- package/dist/clis/notion/write.js +1 -1
- package/dist/clis/ones/common.d.ts +1 -1
- package/dist/clis/ones/common.js +1 -1
- package/dist/clis/ones/enrich-tasks.d.ts +1 -1
- package/dist/clis/ones/login.js +2 -2
- package/dist/clis/ones/logout.js +1 -1
- package/dist/clis/ones/me.js +2 -2
- package/dist/clis/ones/my-tasks.js +2 -2
- package/dist/clis/ones/resolve-labels.d.ts +1 -1
- package/dist/clis/ones/task-helpers.js +1 -1
- package/dist/clis/ones/task.js +2 -2
- package/dist/clis/ones/tasks.js +2 -2
- package/dist/clis/ones/token-info.js +2 -2
- package/dist/clis/ones/worklog.js +2 -2
- package/dist/clis/paperreview/commands.test.js +1 -1
- package/dist/clis/paperreview/feedback.js +2 -2
- package/dist/clis/paperreview/review.js +2 -2
- package/dist/clis/paperreview/submit.js +2 -2
- package/dist/clis/paperreview/utils.js +1 -1
- package/dist/clis/paperreview/utils.test.js +1 -1
- package/dist/clis/pixiv/download.js +2 -2
- package/dist/clis/pixiv/download.test.js +2 -2
- package/dist/clis/pixiv/illusts.js +2 -2
- package/dist/clis/pixiv/illusts.test.js +2 -2
- package/dist/clis/pixiv/search.js +1 -1
- package/dist/clis/pixiv/search.test.js +2 -2
- package/dist/clis/pixiv/test-utils.d.ts +1 -1
- package/dist/clis/pixiv/utils.d.ts +1 -1
- package/dist/clis/pixiv/utils.js +1 -1
- package/dist/clis/producthunt/browse.js +2 -2
- package/dist/clis/producthunt/hot.js +2 -2
- package/dist/clis/producthunt/posts.js +1 -1
- package/dist/clis/producthunt/today.js +1 -1
- package/dist/clis/reddit/comment.js +2 -2
- package/dist/clis/reddit/read.js +2 -2
- package/dist/clis/reddit/read.test.js +1 -1
- package/dist/clis/reddit/save.js +2 -2
- package/dist/clis/reddit/saved.js +2 -2
- package/dist/clis/reddit/subscribe.js +2 -2
- package/dist/clis/reddit/upvote.js +2 -2
- package/dist/clis/reddit/upvoted.js +2 -2
- package/dist/clis/reuters/search.js +1 -1
- package/dist/clis/sinablog/article.js +1 -1
- package/dist/clis/sinablog/hot.js +1 -1
- package/dist/clis/sinablog/search.js +1 -1
- package/dist/clis/sinablog/user.js +1 -1
- package/dist/clis/sinablog/utils.d.ts +1 -1
- package/dist/clis/sinafinance/news.js +2 -2
- package/dist/clis/sinafinance/rolling-news.js +1 -1
- package/dist/clis/sinafinance/stock-rank.d.ts +4 -0
- package/dist/clis/sinafinance/stock-rank.js +65 -0
- package/dist/clis/sinafinance/stock.js +2 -2
- package/dist/clis/smzdm/search.js +1 -1
- package/dist/clis/spotify/spotify.js +2 -2
- package/dist/clis/spotify/utils.js +1 -1
- package/dist/clis/substack/feed.js +1 -1
- package/dist/clis/substack/publication.js +1 -1
- package/dist/clis/substack/search.js +2 -2
- package/dist/clis/substack/utils.d.ts +1 -1
- package/dist/clis/substack/utils.js +1 -1
- package/dist/clis/substack/utils.test.js +0 -2
- package/dist/clis/tieba/commands.test.js +1 -1
- package/dist/clis/tieba/hot.js +2 -2
- package/dist/clis/tieba/posts.js +2 -2
- package/dist/clis/tieba/read.js +2 -2
- package/dist/clis/tieba/search.js +2 -2
- package/dist/clis/twitter/accept.js +2 -2
- package/dist/clis/twitter/article.js +2 -2
- package/dist/clis/twitter/block.js +2 -2
- package/dist/clis/twitter/bookmark.js +2 -2
- package/dist/clis/twitter/bookmarks.js +2 -2
- package/dist/clis/twitter/delete.d.ts +6 -0
- package/dist/clis/twitter/delete.js +82 -47
- package/dist/clis/twitter/delete.test.d.ts +1 -0
- package/dist/clis/twitter/delete.test.js +73 -0
- package/dist/clis/twitter/download.js +1 -1
- package/dist/clis/twitter/follow.js +2 -2
- package/dist/clis/twitter/followers.js +2 -2
- package/dist/clis/twitter/following.js +2 -2
- package/dist/clis/twitter/hide-reply.js +2 -2
- package/dist/clis/twitter/like.js +2 -2
- package/dist/clis/twitter/likes.js +2 -2
- package/dist/clis/twitter/notifications.js +2 -2
- package/dist/clis/twitter/post.js +74 -47
- package/dist/clis/twitter/post.test.d.ts +1 -0
- package/dist/clis/twitter/post.test.js +116 -0
- package/dist/clis/twitter/profile.js +2 -2
- package/dist/clis/twitter/reply-dm.js +2 -2
- package/dist/clis/twitter/reply.d.ts +12 -0
- package/dist/clis/twitter/reply.js +259 -37
- package/dist/clis/twitter/reply.test.d.ts +1 -0
- package/dist/clis/twitter/reply.test.js +151 -0
- package/dist/clis/twitter/search.js +2 -2
- package/dist/clis/twitter/search.test.js +1 -1
- package/dist/clis/twitter/shared.d.ts +1 -1
- package/dist/clis/twitter/thread.js +2 -2
- package/dist/clis/twitter/timeline.js +2 -2
- package/dist/clis/twitter/trending.js +2 -2
- package/dist/clis/twitter/unblock.js +2 -2
- package/dist/clis/twitter/unbookmark.js +2 -2
- package/dist/clis/twitter/unfollow.js +2 -2
- package/dist/clis/v2ex/daily.js +2 -2
- package/dist/clis/v2ex/me.js +2 -2
- package/dist/clis/v2ex/notifications.js +2 -2
- package/dist/clis/web/read.js +1 -1
- package/dist/clis/weibo/comments.js +1 -1
- package/dist/clis/weibo/feed.js +1 -1
- package/dist/clis/weibo/hot.js +1 -1
- package/dist/clis/weibo/me.js +2 -2
- package/dist/clis/weibo/post.js +2 -2
- package/dist/clis/weibo/search.js +2 -2
- package/dist/clis/weibo/user.js +2 -2
- package/dist/clis/weibo/utils.d.ts +1 -1
- package/dist/clis/weibo/utils.js +1 -1
- package/dist/clis/weixin/download.js +1 -1
- package/dist/clis/weread/book.js +2 -2
- package/dist/clis/weread/commands.test.js +2 -2
- package/dist/clis/weread/highlights.js +1 -1
- package/dist/clis/weread/notebooks.js +1 -1
- package/dist/clis/weread/notes.js +1 -1
- package/dist/clis/weread/private-api-regression.test.js +2 -2
- package/dist/clis/weread/ranking.js +1 -1
- package/dist/clis/weread/search-regression.test.js +1 -1
- package/dist/clis/weread/search.js +1 -1
- package/dist/clis/weread/shelf.js +3 -3
- package/dist/clis/weread/utils.d.ts +1 -1
- package/dist/clis/weread/utils.js +1 -1
- package/dist/clis/wikipedia/random.js +2 -2
- package/dist/clis/wikipedia/search.js +2 -2
- package/dist/clis/wikipedia/summary.js +2 -2
- package/dist/clis/wikipedia/trending.js +2 -2
- package/dist/clis/wikipedia/utils.js +1 -1
- package/dist/clis/xianyu/chat.d.ts +7 -0
- package/dist/clis/xianyu/chat.js +146 -0
- package/dist/clis/xianyu/chat.test.d.ts +1 -0
- package/dist/clis/xianyu/chat.test.js +15 -0
- package/dist/clis/xianyu/item.d.ts +7 -0
- package/dist/clis/xianyu/item.js +152 -0
- package/dist/clis/xianyu/item.test.d.ts +1 -0
- package/dist/clis/xianyu/item.test.js +56 -0
- package/dist/clis/xianyu/search.d.ts +10 -0
- package/dist/clis/xianyu/search.js +134 -0
- package/dist/clis/xianyu/search.test.d.ts +1 -0
- package/dist/clis/xianyu/search.test.js +17 -0
- package/dist/clis/xianyu/utils.d.ts +1 -0
- package/dist/clis/xianyu/utils.js +8 -0
- package/dist/clis/xiaoe/catalog.yaml +129 -0
- package/dist/clis/xiaoe/content.yaml +43 -0
- package/dist/clis/xiaoe/courses.yaml +73 -0
- package/dist/clis/xiaoe/detail.yaml +39 -0
- package/dist/clis/xiaoe/play-url.yaml +124 -0
- package/dist/clis/xiaohongshu/comments.js +2 -2
- package/dist/clis/xiaohongshu/comments.test.js +3 -5
- package/dist/clis/xiaohongshu/creator-note-detail.d.ts +1 -1
- package/dist/clis/xiaohongshu/creator-note-detail.js +1 -1
- package/dist/clis/xiaohongshu/creator-note-detail.test.js +1 -3
- package/dist/clis/xiaohongshu/creator-notes-summary.js +1 -1
- package/dist/clis/xiaohongshu/creator-notes.d.ts +1 -1
- package/dist/clis/xiaohongshu/creator-notes.js +1 -1
- package/dist/clis/xiaohongshu/creator-notes.test.js +1 -3
- package/dist/clis/xiaohongshu/creator-profile.js +1 -1
- package/dist/clis/xiaohongshu/creator-stats.js +1 -1
- package/dist/clis/xiaohongshu/download.js +1 -1
- package/dist/clis/xiaohongshu/download.test.js +1 -3
- package/dist/clis/xiaohongshu/note-helpers.d.ts +2 -2
- package/dist/clis/xiaohongshu/note-helpers.js +5 -3
- package/dist/clis/xiaohongshu/note.d.ts +4 -0
- package/dist/clis/xiaohongshu/note.js +10 -12
- package/dist/clis/xiaohongshu/note.test.js +6 -8
- package/dist/clis/xiaohongshu/publish.js +1 -1
- package/dist/clis/xiaohongshu/publish.test.js +1 -3
- package/dist/clis/xiaohongshu/search.js +31 -22
- package/dist/clis/xiaohongshu/search.test.js +57 -49
- package/dist/clis/xiaohongshu/user.js +1 -1
- package/dist/clis/xiaoyuzhou/episode.js +2 -2
- package/dist/clis/xiaoyuzhou/podcast-episodes.js +2 -2
- package/dist/clis/xiaoyuzhou/podcast.js +2 -2
- package/dist/clis/xiaoyuzhou/utils.js +1 -1
- package/dist/clis/xueqiu/comments.d.ts +1 -1
- package/dist/clis/xueqiu/comments.js +4 -4
- package/dist/clis/xueqiu/comments.test.js +3 -3
- package/dist/clis/xueqiu/danjuan-utils.d.ts +1 -1
- package/dist/clis/xueqiu/fund-holdings.js +1 -1
- package/dist/clis/xueqiu/fund-snapshot.js +1 -1
- package/dist/clis/yahoo-finance/quote.js +1 -1
- package/dist/clis/yollomi/background.js +2 -2
- package/dist/clis/yollomi/edit.js +2 -2
- package/dist/clis/yollomi/face-swap.js +2 -2
- package/dist/clis/yollomi/generate.js +2 -2
- package/dist/clis/yollomi/models.js +1 -1
- package/dist/clis/yollomi/object-remover.js +2 -2
- package/dist/clis/yollomi/remove-bg.js +2 -2
- package/dist/clis/yollomi/restore.js +2 -2
- package/dist/clis/yollomi/try-on.js +2 -2
- package/dist/clis/yollomi/upload.js +2 -2
- package/dist/clis/yollomi/upscale.js +2 -2
- package/dist/clis/yollomi/utils.d.ts +1 -1
- package/dist/clis/yollomi/utils.js +1 -1
- package/dist/clis/yollomi/video.js +2 -2
- package/dist/clis/youtube/channel.js +2 -2
- package/dist/clis/youtube/comments.js +2 -2
- package/dist/clis/youtube/search.js +1 -1
- package/dist/clis/youtube/transcript.js +2 -2
- package/dist/clis/youtube/utils.d.ts +1 -1
- package/dist/clis/youtube/video.js +2 -2
- package/dist/clis/yuanbao/ask.d.ts +21 -0
- package/dist/clis/yuanbao/ask.js +427 -0
- package/dist/clis/yuanbao/ask.test.d.ts +1 -0
- package/dist/clis/yuanbao/ask.test.js +124 -0
- package/dist/clis/yuanbao/new.d.ts +1 -0
- package/dist/clis/yuanbao/new.js +70 -0
- package/dist/clis/yuanbao/new.test.d.ts +1 -0
- package/dist/clis/yuanbao/new.test.js +30 -0
- package/dist/clis/yuanbao/shared.d.ts +13 -0
- package/dist/clis/yuanbao/shared.js +49 -0
- package/dist/clis/zhihu/download.js +1 -1
- package/dist/clis/zhihu/question.js +32 -21
- package/dist/clis/zhihu/question.test.js +35 -17
- package/dist/clis/zsxq/dynamics.js +1 -1
- package/dist/clis/zsxq/groups.js +1 -1
- package/dist/clis/zsxq/search.js +1 -1
- package/dist/clis/zsxq/search.test.js +1 -1
- package/dist/clis/zsxq/topic.js +2 -2
- package/dist/clis/zsxq/topic.test.js +1 -1
- package/dist/clis/zsxq/topics.js +1 -1
- package/dist/clis/zsxq/topics.test.js +1 -1
- package/dist/clis/zsxq/utils.d.ts +1 -1
- package/dist/clis/zsxq/utils.js +1 -1
- package/dist/download/article-download.d.ts +1 -59
- package/dist/download/article-download.js +2 -178
- package/dist/download/index.d.ts +1 -71
- package/dist/download/index.js +2 -345
- package/dist/download/media-download.d.ts +1 -49
- package/dist/download/media-download.js +2 -114
- package/dist/download/progress.d.ts +1 -36
- package/dist/download/progress.js +2 -111
- package/dist/pipeline/index.d.ts +1 -5
- package/dist/pipeline/index.js +2 -5
- package/dist/src/browser/base-page.d.ts +50 -0
- package/dist/src/browser/base-page.js +193 -0
- package/dist/src/browser/bridge.js +109 -0
- package/dist/src/browser/cdp.d.ts +40 -0
- package/dist/src/browser/cdp.js +310 -0
- package/dist/src/browser/cdp.test.d.ts +1 -0
- package/dist/src/browser/daemon-client.d.ts +74 -0
- package/dist/src/browser/daemon-client.js +113 -0
- package/dist/src/browser/daemon-client.test.d.ts +1 -0
- package/dist/src/browser/dom-helpers.d.ts +41 -0
- package/dist/src/browser/dom-helpers.js +227 -0
- package/dist/src/browser/dom-helpers.test.d.ts +1 -0
- package/dist/src/browser/dom-snapshot.js +804 -0
- package/dist/src/browser/page.d.ts +62 -0
- package/dist/src/browser/page.js +304 -0
- package/dist/src/browser/page.test.d.ts +1 -0
- package/dist/src/browser/stealth.test.d.ts +1 -0
- package/dist/src/browser/utils.d.ts +10 -0
- package/dist/src/browser/utils.js +27 -0
- package/dist/src/browser.test.d.ts +1 -0
- package/dist/src/browser.test.js +159 -0
- package/dist/src/build-manifest.d.ts +47 -0
- package/dist/src/build-manifest.js +226 -0
- package/dist/src/build-manifest.test.d.ts +1 -0
- package/dist/src/capabilityRouting.test.d.ts +1 -0
- package/dist/src/cascade.js +134 -0
- package/dist/src/cli.d.ts +22 -0
- package/dist/src/cli.js +1023 -0
- package/dist/src/cli.test.d.ts +1 -0
- package/dist/src/cli.test.js +171 -0
- package/dist/src/commanderAdapter.d.ts +23 -0
- package/dist/src/commanderAdapter.js +281 -0
- package/dist/src/commanderAdapter.test.d.ts +1 -0
- package/dist/src/commanderAdapter.test.js +244 -0
- package/dist/src/commands/daemon.test.d.ts +1 -0
- package/dist/src/completion.js +120 -0
- package/dist/src/completion.test.d.ts +1 -0
- package/dist/src/completion.test.js +23 -0
- package/dist/src/daemon.test.d.ts +1 -0
- package/dist/src/discovery.d.ts +40 -0
- package/dist/src/discovery.js +414 -0
- package/dist/src/doctor.js +126 -0
- package/dist/src/doctor.test.d.ts +1 -0
- package/dist/src/download/article-download.d.ts +59 -0
- package/dist/src/download/article-download.js +178 -0
- package/dist/src/download/index.d.ts +71 -0
- package/dist/src/download/index.js +345 -0
- package/dist/src/download/index.test.d.ts +1 -0
- package/dist/src/download/media-download.d.ts +49 -0
- package/dist/src/download/media-download.js +114 -0
- package/dist/src/download/progress.d.ts +36 -0
- package/dist/src/download/progress.js +111 -0
- package/dist/src/electron-apps.d.ts +31 -0
- package/dist/src/electron-apps.js +71 -0
- package/dist/src/electron-apps.test.d.ts +1 -0
- package/dist/src/engine.test.d.ts +1 -0
- package/dist/src/errors.js +119 -0
- package/dist/src/errors.test.d.ts +1 -0
- package/dist/src/execution.js +209 -0
- package/dist/src/execution.test.d.ts +1 -0
- package/dist/src/explore.js +379 -0
- package/dist/src/extension-manifest-regression.test.d.ts +1 -0
- package/dist/src/external.test.d.ts +1 -0
- package/dist/src/interceptor.d.ts +44 -0
- package/dist/src/interceptor.js +183 -0
- package/dist/src/launcher.d.ts +40 -0
- package/dist/src/launcher.js +208 -0
- package/dist/src/launcher.test.d.ts +1 -0
- package/dist/src/launcher.test.js +138 -0
- package/dist/src/main.js +61 -0
- package/dist/src/node-network.test.d.ts +1 -0
- package/dist/src/output.d.ts +14 -0
- package/dist/src/output.js +147 -0
- package/dist/src/output.test.d.ts +1 -0
- package/dist/src/output.test.js +62 -0
- package/dist/src/pipeline/executor.test.js +173 -0
- package/dist/src/pipeline/index.d.ts +5 -0
- package/dist/src/pipeline/index.js +5 -0
- package/dist/src/pipeline/steps/download.test.d.ts +1 -0
- package/dist/src/pipeline/steps/download.test.js +100 -0
- package/dist/src/pipeline/steps/fetch.test.d.ts +1 -0
- package/dist/src/record.js +694 -0
- package/dist/src/record.test.d.ts +1 -0
- package/dist/src/registry.d.ts +81 -0
- package/dist/src/runtime-detect.test.d.ts +1 -0
- package/dist/src/serialization.d.ts +38 -0
- package/dist/src/serialization.js +78 -0
- package/dist/src/serialization.test.d.ts +1 -0
- package/dist/src/synthesize.d.ts +99 -0
- package/dist/src/synthesize.js +205 -0
- package/dist/src/tui.test.d.ts +1 -0
- package/dist/src/types.d.ts +98 -0
- package/dist/src/weixin-download.test.d.ts +1 -0
- package/dist/src/weixin-download.test.js +44 -0
- package/package.json +28 -10
- package/scripts/check-doc-coverage.sh +2 -2
- package/scripts/copy-yaml.cjs +4 -4
- package/scripts/fetch-adapters.js +157 -0
- package/scripts/postinstall.js +1 -1
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -83
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -42
- package/.github/ISSUE_TEMPLATE/new_site_adapter.yml +0 -57
- package/.github/actions/setup-chrome/action.yml +0 -27
- package/.github/dependabot.yml +0 -27
- package/.github/pull_request_template.md +0 -33
- package/.github/workflows/build-extension.yml +0 -67
- package/.github/workflows/ci.yml +0 -147
- package/.github/workflows/doc-check.yml +0 -36
- package/.github/workflows/docs.yml +0 -17
- package/.github/workflows/e2e-headed.yml +0 -74
- package/.github/workflows/release.yml +0 -44
- package/.github/workflows/security.yml +0 -33
- package/CHANGELOG.md +0 -321
- package/CLI-EXPLORER.md +0 -724
- package/CLI-ONESHOT.md +0 -216
- package/CONTRIBUTING.md +0 -208
- package/PRIVACY.md +0 -57
- package/SKILL.md +0 -59
- package/TESTING.md +0 -252
- package/autoresearch/baseline-browse.txt +0 -1
- package/autoresearch/baseline-skill.txt +0 -1
- package/autoresearch/browse-tasks.json +0 -688
- package/autoresearch/eval-browse.ts +0 -185
- package/autoresearch/eval-skill.ts +0 -248
- package/autoresearch/run-browse.sh +0 -9
- package/autoresearch/run-skill.sh +0 -9
- package/bun.lock +0 -615
- package/dist/browser/base-page.d.ts +0 -48
- package/dist/browser/base-page.js +0 -160
- package/dist/browser/bridge.js +0 -107
- package/dist/browser/daemon-client.d.ts +0 -64
- package/dist/browser/daemon-client.js +0 -110
- package/dist/browser/dom-helpers.d.ts +0 -39
- package/dist/browser/dom-helpers.js +0 -216
- package/dist/browser/dom-snapshot.js +0 -782
- package/dist/browser.test.js +0 -159
- package/dist/build-manifest.d.ts +0 -46
- package/dist/build-manifest.js +0 -224
- package/dist/cascade.js +0 -149
- package/dist/cli.d.ts +0 -7
- package/dist/cli.js +0 -912
- package/dist/commanderAdapter.d.ts +0 -22
- package/dist/commanderAdapter.js +0 -297
- package/dist/commanderAdapter.test.js +0 -202
- package/dist/completion.js +0 -118
- package/dist/discovery.d.ts +0 -31
- package/dist/discovery.js +0 -330
- package/dist/doctor.js +0 -126
- package/dist/electron-apps.d.ts +0 -29
- package/dist/electron-apps.js +0 -65
- package/dist/errors.js +0 -119
- package/dist/execution.js +0 -219
- package/dist/explore.js +0 -379
- package/dist/interceptor.d.ts +0 -42
- package/dist/interceptor.js +0 -186
- package/dist/launcher.d.ts +0 -36
- package/dist/launcher.js +0 -152
- package/dist/launcher.test.js +0 -57
- package/dist/main.js +0 -60
- package/dist/output.d.ts +0 -12
- package/dist/output.js +0 -138
- package/dist/output.test.d.ts +0 -4
- package/dist/output.test.js +0 -95
- package/dist/pipeline/executor.test.js +0 -175
- package/dist/pipeline/steps/download.test.js +0 -102
- package/dist/record.js +0 -694
- package/dist/registry.d.ts +0 -79
- package/dist/serialization.d.ts +0 -37
- package/dist/serialization.js +0 -77
- package/dist/synthesize.d.ts +0 -103
- package/dist/synthesize.js +0 -216
- package/dist/types.d.ts +0 -91
- package/dist/weixin-download.test.js +0 -44
- package/docs/.vitepress/config.mts +0 -234
- package/docs/adapters/browser/36kr.md +0 -47
- package/docs/adapters/browser/amazon.md +0 -53
- package/docs/adapters/browser/apple-podcasts.md +0 -28
- package/docs/adapters/browser/arxiv.md +0 -27
- package/docs/adapters/browser/band.md +0 -63
- package/docs/adapters/browser/barchart.md +0 -33
- package/docs/adapters/browser/bbc.md +0 -26
- package/docs/adapters/browser/bilibili.md +0 -47
- package/docs/adapters/browser/bloomberg.md +0 -70
- package/docs/adapters/browser/bluesky.md +0 -53
- package/docs/adapters/browser/boss.md +0 -28
- package/docs/adapters/browser/chaoxing.md +0 -39
- package/docs/adapters/browser/coupang.md +0 -28
- package/docs/adapters/browser/ctrip.md +0 -27
- package/docs/adapters/browser/devto.md +0 -35
- package/docs/adapters/browser/dictionary.md +0 -27
- package/docs/adapters/browser/douban.md +0 -62
- package/docs/adapters/browser/doubao.md +0 -35
- package/docs/adapters/browser/douyin.md +0 -75
- package/docs/adapters/browser/facebook.md +0 -36
- package/docs/adapters/browser/gemini.md +0 -72
- package/docs/adapters/browser/google.md +0 -62
- package/docs/adapters/browser/grok.md +0 -53
- package/docs/adapters/browser/hackernews.md +0 -42
- package/docs/adapters/browser/hf.md +0 -42
- package/docs/adapters/browser/imdb.md +0 -47
- package/docs/adapters/browser/instagram.md +0 -46
- package/docs/adapters/browser/jd.md +0 -27
- package/docs/adapters/browser/jike.md +0 -45
- package/docs/adapters/browser/jimeng.md +0 -39
- package/docs/adapters/browser/linkedin.md +0 -33
- package/docs/adapters/browser/linux-do.md +0 -206
- package/docs/adapters/browser/lobsters.md +0 -32
- package/docs/adapters/browser/medium.md +0 -32
- package/docs/adapters/browser/notebooklm.md +0 -69
- package/docs/adapters/browser/ones.md +0 -59
- package/docs/adapters/browser/paperreview.md +0 -43
- package/docs/adapters/browser/pixiv.md +0 -92
- package/docs/adapters/browser/producthunt.md +0 -49
- package/docs/adapters/browser/reddit.md +0 -50
- package/docs/adapters/browser/reuters.md +0 -27
- package/docs/adapters/browser/sinablog.md +0 -36
- package/docs/adapters/browser/sinafinance.md +0 -85
- package/docs/adapters/browser/smzdm.md +0 -27
- package/docs/adapters/browser/spotify.md +0 -62
- package/docs/adapters/browser/stackoverflow.md +0 -35
- package/docs/adapters/browser/steam.md +0 -26
- package/docs/adapters/browser/substack.md +0 -38
- package/docs/adapters/browser/tieba.md +0 -45
- package/docs/adapters/browser/tiktok.md +0 -68
- package/docs/adapters/browser/twitter.md +0 -56
- package/docs/adapters/browser/v2ex.md +0 -53
- package/docs/adapters/browser/web.md +0 -30
- package/docs/adapters/browser/weibo.md +0 -31
- package/docs/adapters/browser/weixin.md +0 -33
- package/docs/adapters/browser/weread.md +0 -48
- package/docs/adapters/browser/wikipedia.md +0 -30
- package/docs/adapters/browser/xiaohongshu.md +0 -47
- package/docs/adapters/browser/xiaoyuzhou.md +0 -28
- package/docs/adapters/browser/xueqiu.md +0 -65
- package/docs/adapters/browser/yahoo-finance.md +0 -27
- package/docs/adapters/browser/yollomi.md +0 -69
- package/docs/adapters/browser/youtube.md +0 -29
- package/docs/adapters/browser/zhihu.md +0 -30
- package/docs/adapters/browser/zsxq.md +0 -49
- package/docs/adapters/desktop/antigravity.md +0 -49
- package/docs/adapters/desktop/chatgpt.md +0 -49
- package/docs/adapters/desktop/chatwise.md +0 -38
- package/docs/adapters/desktop/codex.md +0 -36
- package/docs/adapters/desktop/cursor.md +0 -37
- package/docs/adapters/desktop/discord.md +0 -28
- package/docs/adapters/desktop/doubao-app.md +0 -35
- package/docs/adapters/desktop/notion.md +0 -29
- package/docs/adapters/index.md +0 -87
- package/docs/adapters-doc/ones.md +0 -32
- package/docs/advanced/cdp.md +0 -103
- package/docs/advanced/download.md +0 -71
- package/docs/advanced/electron.md +0 -125
- package/docs/advanced/rate-limiter-plugin.md +0 -99
- package/docs/advanced/remote-chrome.md +0 -72
- package/docs/comparison.md +0 -125
- package/docs/developer/ai-workflow.md +0 -66
- package/docs/developer/architecture.md +0 -103
- package/docs/developer/contributing.md +0 -155
- package/docs/developer/testing.md +0 -261
- package/docs/developer/ts-adapter.md +0 -105
- package/docs/developer/yaml-adapter.md +0 -124
- package/docs/guide/browser-bridge.md +0 -49
- package/docs/guide/electron-app-cli.md +0 -200
- package/docs/guide/getting-started.md +0 -79
- package/docs/guide/installation.md +0 -37
- package/docs/guide/plugins.md +0 -260
- package/docs/guide/troubleshooting.md +0 -61
- package/docs/index.md +0 -35
- package/docs/superpowers/plans/2026-03-28-perf-smart-wait.md +0 -1143
- package/docs/superpowers/plans/2026-03-31-daemon-lifecycle-redesign.md +0 -857
- package/docs/superpowers/specs/2026-03-28-perf-smart-wait-design.md +0 -170
- package/docs/superpowers/specs/2026-03-31-daemon-lifecycle-redesign.md +0 -208
- package/docs/superpowers/specs/2026-04-02-browse-skill-testing-design.md +0 -144
- package/docs/zh/adapters/index.md +0 -5
- package/docs/zh/advanced/cdp.md +0 -3
- package/docs/zh/developer/contributing.md +0 -24
- package/docs/zh/guide/browser-bridge.md +0 -36
- package/docs/zh/guide/electron-app-cli.md +0 -188
- package/docs/zh/guide/getting-started.md +0 -62
- package/docs/zh/guide/installation.md +0 -37
- package/docs/zh/guide/plugins.md +0 -182
- package/docs/zh/index.md +0 -29
- package/extension/icons/icon-128.png +0 -0
- package/extension/icons/icon-16.png +0 -0
- package/extension/icons/icon-32.png +0 -0
- package/extension/icons/icon-48.png +0 -0
- package/extension/manifest.json +0 -39
- package/extension/package-lock.json +0 -1156
- package/extension/package.json +0 -17
- package/extension/popup.html +0 -84
- package/extension/popup.js +0 -25
- package/extension/scripts/package-release.mjs +0 -179
- package/extension/src/background.test.ts +0 -240
- package/extension/src/background.ts +0 -689
- package/extension/src/cdp.test.ts +0 -75
- package/extension/src/cdp.ts +0 -250
- package/extension/src/protocol.ts +0 -66
- package/extension/store-assets/screenshot-1280x800.png +0 -0
- package/extension/tsconfig.json +0 -15
- package/extension/vite.config.ts +0 -18
- package/skills/opencli-explorer/SKILL.md +0 -853
- package/skills/opencli-oneshot/SKILL.md +0 -222
- package/skills/opencli-operate/SKILL.md +0 -213
- package/skills/opencli-usage/SKILL.md +0 -152
- package/skills/opencli-usage/browser.md +0 -429
- package/skills/opencli-usage/desktop.md +0 -118
- package/skills/opencli-usage/plugins.md +0 -82
- package/skills/opencli-usage/public-api.md +0 -149
- package/src/analysis.ts +0 -170
- package/src/browser/base-page.ts +0 -197
- package/src/browser/bridge.ts +0 -126
- package/src/browser/cdp.test.ts +0 -66
- package/src/browser/cdp.ts +0 -348
- package/src/browser/daemon-client.test.ts +0 -103
- package/src/browser/daemon-client.ts +0 -165
- package/src/browser/discover.ts +0 -26
- package/src/browser/dom-helpers.test.ts +0 -114
- package/src/browser/dom-helpers.ts +0 -226
- package/src/browser/dom-snapshot.test.ts +0 -291
- package/src/browser/dom-snapshot.ts +0 -823
- package/src/browser/errors.ts +0 -63
- package/src/browser/index.ts +0 -14
- package/src/browser/page.test.ts +0 -58
- package/src/browser/page.ts +0 -231
- package/src/browser/stealth.test.ts +0 -153
- package/src/browser/stealth.ts +0 -354
- package/src/browser/tabs.ts +0 -76
- package/src/browser/utils.ts +0 -27
- package/src/browser.test.ts +0 -195
- package/src/build-manifest.test.ts +0 -200
- package/src/build-manifest.ts +0 -277
- package/src/capabilityRouting.test.ts +0 -47
- package/src/capabilityRouting.ts +0 -29
- package/src/cascade.ts +0 -192
- package/src/cli.ts +0 -950
- package/src/clis/36kr/article.ts +0 -69
- package/src/clis/36kr/hot.test.ts +0 -19
- package/src/clis/36kr/hot.ts +0 -100
- package/src/clis/36kr/news.test.ts +0 -90
- package/src/clis/36kr/news.ts +0 -54
- package/src/clis/36kr/search.ts +0 -78
- package/src/clis/_shared/common.ts +0 -11
- package/src/clis/_shared/desktop-commands.ts +0 -121
- package/src/clis/amazon/bestsellers.test.ts +0 -22
- package/src/clis/amazon/bestsellers.ts +0 -180
- package/src/clis/amazon/discussion.test.ts +0 -38
- package/src/clis/amazon/discussion.ts +0 -131
- package/src/clis/amazon/offer.test.ts +0 -35
- package/src/clis/amazon/offer.ts +0 -185
- package/src/clis/amazon/product.test.ts +0 -26
- package/src/clis/amazon/product.ts +0 -131
- package/src/clis/amazon/search.test.ts +0 -24
- package/src/clis/amazon/search.ts +0 -128
- package/src/clis/amazon/shared.test.ts +0 -37
- package/src/clis/amazon/shared.ts +0 -316
- package/src/clis/antigravity/SKILL.md +0 -38
- package/src/clis/antigravity/dump.ts +0 -30
- package/src/clis/antigravity/extract-code.ts +0 -34
- package/src/clis/antigravity/model.ts +0 -47
- package/src/clis/antigravity/new.ts +0 -28
- package/src/clis/antigravity/read.ts +0 -36
- package/src/clis/antigravity/send.ts +0 -40
- package/src/clis/antigravity/serve.ts +0 -600
- package/src/clis/antigravity/status.ts +0 -19
- package/src/clis/antigravity/watch.ts +0 -45
- package/src/clis/apple-podcasts/commands.test.ts +0 -123
- package/src/clis/apple-podcasts/episodes.ts +0 -28
- package/src/clis/apple-podcasts/search.ts +0 -30
- package/src/clis/apple-podcasts/top.ts +0 -47
- package/src/clis/apple-podcasts/utils.test.ts +0 -72
- package/src/clis/apple-podcasts/utils.ts +0 -37
- package/src/clis/arxiv/paper.ts +0 -21
- package/src/clis/arxiv/search.ts +0 -24
- package/src/clis/arxiv/utils.ts +0 -63
- package/src/clis/band/bands.ts +0 -76
- package/src/clis/band/mentions.ts +0 -134
- package/src/clis/band/post.ts +0 -187
- package/src/clis/band/posts.ts +0 -106
- package/src/clis/barchart/flow.ts +0 -120
- package/src/clis/barchart/greeks.ts +0 -123
- package/src/clis/barchart/options.ts +0 -110
- package/src/clis/barchart/quote.ts +0 -137
- package/src/clis/bbc/news.ts +0 -41
- package/src/clis/bilibili/comments.test.ts +0 -102
- package/src/clis/bilibili/comments.ts +0 -44
- package/src/clis/bilibili/download.ts +0 -92
- package/src/clis/bilibili/dynamic.test.ts +0 -79
- package/src/clis/bilibili/dynamic.ts +0 -34
- package/src/clis/bilibili/favorite.ts +0 -45
- package/src/clis/bilibili/feed.ts +0 -71
- package/src/clis/bilibili/following.ts +0 -51
- package/src/clis/bilibili/history.ts +0 -48
- package/src/clis/bilibili/hot.yaml +0 -38
- package/src/clis/bilibili/me.ts +0 -14
- package/src/clis/bilibili/ranking.ts +0 -25
- package/src/clis/bilibili/search.ts +0 -25
- package/src/clis/bilibili/subtitle.test.ts +0 -60
- package/src/clis/bilibili/subtitle.ts +0 -105
- package/src/clis/bilibili/user-videos.ts +0 -42
- package/src/clis/bilibili/utils.ts +0 -116
- package/src/clis/bloomberg/businessweek.ts +0 -18
- package/src/clis/bloomberg/economics.ts +0 -18
- package/src/clis/bloomberg/feeds.ts +0 -16
- package/src/clis/bloomberg/industries.ts +0 -18
- package/src/clis/bloomberg/main.ts +0 -18
- package/src/clis/bloomberg/markets.ts +0 -18
- package/src/clis/bloomberg/news.ts +0 -136
- package/src/clis/bloomberg/opinions.ts +0 -18
- package/src/clis/bloomberg/politics.ts +0 -18
- package/src/clis/bloomberg/tech.ts +0 -18
- package/src/clis/bloomberg/utils.test.ts +0 -135
- package/src/clis/bloomberg/utils.ts +0 -429
- package/src/clis/bluesky/feeds.yaml +0 -29
- package/src/clis/bluesky/followers.yaml +0 -33
- package/src/clis/bluesky/following.yaml +0 -33
- package/src/clis/bluesky/profile.yaml +0 -27
- package/src/clis/bluesky/search.yaml +0 -34
- package/src/clis/bluesky/starter-packs.yaml +0 -34
- package/src/clis/bluesky/thread.yaml +0 -32
- package/src/clis/bluesky/trending.yaml +0 -27
- package/src/clis/bluesky/user.yaml +0 -34
- package/src/clis/boss/batchgreet.ts +0 -75
- package/src/clis/boss/chatlist.ts +0 -36
- package/src/clis/boss/chatmsg.ts +0 -46
- package/src/clis/boss/detail.ts +0 -69
- package/src/clis/boss/exchange.ts +0 -52
- package/src/clis/boss/greet.ts +0 -61
- package/src/clis/boss/invite.ts +0 -80
- package/src/clis/boss/joblist.ts +0 -34
- package/src/clis/boss/mark.ts +0 -75
- package/src/clis/boss/recommend.ts +0 -49
- package/src/clis/boss/resume.ts +0 -157
- package/src/clis/boss/search.ts +0 -162
- package/src/clis/boss/send.ts +0 -54
- package/src/clis/boss/stats.ts +0 -75
- package/src/clis/boss/utils.ts +0 -287
- package/src/clis/chaoxing/assignments.ts +0 -89
- package/src/clis/chaoxing/exams.ts +0 -88
- package/src/clis/chaoxing/utils.test.ts +0 -53
- package/src/clis/chaoxing/utils.ts +0 -266
- package/src/clis/chatgpt/ask.ts +0 -95
- package/src/clis/chatgpt/ax.ts +0 -260
- package/src/clis/chatgpt/model.ts +0 -27
- package/src/clis/chatgpt/new.ts +0 -29
- package/src/clis/chatgpt/read.ts +0 -35
- package/src/clis/chatgpt/send.ts +0 -59
- package/src/clis/chatgpt/status.ts +0 -27
- package/src/clis/chatwise/ask.ts +0 -90
- package/src/clis/chatwise/export.ts +0 -51
- package/src/clis/chatwise/history.ts +0 -61
- package/src/clis/chatwise/model.ts +0 -89
- package/src/clis/chatwise/new.ts +0 -3
- package/src/clis/chatwise/read.ts +0 -42
- package/src/clis/chatwise/screenshot.ts +0 -3
- package/src/clis/chatwise/send.ts +0 -53
- package/src/clis/chatwise/status.ts +0 -3
- package/src/clis/codex/ask.ts +0 -80
- package/src/clis/codex/dump.ts +0 -3
- package/src/clis/codex/export.ts +0 -42
- package/src/clis/codex/extract-diff.ts +0 -48
- package/src/clis/codex/history.ts +0 -47
- package/src/clis/codex/model.ts +0 -59
- package/src/clis/codex/new.ts +0 -3
- package/src/clis/codex/read.ts +0 -37
- package/src/clis/codex/screenshot.ts +0 -3
- package/src/clis/codex/send.ts +0 -48
- package/src/clis/codex/status.ts +0 -3
- package/src/clis/coupang/add-to-cart.ts +0 -148
- package/src/clis/coupang/search.ts +0 -464
- package/src/clis/coupang/utils.test.ts +0 -78
- package/src/clis/coupang/utils.ts +0 -302
- package/src/clis/ctrip/search.test.ts +0 -73
- package/src/clis/ctrip/search.ts +0 -111
- package/src/clis/cursor/ask.ts +0 -82
- package/src/clis/cursor/composer.ts +0 -51
- package/src/clis/cursor/dump.ts +0 -3
- package/src/clis/cursor/export.ts +0 -57
- package/src/clis/cursor/extract-code.ts +0 -39
- package/src/clis/cursor/history.ts +0 -47
- package/src/clis/cursor/model.ts +0 -57
- package/src/clis/cursor/new.ts +0 -3
- package/src/clis/cursor/read.ts +0 -48
- package/src/clis/cursor/screenshot.ts +0 -3
- package/src/clis/cursor/send.ts +0 -48
- package/src/clis/cursor/status.ts +0 -3
- package/src/clis/devto/tag.yaml +0 -34
- package/src/clis/devto/top.yaml +0 -29
- package/src/clis/devto/user.yaml +0 -33
- package/src/clis/dictionary/examples.yaml +0 -25
- package/src/clis/dictionary/search.yaml +0 -27
- package/src/clis/dictionary/synonyms.yaml +0 -25
- package/src/clis/discord-app/channels.ts +0 -60
- package/src/clis/discord-app/members.ts +0 -41
- package/src/clis/discord-app/read.ts +0 -49
- package/src/clis/discord-app/search.ts +0 -64
- package/src/clis/discord-app/send.ts +0 -32
- package/src/clis/discord-app/servers.ts +0 -39
- package/src/clis/discord-app/status.ts +0 -18
- package/src/clis/douban/book-hot.ts +0 -15
- package/src/clis/douban/download.test.ts +0 -196
- package/src/clis/douban/download.ts +0 -78
- package/src/clis/douban/marks.ts +0 -135
- package/src/clis/douban/movie-hot.ts +0 -15
- package/src/clis/douban/photos.ts +0 -36
- package/src/clis/douban/reviews.ts +0 -127
- package/src/clis/douban/search.ts +0 -17
- package/src/clis/douban/subject.yaml +0 -76
- package/src/clis/douban/top250.yaml +0 -70
- package/src/clis/douban/utils.test.ts +0 -97
- package/src/clis/douban/utils.ts +0 -472
- package/src/clis/doubao/ask.ts +0 -40
- package/src/clis/doubao/detail.test.ts +0 -53
- package/src/clis/doubao/detail.ts +0 -41
- package/src/clis/doubao/history.test.ts +0 -45
- package/src/clis/doubao/history.ts +0 -32
- package/src/clis/doubao/meeting-summary.ts +0 -53
- package/src/clis/doubao/meeting-transcript.ts +0 -48
- package/src/clis/doubao/new.ts +0 -22
- package/src/clis/doubao/read.ts +0 -20
- package/src/clis/doubao/send.ts +0 -25
- package/src/clis/doubao/status.ts +0 -27
- package/src/clis/doubao/utils.test.ts +0 -45
- package/src/clis/doubao/utils.ts +0 -990
- package/src/clis/doubao-app/ask.ts +0 -60
- package/src/clis/doubao-app/dump.ts +0 -28
- package/src/clis/doubao-app/new.ts +0 -21
- package/src/clis/doubao-app/read.ts +0 -21
- package/src/clis/doubao-app/screenshot.ts +0 -19
- package/src/clis/doubao-app/send.ts +0 -30
- package/src/clis/doubao-app/status.ts +0 -17
- package/src/clis/doubao-app/utils.ts +0 -116
- package/src/clis/douyin/_shared/browser-fetch.test.ts +0 -38
- package/src/clis/douyin/_shared/browser-fetch.ts +0 -45
- package/src/clis/douyin/_shared/creation-id.test.ts +0 -26
- package/src/clis/douyin/_shared/creation-id.ts +0 -8
- package/src/clis/douyin/_shared/imagex-upload.test.ts +0 -113
- package/src/clis/douyin/_shared/imagex-upload.ts +0 -76
- package/src/clis/douyin/_shared/public-api.ts +0 -84
- package/src/clis/douyin/_shared/sts2.test.ts +0 -31
- package/src/clis/douyin/_shared/sts2.ts +0 -28
- package/src/clis/douyin/_shared/text-extra.test.ts +0 -42
- package/src/clis/douyin/_shared/text-extra.ts +0 -33
- package/src/clis/douyin/_shared/timing.test.ts +0 -38
- package/src/clis/douyin/_shared/timing.ts +0 -22
- package/src/clis/douyin/_shared/tos-upload-short-read.test.ts +0 -102
- package/src/clis/douyin/_shared/tos-upload.test.ts +0 -281
- package/src/clis/douyin/_shared/tos-upload.ts +0 -444
- package/src/clis/douyin/_shared/transcode.test.ts +0 -117
- package/src/clis/douyin/_shared/transcode.ts +0 -78
- package/src/clis/douyin/_shared/types.ts +0 -29
- package/src/clis/douyin/activities.test.ts +0 -65
- package/src/clis/douyin/activities.ts +0 -32
- package/src/clis/douyin/collections.test.ts +0 -59
- package/src/clis/douyin/collections.ts +0 -25
- package/src/clis/douyin/delete.test.ts +0 -12
- package/src/clis/douyin/delete.ts +0 -20
- package/src/clis/douyin/draft.test.ts +0 -454
- package/src/clis/douyin/draft.ts +0 -446
- package/src/clis/douyin/drafts.test.ts +0 -12
- package/src/clis/douyin/drafts.ts +0 -27
- package/src/clis/douyin/hashtag.test.ts +0 -68
- package/src/clis/douyin/hashtag.ts +0 -64
- package/src/clis/douyin/location.test.ts +0 -26
- package/src/clis/douyin/location.ts +0 -27
- package/src/clis/douyin/profile.test.ts +0 -54
- package/src/clis/douyin/profile.ts +0 -44
- package/src/clis/douyin/publish.test.ts +0 -45
- package/src/clis/douyin/publish.ts +0 -340
- package/src/clis/douyin/stats.test.ts +0 -25
- package/src/clis/douyin/stats.ts +0 -30
- package/src/clis/douyin/update.test.ts +0 -12
- package/src/clis/douyin/update.ts +0 -43
- package/src/clis/douyin/user-videos.test.ts +0 -122
- package/src/clis/douyin/user-videos.ts +0 -101
- package/src/clis/douyin/videos.test.ts +0 -62
- package/src/clis/douyin/videos.ts +0 -83
- package/src/clis/facebook/add-friend.yaml +0 -43
- package/src/clis/facebook/events.yaml +0 -44
- package/src/clis/facebook/feed.yaml +0 -63
- package/src/clis/facebook/friends.yaml +0 -42
- package/src/clis/facebook/groups.yaml +0 -50
- package/src/clis/facebook/join-group.yaml +0 -44
- package/src/clis/facebook/memories.yaml +0 -39
- package/src/clis/facebook/notifications.yaml +0 -40
- package/src/clis/facebook/profile.yaml +0 -37
- package/src/clis/facebook/search.test.ts +0 -70
- package/src/clis/facebook/search.yaml +0 -47
- package/src/clis/gemini/ask.ts +0 -46
- package/src/clis/gemini/image.ts +0 -115
- package/src/clis/gemini/new.ts +0 -22
- package/src/clis/gemini/utils.test.ts +0 -36
- package/src/clis/gemini/utils.ts +0 -523
- package/src/clis/google/news.ts +0 -66
- package/src/clis/google/search.ts +0 -133
- package/src/clis/google/suggest.ts +0 -40
- package/src/clis/google/trends.ts +0 -44
- package/src/clis/google/utils.test.ts +0 -82
- package/src/clis/google/utils.ts +0 -24
- package/src/clis/grok/ask.test.ts +0 -78
- package/src/clis/grok/ask.ts +0 -334
- package/src/clis/hackernews/ask.yaml +0 -38
- package/src/clis/hackernews/best.yaml +0 -38
- package/src/clis/hackernews/jobs.yaml +0 -36
- package/src/clis/hackernews/new.yaml +0 -38
- package/src/clis/hackernews/search.yaml +0 -44
- package/src/clis/hackernews/show.yaml +0 -38
- package/src/clis/hackernews/top.yaml +0 -38
- package/src/clis/hackernews/user.yaml +0 -25
- package/src/clis/hf/top.ts +0 -141
- package/src/clis/imdb/person.ts +0 -232
- package/src/clis/imdb/reviews.ts +0 -111
- package/src/clis/imdb/search.ts +0 -179
- package/src/clis/imdb/title.ts +0 -121
- package/src/clis/imdb/top.ts +0 -67
- package/src/clis/imdb/trending.ts +0 -66
- package/src/clis/imdb/utils.test.ts +0 -117
- package/src/clis/imdb/utils.ts +0 -305
- package/src/clis/instagram/comment.yaml +0 -52
- package/src/clis/instagram/download.test.ts +0 -159
- package/src/clis/instagram/download.ts +0 -286
- package/src/clis/instagram/explore.yaml +0 -43
- package/src/clis/instagram/follow.yaml +0 -41
- package/src/clis/instagram/followers.yaml +0 -51
- package/src/clis/instagram/following.yaml +0 -51
- package/src/clis/instagram/like.yaml +0 -46
- package/src/clis/instagram/profile.yaml +0 -42
- package/src/clis/instagram/save.yaml +0 -46
- package/src/clis/instagram/saved.yaml +0 -40
- package/src/clis/instagram/search.yaml +0 -44
- package/src/clis/instagram/unfollow.yaml +0 -38
- package/src/clis/instagram/unlike.yaml +0 -46
- package/src/clis/instagram/unsave.yaml +0 -46
- package/src/clis/instagram/user.yaml +0 -54
- package/src/clis/jd/item.test.ts +0 -52
- package/src/clis/jd/item.ts +0 -104
- package/src/clis/jike/comment.ts +0 -112
- package/src/clis/jike/create.ts +0 -112
- package/src/clis/jike/feed.ts +0 -73
- package/src/clis/jike/like.ts +0 -64
- package/src/clis/jike/notifications.ts +0 -184
- package/src/clis/jike/post.yaml +0 -59
- package/src/clis/jike/repost.ts +0 -113
- package/src/clis/jike/search.ts +0 -73
- package/src/clis/jike/topic.yaml +0 -53
- package/src/clis/jike/user.yaml +0 -52
- package/src/clis/jike/utils.ts +0 -36
- package/src/clis/jimeng/generate.yaml +0 -85
- package/src/clis/jimeng/history.yaml +0 -46
- package/src/clis/linkedin/search.ts +0 -417
- package/src/clis/linkedin/timeline.test.ts +0 -99
- package/src/clis/linkedin/timeline.ts +0 -532
- package/src/clis/linux-do/categories.yaml +0 -70
- package/src/clis/linux-do/category.ts +0 -37
- package/src/clis/linux-do/feed.test.ts +0 -132
- package/src/clis/linux-do/feed.ts +0 -501
- package/src/clis/linux-do/hot.ts +0 -26
- package/src/clis/linux-do/latest.ts +0 -19
- package/src/clis/linux-do/search.yaml +0 -48
- package/src/clis/linux-do/tags.yaml +0 -41
- package/src/clis/linux-do/topic.yaml +0 -77
- package/src/clis/linux-do/user-posts.yaml +0 -67
- package/src/clis/linux-do/user-topics.yaml +0 -54
- package/src/clis/lobsters/active.yaml +0 -29
- package/src/clis/lobsters/hot.yaml +0 -29
- package/src/clis/lobsters/newest.yaml +0 -29
- package/src/clis/lobsters/tag.yaml +0 -34
- package/src/clis/medium/feed.ts +0 -16
- package/src/clis/medium/search.ts +0 -16
- package/src/clis/medium/user.ts +0 -16
- package/src/clis/medium/utils.ts +0 -84
- package/src/clis/notebooklm/compat.test.ts +0 -19
- package/src/clis/notebooklm/current.ts +0 -37
- package/src/clis/notebooklm/get.ts +0 -51
- package/src/clis/notebooklm/history.test.ts +0 -70
- package/src/clis/notebooklm/history.ts +0 -34
- package/src/clis/notebooklm/list.ts +0 -40
- package/src/clis/notebooklm/note-list.test.ts +0 -64
- package/src/clis/notebooklm/note-list.ts +0 -40
- package/src/clis/notebooklm/notes-get.test.ts +0 -88
- package/src/clis/notebooklm/notes-get.ts +0 -65
- package/src/clis/notebooklm/open.test.ts +0 -78
- package/src/clis/notebooklm/open.ts +0 -61
- package/src/clis/notebooklm/rpc.test.ts +0 -126
- package/src/clis/notebooklm/rpc.ts +0 -286
- package/src/clis/notebooklm/shared.ts +0 -98
- package/src/clis/notebooklm/source-fulltext.test.ts +0 -123
- package/src/clis/notebooklm/source-fulltext.ts +0 -67
- package/src/clis/notebooklm/source-get.test.ts +0 -100
- package/src/clis/notebooklm/source-get.ts +0 -58
- package/src/clis/notebooklm/source-guide.test.ts +0 -121
- package/src/clis/notebooklm/source-guide.ts +0 -67
- package/src/clis/notebooklm/source-list.ts +0 -43
- package/src/clis/notebooklm/status.ts +0 -33
- package/src/clis/notebooklm/summary.test.ts +0 -94
- package/src/clis/notebooklm/summary.ts +0 -43
- package/src/clis/notebooklm/utils.test.ts +0 -446
- package/src/clis/notebooklm/utils.ts +0 -902
- package/src/clis/notion/export.ts +0 -36
- package/src/clis/notion/favorites.ts +0 -87
- package/src/clis/notion/new.ts +0 -39
- package/src/clis/notion/read.ts +0 -33
- package/src/clis/notion/search.ts +0 -54
- package/src/clis/notion/sidebar.ts +0 -44
- package/src/clis/notion/status.ts +0 -18
- package/src/clis/notion/write.ts +0 -45
- package/src/clis/ones/common.ts +0 -187
- package/src/clis/ones/enrich-tasks.ts +0 -47
- package/src/clis/ones/login.ts +0 -103
- package/src/clis/ones/logout.ts +0 -19
- package/src/clis/ones/me.ts +0 -34
- package/src/clis/ones/my-tasks.ts +0 -148
- package/src/clis/ones/resolve-labels.ts +0 -80
- package/src/clis/ones/task-helpers.test.ts +0 -14
- package/src/clis/ones/task-helpers.ts +0 -214
- package/src/clis/ones/task.ts +0 -79
- package/src/clis/ones/tasks.ts +0 -92
- package/src/clis/ones/token-info.ts +0 -46
- package/src/clis/ones/worklog.test.ts +0 -24
- package/src/clis/ones/worklog.ts +0 -306
- package/src/clis/paperreview/commands.test.ts +0 -283
- package/src/clis/paperreview/feedback.ts +0 -64
- package/src/clis/paperreview/review.ts +0 -47
- package/src/clis/paperreview/submit.ts +0 -119
- package/src/clis/paperreview/utils.test.ts +0 -68
- package/src/clis/paperreview/utils.ts +0 -276
- package/src/clis/pixiv/detail.yaml +0 -49
- package/src/clis/pixiv/download.test.ts +0 -114
- package/src/clis/pixiv/download.ts +0 -91
- package/src/clis/pixiv/illusts.test.ts +0 -115
- package/src/clis/pixiv/illusts.ts +0 -78
- package/src/clis/pixiv/ranking.yaml +0 -53
- package/src/clis/pixiv/search.test.ts +0 -97
- package/src/clis/pixiv/search.ts +0 -53
- package/src/clis/pixiv/test-utils.ts +0 -29
- package/src/clis/pixiv/user.yaml +0 -46
- package/src/clis/pixiv/utils.ts +0 -62
- package/src/clis/producthunt/browse.ts +0 -109
- package/src/clis/producthunt/hot.ts +0 -127
- package/src/clis/producthunt/posts.ts +0 -29
- package/src/clis/producthunt/today.ts +0 -37
- package/src/clis/producthunt/utils.test.ts +0 -72
- package/src/clis/producthunt/utils.ts +0 -122
- package/src/clis/reddit/comment.ts +0 -60
- package/src/clis/reddit/frontpage.yaml +0 -30
- package/src/clis/reddit/hot.yaml +0 -47
- package/src/clis/reddit/popular.yaml +0 -40
- package/src/clis/reddit/read.test.ts +0 -34
- package/src/clis/reddit/read.ts +0 -186
- package/src/clis/reddit/save.ts +0 -54
- package/src/clis/reddit/saved.ts +0 -51
- package/src/clis/reddit/search.yaml +0 -61
- package/src/clis/reddit/subreddit.yaml +0 -50
- package/src/clis/reddit/subscribe.ts +0 -53
- package/src/clis/reddit/upvote.ts +0 -67
- package/src/clis/reddit/upvoted.ts +0 -51
- package/src/clis/reddit/user-comments.yaml +0 -46
- package/src/clis/reddit/user-posts.yaml +0 -44
- package/src/clis/reddit/user.yaml +0 -40
- package/src/clis/reuters/search.ts +0 -51
- package/src/clis/sinablog/article.ts +0 -15
- package/src/clis/sinablog/hot.ts +0 -15
- package/src/clis/sinablog/search.ts +0 -56
- package/src/clis/sinablog/user.ts +0 -16
- package/src/clis/sinablog/utils.ts +0 -197
- package/src/clis/sinafinance/news.ts +0 -76
- package/src/clis/sinafinance/rolling-news.ts +0 -42
- package/src/clis/sinafinance/stock.ts +0 -127
- package/src/clis/smzdm/search.ts +0 -56
- package/src/clis/spotify/spotify.ts +0 -328
- package/src/clis/spotify/utils.test.ts +0 -87
- package/src/clis/spotify/utils.ts +0 -92
- package/src/clis/stackoverflow/bounties.yaml +0 -29
- package/src/clis/stackoverflow/hot.yaml +0 -28
- package/src/clis/stackoverflow/search.yaml +0 -33
- package/src/clis/stackoverflow/unanswered.yaml +0 -28
- package/src/clis/steam/top-sellers.yaml +0 -29
- package/src/clis/substack/feed.ts +0 -16
- package/src/clis/substack/publication.ts +0 -16
- package/src/clis/substack/search.ts +0 -92
- package/src/clis/substack/utils.test.ts +0 -54
- package/src/clis/substack/utils.ts +0 -141
- package/src/clis/tieba/commands.test.ts +0 -86
- package/src/clis/tieba/hot.ts +0 -52
- package/src/clis/tieba/posts.ts +0 -108
- package/src/clis/tieba/read.ts +0 -158
- package/src/clis/tieba/search.ts +0 -119
- package/src/clis/tieba/utils.test.ts +0 -322
- package/src/clis/tieba/utils.ts +0 -348
- package/src/clis/tiktok/comment.yaml +0 -66
- package/src/clis/tiktok/explore.yaml +0 -39
- package/src/clis/tiktok/follow.yaml +0 -39
- package/src/clis/tiktok/following.yaml +0 -46
- package/src/clis/tiktok/friends.yaml +0 -47
- package/src/clis/tiktok/like.yaml +0 -38
- package/src/clis/tiktok/live.yaml +0 -51
- package/src/clis/tiktok/notifications.yaml +0 -52
- package/src/clis/tiktok/profile.yaml +0 -45
- package/src/clis/tiktok/save.yaml +0 -34
- package/src/clis/tiktok/search.yaml +0 -47
- package/src/clis/tiktok/unfollow.yaml +0 -44
- package/src/clis/tiktok/unlike.yaml +0 -38
- package/src/clis/tiktok/unsave.yaml +0 -36
- package/src/clis/tiktok/user.yaml +0 -44
- package/src/clis/twitter/accept.ts +0 -214
- package/src/clis/twitter/article.ts +0 -170
- package/src/clis/twitter/block.ts +0 -93
- package/src/clis/twitter/bookmark.ts +0 -68
- package/src/clis/twitter/bookmarks.ts +0 -202
- package/src/clis/twitter/delete.ts +0 -78
- package/src/clis/twitter/download.ts +0 -118
- package/src/clis/twitter/follow.ts +0 -70
- package/src/clis/twitter/followers.ts +0 -116
- package/src/clis/twitter/following.ts +0 -109
- package/src/clis/twitter/hide-reply.ts +0 -71
- package/src/clis/twitter/like.ts +0 -74
- package/src/clis/twitter/likes.test.ts +0 -91
- package/src/clis/twitter/likes.ts +0 -256
- package/src/clis/twitter/notifications.ts +0 -136
- package/src/clis/twitter/post.ts +0 -76
- package/src/clis/twitter/profile.ts +0 -108
- package/src/clis/twitter/reply-dm.ts +0 -194
- package/src/clis/twitter/reply.ts +0 -63
- package/src/clis/twitter/search.test.ts +0 -265
- package/src/clis/twitter/search.ts +0 -185
- package/src/clis/twitter/shared.ts +0 -45
- package/src/clis/twitter/thread.ts +0 -182
- package/src/clis/twitter/timeline.test.ts +0 -109
- package/src/clis/twitter/timeline.ts +0 -248
- package/src/clis/twitter/trending.ts +0 -66
- package/src/clis/twitter/unblock.ts +0 -76
- package/src/clis/twitter/unbookmark.ts +0 -67
- package/src/clis/twitter/unfollow.ts +0 -76
- package/src/clis/v2ex/daily.ts +0 -106
- package/src/clis/v2ex/hot.yaml +0 -28
- package/src/clis/v2ex/latest.yaml +0 -28
- package/src/clis/v2ex/me.ts +0 -104
- package/src/clis/v2ex/member.yaml +0 -29
- package/src/clis/v2ex/node.yaml +0 -34
- package/src/clis/v2ex/nodes.yaml +0 -31
- package/src/clis/v2ex/notifications.ts +0 -76
- package/src/clis/v2ex/replies.yaml +0 -32
- package/src/clis/v2ex/topic.yaml +0 -33
- package/src/clis/v2ex/user.yaml +0 -34
- package/src/clis/web/read.ts +0 -210
- package/src/clis/weibo/comments.ts +0 -54
- package/src/clis/weibo/feed.ts +0 -57
- package/src/clis/weibo/hot.ts +0 -39
- package/src/clis/weibo/me.ts +0 -77
- package/src/clis/weibo/post.ts +0 -77
- package/src/clis/weibo/search.ts +0 -78
- package/src/clis/weibo/user.ts +0 -64
- package/src/clis/weibo/utils.ts +0 -32
- package/src/clis/weixin/download.ts +0 -382
- package/src/clis/weread/book.ts +0 -271
- package/src/clis/weread/commands.test.ts +0 -466
- package/src/clis/weread/highlights.ts +0 -25
- package/src/clis/weread/notebooks.ts +0 -23
- package/src/clis/weread/notes.ts +0 -31
- package/src/clis/weread/private-api-regression.test.ts +0 -435
- package/src/clis/weread/ranking.ts +0 -29
- package/src/clis/weread/search-regression.test.ts +0 -440
- package/src/clis/weread/search.ts +0 -207
- package/src/clis/weread/shelf.ts +0 -84
- package/src/clis/weread/utils.test.ts +0 -153
- package/src/clis/weread/utils.ts +0 -390
- package/src/clis/wikipedia/random.ts +0 -19
- package/src/clis/wikipedia/search.ts +0 -38
- package/src/clis/wikipedia/summary.ts +0 -23
- package/src/clis/wikipedia/trending.ts +0 -41
- package/src/clis/wikipedia/utils.ts +0 -51
- package/src/clis/xiaohongshu/comments.test.ts +0 -173
- package/src/clis/xiaohongshu/comments.ts +0 -140
- package/src/clis/xiaohongshu/creator-note-detail.test.ts +0 -275
- package/src/clis/xiaohongshu/creator-note-detail.ts +0 -447
- package/src/clis/xiaohongshu/creator-notes-summary.test.ts +0 -54
- package/src/clis/xiaohongshu/creator-notes-summary.ts +0 -120
- package/src/clis/xiaohongshu/creator-notes.test.ts +0 -214
- package/src/clis/xiaohongshu/creator-notes.ts +0 -295
- package/src/clis/xiaohongshu/creator-profile.ts +0 -59
- package/src/clis/xiaohongshu/creator-stats.ts +0 -80
- package/src/clis/xiaohongshu/download.test.ts +0 -96
- package/src/clis/xiaohongshu/download.ts +0 -174
- package/src/clis/xiaohongshu/feed.yaml +0 -31
- package/src/clis/xiaohongshu/note-helpers.ts +0 -25
- package/src/clis/xiaohongshu/note.test.ts +0 -215
- package/src/clis/xiaohongshu/note.ts +0 -104
- package/src/clis/xiaohongshu/notifications.yaml +0 -37
- package/src/clis/xiaohongshu/publish.test.ts +0 -230
- package/src/clis/xiaohongshu/publish.ts +0 -598
- package/src/clis/xiaohongshu/search.test.ts +0 -180
- package/src/clis/xiaohongshu/search.ts +0 -133
- package/src/clis/xiaohongshu/user-helpers.test.ts +0 -129
- package/src/clis/xiaohongshu/user-helpers.ts +0 -89
- package/src/clis/xiaohongshu/user.ts +0 -64
- package/src/clis/xiaoyuzhou/episode.ts +0 -28
- package/src/clis/xiaoyuzhou/podcast-episodes.ts +0 -36
- package/src/clis/xiaoyuzhou/podcast.ts +0 -27
- package/src/clis/xiaoyuzhou/utils.test.ts +0 -122
- package/src/clis/xiaoyuzhou/utils.ts +0 -65
- package/src/clis/xueqiu/comments.test.ts +0 -823
- package/src/clis/xueqiu/comments.ts +0 -461
- package/src/clis/xueqiu/danjuan-utils.test.ts +0 -49
- package/src/clis/xueqiu/danjuan-utils.ts +0 -176
- package/src/clis/xueqiu/earnings-date.yaml +0 -69
- package/src/clis/xueqiu/feed.yaml +0 -53
- package/src/clis/xueqiu/fund-holdings.ts +0 -32
- package/src/clis/xueqiu/fund-snapshot.ts +0 -27
- package/src/clis/xueqiu/hot-stock.yaml +0 -49
- package/src/clis/xueqiu/hot.yaml +0 -46
- package/src/clis/xueqiu/search.yaml +0 -55
- package/src/clis/xueqiu/stock.yaml +0 -69
- package/src/clis/xueqiu/watchlist.yaml +0 -46
- package/src/clis/yahoo-finance/quote.ts +0 -72
- package/src/clis/yollomi/background.ts +0 -48
- package/src/clis/yollomi/edit.ts +0 -58
- package/src/clis/yollomi/face-swap.ts +0 -45
- package/src/clis/yollomi/generate.ts +0 -95
- package/src/clis/yollomi/models.ts +0 -38
- package/src/clis/yollomi/object-remover.ts +0 -44
- package/src/clis/yollomi/remove-bg.ts +0 -40
- package/src/clis/yollomi/restore.ts +0 -40
- package/src/clis/yollomi/try-on.ts +0 -48
- package/src/clis/yollomi/upload.ts +0 -78
- package/src/clis/yollomi/upscale.ts +0 -49
- package/src/clis/yollomi/utils.ts +0 -202
- package/src/clis/yollomi/video.ts +0 -61
- package/src/clis/youtube/channel.ts +0 -155
- package/src/clis/youtube/comments.ts +0 -97
- package/src/clis/youtube/search.ts +0 -99
- package/src/clis/youtube/transcript-group.test.ts +0 -108
- package/src/clis/youtube/transcript-group.ts +0 -287
- package/src/clis/youtube/transcript.ts +0 -279
- package/src/clis/youtube/utils.test.ts +0 -43
- package/src/clis/youtube/utils.ts +0 -97
- package/src/clis/youtube/video.ts +0 -118
- package/src/clis/zhihu/download.test.ts +0 -14
- package/src/clis/zhihu/download.ts +0 -87
- package/src/clis/zhihu/hot.yaml +0 -46
- package/src/clis/zhihu/question.test.ts +0 -71
- package/src/clis/zhihu/question.ts +0 -58
- package/src/clis/zhihu/search.yaml +0 -59
- package/src/clis/zsxq/dynamics.ts +0 -60
- package/src/clis/zsxq/groups.ts +0 -41
- package/src/clis/zsxq/search.test.ts +0 -29
- package/src/clis/zsxq/search.ts +0 -54
- package/src/clis/zsxq/topic.test.ts +0 -34
- package/src/clis/zsxq/topic.ts +0 -68
- package/src/clis/zsxq/topics.test.ts +0 -29
- package/src/clis/zsxq/topics.ts +0 -36
- package/src/clis/zsxq/utils.ts +0 -351
- package/src/commanderAdapter.test.ts +0 -264
- package/src/commanderAdapter.ts +0 -315
- package/src/commands/daemon.test.ts +0 -204
- package/src/commands/daemon.ts +0 -87
- package/src/completion.ts +0 -130
- package/src/constants.ts +0 -41
- package/src/daemon.test.ts +0 -88
- package/src/daemon.ts +0 -339
- package/src/discovery.ts +0 -328
- package/src/doctor.test.ts +0 -111
- package/src/doctor.ts +0 -163
- package/src/download/article-download.ts +0 -272
- package/src/download/index.test.ts +0 -135
- package/src/download/index.ts +0 -422
- package/src/download/media-download.ts +0 -180
- package/src/download/progress.ts +0 -125
- package/src/electron-apps.test.ts +0 -50
- package/src/electron-apps.ts +0 -89
- package/src/engine.test.ts +0 -323
- package/src/errors.test.ts +0 -79
- package/src/errors.ts +0 -162
- package/src/execution.test.ts +0 -47
- package/src/execution.ts +0 -239
- package/src/explore.ts +0 -502
- package/src/extension-manifest-regression.test.ts +0 -18
- package/src/external-clis.yaml +0 -56
- package/src/external.test.ts +0 -97
- package/src/external.ts +0 -246
- package/src/generate.ts +0 -161
- package/src/hooks.test.ts +0 -126
- package/src/hooks.ts +0 -91
- package/src/idle-manager.ts +0 -60
- package/src/interceptor.test.ts +0 -94
- package/src/interceptor.ts +0 -204
- package/src/launcher.test.ts +0 -67
- package/src/launcher.ts +0 -185
- package/src/logger.ts +0 -57
- package/src/main.ts +0 -66
- package/src/node-network.test.ts +0 -93
- package/src/node-network.ts +0 -213
- package/src/output.test.ts +0 -109
- package/src/output.ts +0 -136
- package/src/pipeline/executor.test.ts +0 -193
- package/src/pipeline/executor.ts +0 -110
- package/src/pipeline/index.ts +0 -6
- package/src/pipeline/registry.ts +0 -62
- package/src/pipeline/steps/browser.ts +0 -76
- package/src/pipeline/steps/download.test.ts +0 -137
- package/src/pipeline/steps/download.ts +0 -320
- package/src/pipeline/steps/fetch.test.ts +0 -179
- package/src/pipeline/steps/fetch.ts +0 -160
- package/src/pipeline/steps/intercept.ts +0 -55
- package/src/pipeline/steps/tap.ts +0 -100
- package/src/pipeline/steps/transform.ts +0 -71
- package/src/pipeline/template.test.ts +0 -177
- package/src/pipeline/template.ts +0 -269
- package/src/pipeline/transform.test.ts +0 -140
- package/src/plugin-manifest.test.ts +0 -223
- package/src/plugin-manifest.ts +0 -206
- package/src/plugin-scaffold.test.ts +0 -98
- package/src/plugin-scaffold.ts +0 -170
- package/src/plugin.test.ts +0 -1427
- package/src/plugin.ts +0 -1537
- package/src/record.test.ts +0 -362
- package/src/record.ts +0 -824
- package/src/registry-api.ts +0 -14
- package/src/registry.test.ts +0 -133
- package/src/registry.ts +0 -158
- package/src/runtime-detect.test.ts +0 -30
- package/src/runtime-detect.ts +0 -36
- package/src/runtime.ts +0 -86
- package/src/scripts/framework.ts +0 -20
- package/src/scripts/interact.ts +0 -22
- package/src/scripts/store.ts +0 -40
- package/src/serialization.test.ts +0 -44
- package/src/serialization.ts +0 -90
- package/src/snapshotFormatter.test.ts +0 -579
- package/src/snapshotFormatter.ts +0 -359
- package/src/synthesize.ts +0 -296
- package/src/tui.test.ts +0 -23
- package/src/tui.ts +0 -237
- package/src/types.ts +0 -88
- package/src/update-check.ts +0 -114
- package/src/utils.ts +0 -44
- package/src/validate.ts +0 -103
- package/src/verify.ts +0 -93
- package/src/version.ts +0 -18
- package/src/weixin-download.test.ts +0 -91
- package/src/yaml-schema.ts +0 -48
- package/tests/e2e/band-auth.test.ts +0 -20
- package/tests/e2e/browser-auth-helpers.ts +0 -18
- package/tests/e2e/browser-auth.test.ts +0 -141
- package/tests/e2e/browser-public-extended.test.ts +0 -166
- package/tests/e2e/browser-public.test.ts +0 -417
- package/tests/e2e/helpers.ts +0 -64
- package/tests/e2e/management.test.ts +0 -106
- package/tests/e2e/output-formats.test.ts +0 -44
- package/tests/e2e/plugin-management.test.ts +0 -140
- package/tests/e2e/public-commands.test.ts +0 -569
- package/tests/smoke/api-health.test.ts +0 -131
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -50
- /package/dist/{browser.test.d.ts → clis/1688/item.test.d.ts} +0 -0
- /package/dist/{browser/cdp.test.d.ts → clis/1688/search.test.d.ts} +0 -0
- /package/dist/{browser/daemon-client.test.d.ts → clis/1688/shared.test.d.ts} +0 -0
- /package/dist/{browser/dom-helpers.test.d.ts → clis/1688/store.test.d.ts} +0 -0
- /package/dist/{browser/page.test.d.ts → clis/amazon/movers-shakers.d.ts} +0 -0
- /package/dist/{browser/stealth.test.d.ts → clis/amazon/new-releases.d.ts} +0 -0
- /package/dist/{build-manifest.test.d.ts → clis/amazon/rankings.test.d.ts} +0 -0
- /package/dist/{capabilityRouting.test.d.ts → clis/bilibili/utils.test.d.ts} +0 -0
- /package/dist/{commanderAdapter.test.d.ts → clis/gemini/ask.test.d.ts} +0 -0
- /package/dist/{commands/daemon.test.d.ts → clis/gemini/deep-research-result.test.d.ts} +0 -0
- /package/dist/{daemon.test.d.ts → clis/gemini/deep-research.test.d.ts} +0 -0
- /package/dist/{doctor.test.d.ts → clis/gemini/reply-state.test.d.ts} +0 -0
- /package/dist/{download/index.test.d.ts → clis/hupu/detail.d.ts} +0 -0
- /package/dist/{electron-apps.test.d.ts → clis/hupu/like.d.ts} +0 -0
- /package/dist/{engine.test.d.ts → clis/hupu/mentions.d.ts} +0 -0
- /package/dist/{errors.test.d.ts → clis/hupu/reply.d.ts} +0 -0
- /package/dist/{execution.test.d.ts → clis/hupu/search.d.ts} +0 -0
- /package/dist/{extension-manifest-regression.test.d.ts → clis/hupu/unlike.d.ts} +0 -0
- /package/dist/{external.test.d.ts → clis/instagram/_shared/private-publish.test.d.ts} +0 -0
- /package/dist/{launcher.test.d.ts → clis/instagram/_shared/protocol-capture.test.d.ts} +0 -0
- /package/dist/{node-network.test.d.ts → clis/instagram/note.d.ts} +0 -0
- /package/dist/{pipeline/steps/download.test.d.ts → clis/instagram/reel.d.ts} +0 -0
- /package/dist/{pipeline/steps/fetch.test.d.ts → clis/instagram/story.d.ts} +0 -0
- /package/dist/{record.test.d.ts → clis/lesswrong/comments.d.ts} +0 -0
- /package/dist/{runtime-detect.test.d.ts → clis/lesswrong/curated.d.ts} +0 -0
- /package/dist/{serialization.test.d.ts → clis/lesswrong/frontpage.d.ts} +0 -0
- /package/dist/{tui.test.d.ts → clis/lesswrong/new.d.ts} +0 -0
- /package/dist/{weixin-download.test.d.ts → clis/lesswrong/read.d.ts} +0 -0
- /package/dist/{analysis.d.ts → src/analysis.d.ts} +0 -0
- /package/dist/{analysis.js → src/analysis.js} +0 -0
- /package/dist/{browser → src/browser}/bridge.d.ts +0 -0
- /package/dist/{browser → src/browser}/cdp.test.js +0 -0
- /package/dist/{browser → src/browser}/daemon-client.test.js +0 -0
- /package/dist/{browser → src/browser}/discover.d.ts +0 -0
- /package/dist/{browser → src/browser}/discover.js +0 -0
- /package/dist/{browser → src/browser}/dom-helpers.test.js +0 -0
- /package/dist/{browser → src/browser}/dom-snapshot.d.ts +0 -0
- /package/dist/{browser → src/browser}/dom-snapshot.test.d.ts +0 -0
- /package/dist/{browser → src/browser}/dom-snapshot.test.js +0 -0
- /package/dist/{browser → src/browser}/errors.d.ts +0 -0
- /package/dist/{browser → src/browser}/errors.js +0 -0
- /package/dist/{browser → src/browser}/index.d.ts +0 -0
- /package/dist/{browser → src/browser}/index.js +0 -0
- /package/dist/{browser → src/browser}/page.test.js +0 -0
- /package/dist/{browser → src/browser}/stealth.d.ts +0 -0
- /package/dist/{browser → src/browser}/stealth.js +0 -0
- /package/dist/{browser → src/browser}/stealth.test.js +0 -0
- /package/dist/{browser → src/browser}/tabs.d.ts +0 -0
- /package/dist/{browser → src/browser}/tabs.js +0 -0
- /package/dist/{build-manifest.test.js → src/build-manifest.test.js} +0 -0
- /package/dist/{capabilityRouting.d.ts → src/capabilityRouting.d.ts} +0 -0
- /package/dist/{capabilityRouting.js → src/capabilityRouting.js} +0 -0
- /package/dist/{capabilityRouting.test.js → src/capabilityRouting.test.js} +0 -0
- /package/dist/{cascade.d.ts → src/cascade.d.ts} +0 -0
- /package/dist/{commands → src/commands}/daemon.d.ts +0 -0
- /package/dist/{commands → src/commands}/daemon.js +0 -0
- /package/dist/{commands → src/commands}/daemon.test.js +0 -0
- /package/dist/{completion.d.ts → src/completion.d.ts} +0 -0
- /package/dist/{constants.d.ts → src/constants.d.ts} +0 -0
- /package/dist/{constants.js → src/constants.js} +0 -0
- /package/dist/{daemon.d.ts → src/daemon.d.ts} +0 -0
- /package/dist/{daemon.js → src/daemon.js} +0 -0
- /package/dist/{daemon.test.js → src/daemon.test.js} +0 -0
- /package/dist/{doctor.d.ts → src/doctor.d.ts} +0 -0
- /package/dist/{doctor.test.js → src/doctor.test.js} +0 -0
- /package/dist/{download → src/download}/index.test.js +0 -0
- /package/dist/{electron-apps.test.js → src/electron-apps.test.js} +0 -0
- /package/dist/{engine.test.js → src/engine.test.js} +0 -0
- /package/dist/{errors.d.ts → src/errors.d.ts} +0 -0
- /package/dist/{errors.test.js → src/errors.test.js} +0 -0
- /package/dist/{execution.d.ts → src/execution.d.ts} +0 -0
- /package/dist/{execution.test.js → src/execution.test.js} +0 -0
- /package/dist/{explore.d.ts → src/explore.d.ts} +0 -0
- /package/dist/{extension-manifest-regression.test.js → src/extension-manifest-regression.test.js} +0 -0
- /package/dist/{external-clis.yaml → src/external-clis.yaml} +0 -0
- /package/dist/{external.d.ts → src/external.d.ts} +0 -0
- /package/dist/{external.js → src/external.js} +0 -0
- /package/dist/{external.test.js → src/external.test.js} +0 -0
- /package/dist/{generate.d.ts → src/generate.d.ts} +0 -0
- /package/dist/{generate.js → src/generate.js} +0 -0
- /package/dist/{hooks.d.ts → src/hooks.d.ts} +0 -0
- /package/dist/{hooks.js → src/hooks.js} +0 -0
- /package/dist/{hooks.test.d.ts → src/hooks.test.d.ts} +0 -0
- /package/dist/{hooks.test.js → src/hooks.test.js} +0 -0
- /package/dist/{idle-manager.d.ts → src/idle-manager.d.ts} +0 -0
- /package/dist/{idle-manager.js → src/idle-manager.js} +0 -0
- /package/dist/{interceptor.test.d.ts → src/interceptor.test.d.ts} +0 -0
- /package/dist/{interceptor.test.js → src/interceptor.test.js} +0 -0
- /package/dist/{logger.d.ts → src/logger.d.ts} +0 -0
- /package/dist/{logger.js → src/logger.js} +0 -0
- /package/dist/{main.d.ts → src/main.d.ts} +0 -0
- /package/dist/{node-network.d.ts → src/node-network.d.ts} +0 -0
- /package/dist/{node-network.js → src/node-network.js} +0 -0
- /package/dist/{node-network.test.js → src/node-network.test.js} +0 -0
- /package/dist/{pipeline → src/pipeline}/executor.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/executor.js +0 -0
- /package/dist/{pipeline → src/pipeline}/executor.test.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/registry.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/registry.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/browser.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/browser.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/download.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/download.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/fetch.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/fetch.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/fetch.test.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/intercept.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/intercept.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/tap.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/tap.js +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/transform.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/steps/transform.js +0 -0
- /package/dist/{pipeline → src/pipeline}/template.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/template.js +0 -0
- /package/dist/{pipeline → src/pipeline}/template.test.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/template.test.js +0 -0
- /package/dist/{pipeline → src/pipeline}/transform.test.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/transform.test.js +0 -0
- /package/dist/{plugin-manifest.d.ts → src/plugin-manifest.d.ts} +0 -0
- /package/dist/{plugin-manifest.js → src/plugin-manifest.js} +0 -0
- /package/dist/{plugin-manifest.test.d.ts → src/plugin-manifest.test.d.ts} +0 -0
- /package/dist/{plugin-manifest.test.js → src/plugin-manifest.test.js} +0 -0
- /package/dist/{plugin-scaffold.d.ts → src/plugin-scaffold.d.ts} +0 -0
- /package/dist/{plugin-scaffold.js → src/plugin-scaffold.js} +0 -0
- /package/dist/{plugin-scaffold.test.d.ts → src/plugin-scaffold.test.d.ts} +0 -0
- /package/dist/{plugin-scaffold.test.js → src/plugin-scaffold.test.js} +0 -0
- /package/dist/{plugin.d.ts → src/plugin.d.ts} +0 -0
- /package/dist/{plugin.js → src/plugin.js} +0 -0
- /package/dist/{plugin.test.d.ts → src/plugin.test.d.ts} +0 -0
- /package/dist/{plugin.test.js → src/plugin.test.js} +0 -0
- /package/dist/{record.d.ts → src/record.d.ts} +0 -0
- /package/dist/{record.test.js → src/record.test.js} +0 -0
- /package/dist/{registry-api.d.ts → src/registry-api.d.ts} +0 -0
- /package/dist/{registry-api.js → src/registry-api.js} +0 -0
- /package/dist/{registry.js → src/registry.js} +0 -0
- /package/dist/{registry.test.d.ts → src/registry.test.d.ts} +0 -0
- /package/dist/{registry.test.js → src/registry.test.js} +0 -0
- /package/dist/{runtime-detect.d.ts → src/runtime-detect.d.ts} +0 -0
- /package/dist/{runtime-detect.js → src/runtime-detect.js} +0 -0
- /package/dist/{runtime-detect.test.js → src/runtime-detect.test.js} +0 -0
- /package/dist/{runtime.d.ts → src/runtime.d.ts} +0 -0
- /package/dist/{runtime.js → src/runtime.js} +0 -0
- /package/dist/{scripts → src/scripts}/framework.d.ts +0 -0
- /package/dist/{scripts → src/scripts}/framework.js +0 -0
- /package/dist/{scripts → src/scripts}/interact.d.ts +0 -0
- /package/dist/{scripts → src/scripts}/interact.js +0 -0
- /package/dist/{scripts → src/scripts}/store.d.ts +0 -0
- /package/dist/{scripts → src/scripts}/store.js +0 -0
- /package/dist/{serialization.test.js → src/serialization.test.js} +0 -0
- /package/dist/{snapshotFormatter.d.ts → src/snapshotFormatter.d.ts} +0 -0
- /package/dist/{snapshotFormatter.js → src/snapshotFormatter.js} +0 -0
- /package/dist/{snapshotFormatter.test.d.ts → src/snapshotFormatter.test.d.ts} +0 -0
- /package/dist/{snapshotFormatter.test.js → src/snapshotFormatter.test.js} +0 -0
- /package/dist/{tui.d.ts → src/tui.d.ts} +0 -0
- /package/dist/{tui.js → src/tui.js} +0 -0
- /package/dist/{tui.test.js → src/tui.test.js} +0 -0
- /package/dist/{types.js → src/types.js} +0 -0
- /package/dist/{update-check.d.ts → src/update-check.d.ts} +0 -0
- /package/dist/{update-check.js → src/update-check.js} +0 -0
- /package/dist/{utils.d.ts → src/utils.d.ts} +0 -0
- /package/dist/{utils.js → src/utils.js} +0 -0
- /package/dist/{validate.d.ts → src/validate.d.ts} +0 -0
- /package/dist/{validate.js → src/validate.js} +0 -0
- /package/dist/{verify.d.ts → src/verify.d.ts} +0 -0
- /package/dist/{verify.js → src/verify.js} +0 -0
- /package/dist/{version.d.ts → src/version.d.ts} +0 -0
- /package/dist/{version.js → src/version.js} +0 -0
- /package/dist/{yaml-schema.d.ts → src/yaml-schema.d.ts} +0 -0
- /package/dist/{yaml-schema.js → src/yaml-schema.js} +0 -0
|
@@ -1,11 +1,141 @@
|
|
|
1
|
+
import { CommandExecutionError } from '../../src/errors.js';
|
|
1
2
|
export const GEMINI_DOMAIN = 'gemini.google.com';
|
|
2
3
|
export const GEMINI_APP_URL = 'https://gemini.google.com/app';
|
|
4
|
+
export const GEMINI_DEEP_RESEARCH_DEFAULT_TOOL_LABELS = ['Deep Research', 'Deep research', '\u6df1\u5ea6\u7814\u7a76'];
|
|
5
|
+
export const GEMINI_DEEP_RESEARCH_DEFAULT_CONFIRM_LABELS = [
|
|
6
|
+
'Start research',
|
|
7
|
+
'Start Research',
|
|
8
|
+
'Start deep research',
|
|
9
|
+
'Start Deep Research',
|
|
10
|
+
'Generate research plan',
|
|
11
|
+
'Generate Research Plan',
|
|
12
|
+
'Generate deep research plan',
|
|
13
|
+
'Generate Deep Research Plan',
|
|
14
|
+
'\u5f00\u59cb\u7814\u7a76',
|
|
15
|
+
'\u5f00\u59cb\u6df1\u5ea6\u7814\u7a76',
|
|
16
|
+
'\u5f00\u59cb\u8c03\u7814',
|
|
17
|
+
'\u751f\u6210\u7814\u7a76\u8ba1\u5212',
|
|
18
|
+
'\u751f\u6210\u8c03\u7814\u8ba1\u5212',
|
|
19
|
+
];
|
|
3
20
|
const GEMINI_RESPONSE_NOISE_PATTERNS = [
|
|
4
21
|
/Gemini can make mistakes\.?/gi,
|
|
5
22
|
/Google Terms/gi,
|
|
6
23
|
/Google Privacy Policy/gi,
|
|
7
24
|
/Opens in a new window/gi,
|
|
8
25
|
];
|
|
26
|
+
const GEMINI_TRANSCRIPT_CHROME_MARKERS = ['gemini', '我的内容', '对话', 'google terms', 'google privacy policy'];
|
|
27
|
+
const GEMINI_COMPOSER_SELECTORS = [
|
|
28
|
+
'.ql-editor[contenteditable="true"]',
|
|
29
|
+
'.ql-editor[role="textbox"]',
|
|
30
|
+
'.ql-editor[aria-label*="Gemini"]',
|
|
31
|
+
'[contenteditable="true"][aria-label*="Gemini"]',
|
|
32
|
+
'[aria-label="Enter a prompt for Gemini"]',
|
|
33
|
+
'[aria-label*="prompt for Gemini"]',
|
|
34
|
+
];
|
|
35
|
+
const GEMINI_COMPOSER_MARKER_ATTR = 'data-opencli-gemini-composer';
|
|
36
|
+
const GEMINI_COMPOSER_PREPARE_ATTEMPTS = 4;
|
|
37
|
+
const GEMINI_COMPOSER_PREPARE_WAIT_SECONDS = 1;
|
|
38
|
+
function buildGeminiComposerLocatorScript() {
|
|
39
|
+
const selectorsJson = JSON.stringify(GEMINI_COMPOSER_SELECTORS);
|
|
40
|
+
const markerAttrJson = JSON.stringify(GEMINI_COMPOSER_MARKER_ATTR);
|
|
41
|
+
return `
|
|
42
|
+
const isVisible = (el) => {
|
|
43
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
44
|
+
const style = window.getComputedStyle(el);
|
|
45
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
46
|
+
const rect = el.getBoundingClientRect();
|
|
47
|
+
return rect.width > 0 && rect.height > 0;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const markerAttr = ${markerAttrJson};
|
|
51
|
+
const clearComposerMarkers = (active) => {
|
|
52
|
+
document.querySelectorAll('[' + markerAttr + ']').forEach((node) => {
|
|
53
|
+
if (node !== active) node.removeAttribute(markerAttr);
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const markComposer = (node) => {
|
|
58
|
+
if (!(node instanceof HTMLElement)) return null;
|
|
59
|
+
clearComposerMarkers(node);
|
|
60
|
+
node.setAttribute(markerAttr, '1');
|
|
61
|
+
return node;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const findComposer = () => {
|
|
65
|
+
const marked = document.querySelector('[' + markerAttr + '="1"]');
|
|
66
|
+
if (marked instanceof HTMLElement && isVisible(marked)) return marked;
|
|
67
|
+
|
|
68
|
+
const selectors = ${selectorsJson};
|
|
69
|
+
for (const selector of selectors) {
|
|
70
|
+
const node = Array.from(document.querySelectorAll(selector)).find((candidate) => candidate instanceof HTMLElement && isVisible(candidate));
|
|
71
|
+
if (node instanceof HTMLElement) return markComposer(node);
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
};
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
export function resolveGeminiLabels(value, fallback) {
|
|
78
|
+
const label = String(value ?? '').trim();
|
|
79
|
+
return label ? [label] : fallback;
|
|
80
|
+
}
|
|
81
|
+
export function parseGeminiPositiveInt(value, fallback) {
|
|
82
|
+
const parsed = Number.parseInt(String(value ?? ''), 10);
|
|
83
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
84
|
+
}
|
|
85
|
+
export function parseGeminiTitleMatchMode(value, fallback = 'contains') {
|
|
86
|
+
const raw = String(value ?? fallback).trim().toLowerCase();
|
|
87
|
+
if (raw === 'contains' || raw === 'exact')
|
|
88
|
+
return raw;
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
export function parseGeminiConversationUrl(value) {
|
|
92
|
+
const raw = String(value ?? '').trim();
|
|
93
|
+
if (!raw)
|
|
94
|
+
return null;
|
|
95
|
+
try {
|
|
96
|
+
const url = new URL(raw);
|
|
97
|
+
if (url.hostname !== GEMINI_DOMAIN && !url.hostname.endsWith(`.${GEMINI_DOMAIN}`))
|
|
98
|
+
return null;
|
|
99
|
+
if (!url.pathname.startsWith('/app/'))
|
|
100
|
+
return null;
|
|
101
|
+
return url.href;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export function normalizeGeminiTitle(value) {
|
|
108
|
+
return value.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
109
|
+
}
|
|
110
|
+
export function pickGeminiConversationByTitle(conversations, query, mode = 'contains') {
|
|
111
|
+
const normalizedQuery = normalizeGeminiTitle(query);
|
|
112
|
+
if (!normalizedQuery)
|
|
113
|
+
return null;
|
|
114
|
+
for (const conversation of conversations) {
|
|
115
|
+
const normalizedTitle = normalizeGeminiTitle(conversation.Title);
|
|
116
|
+
if (!normalizedTitle)
|
|
117
|
+
continue;
|
|
118
|
+
if (mode === 'exact') {
|
|
119
|
+
if (normalizedTitle === normalizedQuery)
|
|
120
|
+
return conversation;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (normalizedTitle.includes(normalizedQuery))
|
|
124
|
+
return conversation;
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
export function resolveGeminiConversationForQuery(conversations, query, mode) {
|
|
129
|
+
const normalizedQuery = String(query ?? '').trim();
|
|
130
|
+
if (!normalizedQuery)
|
|
131
|
+
return conversations[0] ?? null;
|
|
132
|
+
const exact = pickGeminiConversationByTitle(conversations, normalizedQuery, 'exact');
|
|
133
|
+
if (exact)
|
|
134
|
+
return exact;
|
|
135
|
+
if (mode === 'contains')
|
|
136
|
+
return pickGeminiConversationByTitle(conversations, normalizedQuery, 'contains');
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
9
139
|
export function sanitizeGeminiResponseText(value, promptText) {
|
|
10
140
|
let sanitized = value;
|
|
11
141
|
for (const pattern of GEMINI_RESPONSE_NOISE_PATTERNS) {
|
|
@@ -29,35 +159,163 @@ export function collectGeminiTranscriptAdditions(beforeLines, currentLines, prom
|
|
|
29
159
|
const beforeSet = new Set(beforeLines);
|
|
30
160
|
const additions = currentLines
|
|
31
161
|
.filter((line) => !beforeSet.has(line))
|
|
32
|
-
.map((line) =>
|
|
162
|
+
.map((line) => extractGeminiTranscriptLineCandidate(line, promptText))
|
|
33
163
|
.filter((line) => line && line !== promptText);
|
|
34
164
|
return additions.join('\n').trim();
|
|
35
165
|
}
|
|
166
|
+
export function collapseAdjacentGeminiTurns(turns) {
|
|
167
|
+
const collapsed = [];
|
|
168
|
+
for (const turn of turns) {
|
|
169
|
+
if (!turn || typeof turn.Role !== 'string' || typeof turn.Text !== 'string')
|
|
170
|
+
continue;
|
|
171
|
+
const previous = collapsed.at(-1);
|
|
172
|
+
if (previous?.Role === turn.Role && previous.Text === turn.Text)
|
|
173
|
+
continue;
|
|
174
|
+
collapsed.push(turn);
|
|
175
|
+
}
|
|
176
|
+
return collapsed;
|
|
177
|
+
}
|
|
178
|
+
function hasGeminiTurnPrefix(before, current) {
|
|
179
|
+
if (before.length > current.length)
|
|
180
|
+
return false;
|
|
181
|
+
return before.every((turn, index) => (turn.Role === current[index]?.Role
|
|
182
|
+
&& turn.Text === current[index]?.Text));
|
|
183
|
+
}
|
|
184
|
+
function findLastMatchingGeminiTurnIndex(turns, target) {
|
|
185
|
+
if (!target)
|
|
186
|
+
return null;
|
|
187
|
+
for (let index = turns.length - 1; index >= 0; index -= 1) {
|
|
188
|
+
const turn = turns[index];
|
|
189
|
+
if (turn?.Role === target.Role && turn.Text === target.Text) {
|
|
190
|
+
return index;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
function diffTrustedStructuredTurns(before, current) {
|
|
196
|
+
if (!before.structuredTurnsTrusted || !current.structuredTurnsTrusted) {
|
|
197
|
+
return {
|
|
198
|
+
appendedTurns: [],
|
|
199
|
+
hasTrustedAppend: false,
|
|
200
|
+
hasNewUserTurn: false,
|
|
201
|
+
hasNewAssistantTurn: false,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (!hasGeminiTurnPrefix(before.turns, current.turns)) {
|
|
205
|
+
return {
|
|
206
|
+
appendedTurns: [],
|
|
207
|
+
hasTrustedAppend: false,
|
|
208
|
+
hasNewUserTurn: false,
|
|
209
|
+
hasNewAssistantTurn: false,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const appendedTurns = current.turns.slice(before.turns.length);
|
|
213
|
+
return {
|
|
214
|
+
appendedTurns,
|
|
215
|
+
hasTrustedAppend: appendedTurns.length > 0,
|
|
216
|
+
hasNewUserTurn: appendedTurns.some((turn) => turn.Role === 'User'),
|
|
217
|
+
hasNewAssistantTurn: appendedTurns.some((turn) => turn.Role === 'Assistant'),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function diffTranscriptLines(before, current) {
|
|
221
|
+
const beforeLines = new Set(before.transcriptLines);
|
|
222
|
+
return current.transcriptLines.filter((line) => !beforeLines.has(line));
|
|
223
|
+
}
|
|
224
|
+
function isLikelyGeminiTranscriptChrome(line) {
|
|
225
|
+
const lower = line.toLowerCase();
|
|
226
|
+
const markerHits = GEMINI_TRANSCRIPT_CHROME_MARKERS.filter((marker) => lower.includes(marker)).length;
|
|
227
|
+
return markerHits >= 2;
|
|
228
|
+
}
|
|
229
|
+
function extractGeminiTranscriptLineCandidate(transcriptLine, promptText) {
|
|
230
|
+
const candidate = transcriptLine.trim();
|
|
231
|
+
if (!candidate)
|
|
232
|
+
return '';
|
|
233
|
+
const prompt = promptText.trim();
|
|
234
|
+
const sanitized = sanitizeGeminiResponseText(candidate, promptText);
|
|
235
|
+
if (!prompt)
|
|
236
|
+
return sanitized;
|
|
237
|
+
if (!candidate.includes(prompt))
|
|
238
|
+
return sanitized;
|
|
239
|
+
if (sanitized && sanitized !== prompt && sanitized !== candidate)
|
|
240
|
+
return sanitized;
|
|
241
|
+
if (isLikelyGeminiTranscriptChrome(candidate))
|
|
242
|
+
return '';
|
|
243
|
+
// Some transcript snapshots flatten "prompt + answer" into a single line.
|
|
244
|
+
// Recover the answer only when the line starts with the current prompt.
|
|
245
|
+
if (candidate.startsWith(prompt)) {
|
|
246
|
+
const tail = candidate.slice(prompt.length).replace(/^[\s::,,-]+/, '').trim();
|
|
247
|
+
return tail ? sanitizeGeminiResponseText(tail, '') : '';
|
|
248
|
+
}
|
|
249
|
+
return sanitized;
|
|
250
|
+
}
|
|
36
251
|
function getStateScript() {
|
|
37
252
|
return `
|
|
38
253
|
(() => {
|
|
254
|
+
${buildGeminiComposerLocatorScript()}
|
|
255
|
+
|
|
39
256
|
const signInNode = Array.from(document.querySelectorAll('a, button')).find((node) => {
|
|
40
257
|
const text = (node.textContent || '').trim().toLowerCase();
|
|
41
258
|
const aria = (node.getAttribute('aria-label') || '').trim().toLowerCase();
|
|
42
259
|
const href = node.getAttribute('href') || '';
|
|
43
260
|
return text === 'sign in'
|
|
44
261
|
|| aria === 'sign in'
|
|
262
|
+
|| text === '登录'
|
|
263
|
+
|| aria === '登录'
|
|
45
264
|
|| href.includes('accounts.google.com/ServiceLogin');
|
|
46
265
|
});
|
|
47
266
|
|
|
48
|
-
const composer =
|
|
49
|
-
const sendButton = document.querySelector('button[aria-label="Send message"]');
|
|
267
|
+
const composer = findComposer();
|
|
50
268
|
|
|
51
269
|
return {
|
|
52
270
|
url: window.location.href,
|
|
53
271
|
title: document.title || '',
|
|
54
272
|
isSignedIn: signInNode ? false : (composer ? true : null),
|
|
55
273
|
composerLabel: composer?.getAttribute('aria-label') || '',
|
|
56
|
-
canSend: !!
|
|
274
|
+
canSend: !!composer,
|
|
275
|
+
};
|
|
276
|
+
})()
|
|
277
|
+
`;
|
|
278
|
+
}
|
|
279
|
+
function readGeminiSnapshotScript() {
|
|
280
|
+
return `
|
|
281
|
+
(() => {
|
|
282
|
+
${buildGeminiComposerLocatorScript()}
|
|
283
|
+
const composer = findComposer();
|
|
284
|
+
const composerText = composer?.textContent?.replace(/\\u00a0/g, ' ').trim() || '';
|
|
285
|
+
const isGenerating = !!Array.from(document.querySelectorAll('button, [role="button"]')).find((node) => {
|
|
286
|
+
const text = (node.textContent || '').trim().toLowerCase();
|
|
287
|
+
const aria = (node.getAttribute('aria-label') || '').trim().toLowerCase();
|
|
288
|
+
return text === 'stop response'
|
|
289
|
+
|| aria === 'stop response'
|
|
290
|
+
|| text === '停止回答'
|
|
291
|
+
|| aria === '停止回答';
|
|
292
|
+
});
|
|
293
|
+
const turns = ${getTurnsScript().trim()};
|
|
294
|
+
const transcriptLines = ${getTranscriptLinesScript().trim()};
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
url: window.location.href,
|
|
298
|
+
turns,
|
|
299
|
+
transcriptLines,
|
|
300
|
+
composerHasText: composerText.length > 0,
|
|
301
|
+
isGenerating,
|
|
302
|
+
structuredTurnsTrusted: turns.length > 0 || transcriptLines.length === 0,
|
|
57
303
|
};
|
|
58
304
|
})()
|
|
59
305
|
`;
|
|
60
306
|
}
|
|
307
|
+
function isGeminiConversationUrl(url) {
|
|
308
|
+
try {
|
|
309
|
+
const parsed = new URL(url);
|
|
310
|
+
if (parsed.hostname !== GEMINI_DOMAIN && !parsed.hostname.endsWith(`.${GEMINI_DOMAIN}`))
|
|
311
|
+
return false;
|
|
312
|
+
const pathname = parsed.pathname.replace(/\/+$/, '');
|
|
313
|
+
return pathname.startsWith('/app/') && pathname !== '/app';
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
61
319
|
function getTranscriptLinesScript() {
|
|
62
320
|
return `
|
|
63
321
|
(() => {
|
|
@@ -159,7 +417,16 @@ function getTurnsScript() {
|
|
|
159
417
|
];
|
|
160
418
|
|
|
161
419
|
const roots = selectors.flatMap((selector) => Array.from(document.querySelectorAll(selector)));
|
|
162
|
-
const unique = roots
|
|
420
|
+
const unique = roots
|
|
421
|
+
.filter((el, index, all) => all.indexOf(el) === index)
|
|
422
|
+
.filter(isVisible)
|
|
423
|
+
.sort((left, right) => {
|
|
424
|
+
if (left === right) return 0;
|
|
425
|
+
const relation = left.compareDocumentPosition(right);
|
|
426
|
+
if (relation & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
|
|
427
|
+
if (relation & Node.DOCUMENT_POSITION_PRECEDING) return 1;
|
|
428
|
+
return 0;
|
|
429
|
+
});
|
|
163
430
|
|
|
164
431
|
const turns = unique.map((el) => {
|
|
165
432
|
const text = clean(el.innerText || el.textContent || '');
|
|
@@ -179,52 +446,184 @@ function getTurnsScript() {
|
|
|
179
446
|
return role ? { Role: role, Text: text } : null;
|
|
180
447
|
}).filter(Boolean);
|
|
181
448
|
|
|
182
|
-
|
|
183
|
-
const seen = new Set();
|
|
184
|
-
for (const turn of turns) {
|
|
185
|
-
const key = turn.Role + '::' + turn.Text;
|
|
186
|
-
if (seen.has(key)) continue;
|
|
187
|
-
seen.add(key);
|
|
188
|
-
deduped.push(turn);
|
|
189
|
-
}
|
|
190
|
-
return deduped;
|
|
449
|
+
return turns;
|
|
191
450
|
})()
|
|
192
451
|
`;
|
|
193
452
|
}
|
|
194
|
-
function
|
|
453
|
+
function prepareComposerScript() {
|
|
195
454
|
return `
|
|
196
|
-
((
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
455
|
+
(() => {
|
|
456
|
+
${buildGeminiComposerLocatorScript()}
|
|
457
|
+
const composer = findComposer();
|
|
458
|
+
|
|
459
|
+
if (!(composer instanceof HTMLElement)) {
|
|
460
|
+
return { ok: false, reason: 'Could not find Gemini composer' };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
try {
|
|
464
|
+
composer.focus();
|
|
200
465
|
const selection = window.getSelection();
|
|
201
466
|
const range = document.createRange();
|
|
202
|
-
range.selectNodeContents(
|
|
467
|
+
range.selectNodeContents(composer);
|
|
203
468
|
range.collapse(false);
|
|
204
469
|
selection?.removeAllRanges();
|
|
205
470
|
selection?.addRange(range);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
471
|
+
composer.textContent = '';
|
|
472
|
+
composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: '', inputType: 'deleteContentBackward' }));
|
|
473
|
+
} catch (error) {
|
|
474
|
+
return {
|
|
475
|
+
ok: false,
|
|
476
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
ok: true,
|
|
482
|
+
label: composer.getAttribute('aria-label') || '',
|
|
483
|
+
};
|
|
484
|
+
})()
|
|
485
|
+
`;
|
|
486
|
+
}
|
|
487
|
+
function composerHasTextScript() {
|
|
488
|
+
return `
|
|
489
|
+
(() => {
|
|
490
|
+
${buildGeminiComposerLocatorScript()}
|
|
491
|
+
const composer = findComposer();
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
hasText: !!(composer && ((composer.textContent || '').trim() || (composer.innerText || '').trim())),
|
|
495
|
+
};
|
|
496
|
+
})()
|
|
497
|
+
`;
|
|
498
|
+
}
|
|
499
|
+
function insertComposerTextFallbackScript(text) {
|
|
500
|
+
return `
|
|
501
|
+
((inputText) => {
|
|
502
|
+
${buildGeminiComposerLocatorScript()}
|
|
503
|
+
const composer = findComposer();
|
|
504
|
+
|
|
505
|
+
if (!(composer instanceof HTMLElement)) {
|
|
506
|
+
return { hasText: false, reason: 'Could not find Gemini composer' };
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const selection = window.getSelection();
|
|
510
|
+
const range = document.createRange();
|
|
511
|
+
range.selectNodeContents(composer);
|
|
512
|
+
range.collapse(false);
|
|
513
|
+
selection?.removeAllRanges();
|
|
514
|
+
selection?.addRange(range);
|
|
515
|
+
|
|
516
|
+
composer.focus();
|
|
517
|
+
composer.textContent = '';
|
|
518
|
+
const execResult = typeof document.execCommand === 'function'
|
|
519
|
+
? document.execCommand('insertText', false, inputText)
|
|
520
|
+
: false;
|
|
521
|
+
|
|
522
|
+
if (!execResult) {
|
|
523
|
+
const paragraph = document.createElement('p');
|
|
524
|
+
const lines = String(inputText).split(/\\n/);
|
|
525
|
+
for (const [index, line] of lines.entries()) {
|
|
526
|
+
if (index > 0) paragraph.appendChild(document.createElement('br'));
|
|
527
|
+
paragraph.appendChild(document.createTextNode(line));
|
|
528
|
+
}
|
|
529
|
+
composer.replaceChildren(paragraph);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
composer.dispatchEvent(new InputEvent('beforeinput', { bubbles: true, data: inputText, inputType: 'insertText' }));
|
|
533
|
+
composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: inputText, inputType: 'insertText' }));
|
|
534
|
+
composer.dispatchEvent(new Event('change', { bubbles: true }));
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
hasText: !!((composer.textContent || '').trim() || (composer.innerText || '').trim()),
|
|
209
538
|
};
|
|
539
|
+
})(${JSON.stringify(text)})
|
|
540
|
+
`;
|
|
541
|
+
}
|
|
542
|
+
function submitComposerScript() {
|
|
543
|
+
return `
|
|
544
|
+
(() => {
|
|
545
|
+
${buildGeminiComposerLocatorScript()}
|
|
546
|
+
const composer = findComposer();
|
|
210
547
|
|
|
211
|
-
const composer = document.querySelector('[aria-label="Enter a prompt for Gemini"], [aria-label*="prompt for Gemini"], .ql-editor[aria-label*="Gemini"], [contenteditable="true"][aria-label*="Gemini"]');
|
|
212
548
|
if (!(composer instanceof HTMLElement)) {
|
|
213
549
|
throw new Error('Could not find Gemini composer');
|
|
214
550
|
}
|
|
215
551
|
|
|
216
|
-
|
|
552
|
+
const composerRect = composer.getBoundingClientRect();
|
|
553
|
+
const rootCandidates = [
|
|
554
|
+
composer.closest('form'),
|
|
555
|
+
composer.closest('[role="form"]'),
|
|
556
|
+
composer.closest('.input-area-container'),
|
|
557
|
+
composer.closest('.textbox-container'),
|
|
558
|
+
composer.closest('.input-wrapper'),
|
|
559
|
+
composer.parentElement,
|
|
560
|
+
composer.parentElement?.parentElement,
|
|
561
|
+
].filter(Boolean);
|
|
562
|
+
|
|
563
|
+
const seen = new Set();
|
|
564
|
+
const buttons = [];
|
|
565
|
+
for (const root of rootCandidates) {
|
|
566
|
+
root.querySelectorAll('button, [role="button"]').forEach((node) => {
|
|
567
|
+
if (!(node instanceof HTMLElement)) return;
|
|
568
|
+
if (seen.has(node)) return;
|
|
569
|
+
seen.add(node);
|
|
570
|
+
buttons.push(node);
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const excludedPattern = /main menu|主菜单|microphone|麦克风|upload|上传|mode|模式|tools|工具|settings|临时对话|new chat|新对话/i;
|
|
575
|
+
const submitPattern = /send|发送|submit|提交/i;
|
|
576
|
+
let bestButton = null;
|
|
577
|
+
let bestScore = -1;
|
|
578
|
+
|
|
579
|
+
for (const button of buttons) {
|
|
580
|
+
if (!isVisible(button)) continue;
|
|
581
|
+
if (button instanceof HTMLButtonElement && button.disabled) continue;
|
|
582
|
+
if (button.getAttribute('aria-disabled') === 'true') continue;
|
|
583
|
+
|
|
584
|
+
const label = ((button.getAttribute('aria-label') || '') + ' ' + ((button.textContent || '').trim())).trim();
|
|
585
|
+
if (excludedPattern.test(label)) continue;
|
|
217
586
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
587
|
+
const rect = button.getBoundingClientRect();
|
|
588
|
+
const verticalDistance = Math.abs((rect.top + rect.bottom) / 2 - (composerRect.top + composerRect.bottom) / 2);
|
|
589
|
+
if (verticalDistance > 160) continue;
|
|
590
|
+
|
|
591
|
+
let score = 0;
|
|
592
|
+
if (submitPattern.test(label)) score += 10;
|
|
593
|
+
if (rect.left >= composerRect.right - 160) score += 3;
|
|
594
|
+
if (rect.left >= composerRect.left) score += 1;
|
|
595
|
+
if (rect.width <= 96 && rect.height <= 96) score += 1;
|
|
596
|
+
|
|
597
|
+
if (score > bestScore) {
|
|
598
|
+
bestScore = score;
|
|
599
|
+
bestButton = button;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if (bestButton instanceof HTMLElement && bestScore >= 3) {
|
|
604
|
+
bestButton.click();
|
|
221
605
|
return 'button';
|
|
222
606
|
}
|
|
223
607
|
|
|
224
|
-
composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
225
|
-
composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
226
608
|
return 'enter';
|
|
227
|
-
})(
|
|
609
|
+
})()
|
|
610
|
+
`;
|
|
611
|
+
}
|
|
612
|
+
function dispatchComposerEnterScript() {
|
|
613
|
+
return `
|
|
614
|
+
(() => {
|
|
615
|
+
${buildGeminiComposerLocatorScript()}
|
|
616
|
+
const composer = findComposer();
|
|
617
|
+
|
|
618
|
+
if (!(composer instanceof HTMLElement)) {
|
|
619
|
+
throw new Error('Could not find Gemini composer');
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
composer.focus();
|
|
623
|
+
composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true }));
|
|
624
|
+
composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true }));
|
|
625
|
+
return 'enter';
|
|
626
|
+
})()
|
|
228
627
|
`;
|
|
229
628
|
}
|
|
230
629
|
function clickNewChatScript() {
|
|
@@ -241,7 +640,14 @@ function clickNewChatScript() {
|
|
|
241
640
|
const candidates = Array.from(document.querySelectorAll('button, a')).filter((node) => {
|
|
242
641
|
const text = (node.textContent || '').trim().toLowerCase();
|
|
243
642
|
const aria = (node.getAttribute('aria-label') || '').trim().toLowerCase();
|
|
244
|
-
return isVisible(node) && (
|
|
643
|
+
return isVisible(node) && (
|
|
644
|
+
text === 'new chat'
|
|
645
|
+
|| aria === 'new chat'
|
|
646
|
+
|| text === '发起新对话'
|
|
647
|
+
|| aria === '发起新对话'
|
|
648
|
+
|| text === '新对话'
|
|
649
|
+
|| aria === '新对话'
|
|
650
|
+
);
|
|
245
651
|
});
|
|
246
652
|
|
|
247
653
|
const target = candidates.find((node) => !node.hasAttribute('disabled')) || candidates[0];
|
|
@@ -253,6 +659,337 @@ function clickNewChatScript() {
|
|
|
253
659
|
})()
|
|
254
660
|
`;
|
|
255
661
|
}
|
|
662
|
+
function openGeminiToolsMenuScript() {
|
|
663
|
+
return `
|
|
664
|
+
(() => {
|
|
665
|
+
const labels = ['tools', 'tool', 'mode', '研究', 'deep research', 'deep-research', '工具'];
|
|
666
|
+
const normalize = (value) => (value || '').replace(/\\s+/g, ' ').trim().toLowerCase();
|
|
667
|
+
const matchesLabel = (value) => {
|
|
668
|
+
const text = normalize(value);
|
|
669
|
+
return labels.some((label) => text.includes(label));
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
const isDisabled = (el) => {
|
|
673
|
+
if (!(el instanceof HTMLElement)) return true;
|
|
674
|
+
if ('disabled' in el && el.disabled) return true;
|
|
675
|
+
if (el.hasAttribute('disabled')) return true;
|
|
676
|
+
const ariaDisabled = (el.getAttribute('aria-disabled') || '').toLowerCase();
|
|
677
|
+
return ariaDisabled === 'true';
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
const isVisible = (el) => {
|
|
681
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
682
|
+
if (el.hidden || el.closest('[hidden]')) return false;
|
|
683
|
+
const ariaHidden = el.getAttribute('aria-hidden');
|
|
684
|
+
if (ariaHidden && ariaHidden.toLowerCase() === 'true') return false;
|
|
685
|
+
if (el.closest('[aria-hidden="true"]')) return false;
|
|
686
|
+
const style = window.getComputedStyle(el);
|
|
687
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
688
|
+
if (Number(style.opacity) === 0) return false;
|
|
689
|
+
if (style.pointerEvents === 'none') return false;
|
|
690
|
+
const rect = el.getBoundingClientRect();
|
|
691
|
+
return rect.width > 0 && rect.height > 0;
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
const isInteractable = (el) => isVisible(el) && !isDisabled(el);
|
|
695
|
+
|
|
696
|
+
const roots = [
|
|
697
|
+
document.querySelector('main'),
|
|
698
|
+
document.querySelector('[role="main"]'),
|
|
699
|
+
document.querySelector('header'),
|
|
700
|
+
document,
|
|
701
|
+
].filter(Boolean);
|
|
702
|
+
|
|
703
|
+
const isMenuTrigger = (node) => {
|
|
704
|
+
if (!(node instanceof HTMLElement)) return false;
|
|
705
|
+
const popupValue = (node.getAttribute('aria-haspopup') || '').toLowerCase();
|
|
706
|
+
const hasPopup = popupValue === 'menu' || popupValue === 'listbox' || popupValue === 'true';
|
|
707
|
+
const controls = (node.getAttribute('aria-controls') || '').toLowerCase();
|
|
708
|
+
const hasControls = ['menu', 'listbox', 'popup'].some((token) => controls.includes(token));
|
|
709
|
+
return hasPopup || hasControls;
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const menuAlreadyOpen = () => {
|
|
713
|
+
const visibleMenus = Array.from(document.querySelectorAll('[role="menu"], [role="listbox"]')).filter(isVisible);
|
|
714
|
+
const labeledMenu = visibleMenus.some((menu) => {
|
|
715
|
+
const text = menu.textContent || '';
|
|
716
|
+
const aria = menu.getAttribute('aria-label') || '';
|
|
717
|
+
return matchesLabel(text) || matchesLabel(aria);
|
|
718
|
+
});
|
|
719
|
+
if (labeledMenu) return true;
|
|
720
|
+
const expanded = Array.from(document.querySelectorAll('[aria-expanded="true"]')).filter(isVisible);
|
|
721
|
+
return expanded.some((node) => {
|
|
722
|
+
if (!(node instanceof HTMLElement)) return false;
|
|
723
|
+
const text = node.textContent || '';
|
|
724
|
+
const aria = node.getAttribute('aria-label') || '';
|
|
725
|
+
return isMenuTrigger(node) && (matchesLabel(text) || matchesLabel(aria));
|
|
726
|
+
});
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
if (menuAlreadyOpen()) return true;
|
|
730
|
+
|
|
731
|
+
const pickTarget = (root) => {
|
|
732
|
+
const nodes = Array.from(root.querySelectorAll('button, [role="button"]')).filter(isInteractable);
|
|
733
|
+
const matches = nodes.filter((node) => {
|
|
734
|
+
const text = (node.textContent || '').trim().toLowerCase();
|
|
735
|
+
const aria = (node.getAttribute('aria-label') || '').trim().toLowerCase();
|
|
736
|
+
if (!text && !aria) return false;
|
|
737
|
+
return matchesLabel(text) || matchesLabel(aria);
|
|
738
|
+
});
|
|
739
|
+
if (matches.length === 0) return null;
|
|
740
|
+
const menuMatches = matches.filter((node) => isMenuTrigger(node));
|
|
741
|
+
return menuMatches[0] || matches[0];
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
let target = null;
|
|
745
|
+
for (const root of roots) {
|
|
746
|
+
target = pickTarget(root);
|
|
747
|
+
if (target) break;
|
|
748
|
+
}
|
|
749
|
+
if (target instanceof HTMLElement) {
|
|
750
|
+
target.click();
|
|
751
|
+
return true;
|
|
752
|
+
}
|
|
753
|
+
return false;
|
|
754
|
+
})()
|
|
755
|
+
`;
|
|
756
|
+
}
|
|
757
|
+
function selectGeminiToolScript(labels) {
|
|
758
|
+
const labelsJson = JSON.stringify(labels);
|
|
759
|
+
return `
|
|
760
|
+
((targetLabels) => {
|
|
761
|
+
const isDisabled = (el) => {
|
|
762
|
+
if (!(el instanceof HTMLElement)) return true;
|
|
763
|
+
if ('disabled' in el && el.disabled) return true;
|
|
764
|
+
if (el.hasAttribute('disabled')) return true;
|
|
765
|
+
const ariaDisabled = (el.getAttribute('aria-disabled') || '').toLowerCase();
|
|
766
|
+
return ariaDisabled === 'true';
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
const isVisible = (el) => {
|
|
770
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
771
|
+
if (el.hidden || el.closest('[hidden]')) return false;
|
|
772
|
+
const ariaHidden = el.getAttribute('aria-hidden');
|
|
773
|
+
if (ariaHidden && ariaHidden.toLowerCase() === 'true') return false;
|
|
774
|
+
if (el.closest('[aria-hidden="true"]')) return false;
|
|
775
|
+
const style = window.getComputedStyle(el);
|
|
776
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
777
|
+
if (Number(style.opacity) === 0) return false;
|
|
778
|
+
if (style.pointerEvents === 'none') return false;
|
|
779
|
+
const rect = el.getBoundingClientRect();
|
|
780
|
+
return rect.width > 0 && rect.height > 0;
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
const isInteractable = (el) => isVisible(el) && !isDisabled(el);
|
|
784
|
+
|
|
785
|
+
const normalized = Array.isArray(targetLabels)
|
|
786
|
+
? targetLabels.map((label) => String(label || '').trim()).filter((label) => label)
|
|
787
|
+
: [];
|
|
788
|
+
const lowered = normalized.map((label) => label.toLowerCase());
|
|
789
|
+
if (lowered.length === 0) return '';
|
|
790
|
+
|
|
791
|
+
const menuSelectors = [
|
|
792
|
+
'[role="menu"]',
|
|
793
|
+
'[role="listbox"]',
|
|
794
|
+
'[aria-label*="tool" i]',
|
|
795
|
+
'[aria-label*="mode" i]',
|
|
796
|
+
'[aria-modal="true"]',
|
|
797
|
+
];
|
|
798
|
+
const menuRoots = Array.from(document.querySelectorAll(menuSelectors.join(','))).filter(isVisible);
|
|
799
|
+
if (menuRoots.length === 0) return '';
|
|
800
|
+
const seen = new Set();
|
|
801
|
+
|
|
802
|
+
for (const root of menuRoots) {
|
|
803
|
+
const candidates = Array.from(root.querySelectorAll('button, [role="menuitem"], [role="option"], [role="button"], a, li'));
|
|
804
|
+
for (const node of candidates) {
|
|
805
|
+
if (seen.has(node)) continue;
|
|
806
|
+
seen.add(node);
|
|
807
|
+
if (!isInteractable(node)) continue;
|
|
808
|
+
const text = (node.textContent || '').trim().toLowerCase();
|
|
809
|
+
const aria = (node.getAttribute('aria-label') || '').trim().toLowerCase();
|
|
810
|
+
if (!text && !aria) continue;
|
|
811
|
+
const combined = \`\${text} \${aria}\`.trim();
|
|
812
|
+
for (let index = 0; index < lowered.length; index += 1) {
|
|
813
|
+
const label = lowered[index];
|
|
814
|
+
if (label && combined.includes(label)) {
|
|
815
|
+
if (node instanceof HTMLElement) node.click();
|
|
816
|
+
return normalized[index];
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
return '';
|
|
823
|
+
})(${labelsJson})
|
|
824
|
+
`;
|
|
825
|
+
}
|
|
826
|
+
function clickGeminiConfirmButtonScript(labels) {
|
|
827
|
+
const labelsJson = JSON.stringify(labels);
|
|
828
|
+
return `
|
|
829
|
+
((targetLabels) => {
|
|
830
|
+
const isDisabled = (el) => {
|
|
831
|
+
if (!(el instanceof HTMLElement)) return true;
|
|
832
|
+
if ('disabled' in el && el.disabled) return true;
|
|
833
|
+
if (el.hasAttribute('disabled')) return true;
|
|
834
|
+
const ariaDisabled = (el.getAttribute('aria-disabled') || '').toLowerCase();
|
|
835
|
+
return ariaDisabled === 'true';
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
const isVisible = (el) => {
|
|
839
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
840
|
+
if (el.hidden || el.closest('[hidden]')) return false;
|
|
841
|
+
const ariaHidden = el.getAttribute('aria-hidden');
|
|
842
|
+
if (ariaHidden && ariaHidden.toLowerCase() === 'true') return false;
|
|
843
|
+
if (el.closest('[aria-hidden="true"]')) return false;
|
|
844
|
+
const style = window.getComputedStyle(el);
|
|
845
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
846
|
+
if (Number(style.opacity) === 0) return false;
|
|
847
|
+
if (style.pointerEvents === 'none') return false;
|
|
848
|
+
const rect = el.getBoundingClientRect();
|
|
849
|
+
return rect.width > 0 && rect.height > 0;
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
const isInteractable = (el) => isVisible(el) && !isDisabled(el);
|
|
853
|
+
|
|
854
|
+
const normalized = Array.isArray(targetLabels)
|
|
855
|
+
? targetLabels.map((label) => String(label || '').trim()).filter((label) => label)
|
|
856
|
+
: [];
|
|
857
|
+
const lowered = normalized.map((label) => label.toLowerCase());
|
|
858
|
+
if (lowered.length === 0) return '';
|
|
859
|
+
|
|
860
|
+
const dialogRoots = Array.from(document.querySelectorAll('[role="dialog"], [aria-modal="true"]')).filter(isVisible);
|
|
861
|
+
const mainRoot = document.querySelector('main');
|
|
862
|
+
const primaryRoots = [...dialogRoots, mainRoot].filter(Boolean).filter(isVisible);
|
|
863
|
+
const rootGroups = primaryRoots.length > 0 ? [primaryRoots, [document]] : [[document]];
|
|
864
|
+
const seen = new Set();
|
|
865
|
+
|
|
866
|
+
for (const roots of rootGroups) {
|
|
867
|
+
for (const root of roots) {
|
|
868
|
+
const candidates = Array.from(root.querySelectorAll('button, [role="button"]'));
|
|
869
|
+
for (const node of candidates) {
|
|
870
|
+
if (seen.has(node)) continue;
|
|
871
|
+
seen.add(node);
|
|
872
|
+
if (!isInteractable(node)) continue;
|
|
873
|
+
const text = (node.textContent || '').trim().toLowerCase();
|
|
874
|
+
const aria = (node.getAttribute('aria-label') || '').trim().toLowerCase();
|
|
875
|
+
if (!text && !aria) continue;
|
|
876
|
+
const combined = \`\${text} \${aria}\`.trim();
|
|
877
|
+
for (let index = 0; index < lowered.length; index += 1) {
|
|
878
|
+
const label = lowered[index];
|
|
879
|
+
if (label && combined.includes(label)) {
|
|
880
|
+
if (node instanceof HTMLElement) node.click();
|
|
881
|
+
return normalized[index];
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
return '';
|
|
889
|
+
})(${labelsJson})
|
|
890
|
+
`;
|
|
891
|
+
}
|
|
892
|
+
function getGeminiConversationListScript() {
|
|
893
|
+
return `
|
|
894
|
+
(() => {
|
|
895
|
+
const normalizeText = (value) => String(value || '').replace(/\\s+/g, ' ').trim();
|
|
896
|
+
const clampText = (value, maxLength) => {
|
|
897
|
+
const normalized = normalizeText(value);
|
|
898
|
+
if (!normalized) return '';
|
|
899
|
+
if (normalized.length <= maxLength) return normalized;
|
|
900
|
+
return normalized.slice(0, maxLength).trim();
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
const isVisible = (el) => {
|
|
904
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
905
|
+
if (el.hidden || el.closest('[hidden]')) return false;
|
|
906
|
+
const ariaHidden = el.getAttribute('aria-hidden');
|
|
907
|
+
if (ariaHidden && ariaHidden.toLowerCase() === 'true') return false;
|
|
908
|
+
if (el.closest('[aria-hidden="true"]')) return false;
|
|
909
|
+
const style = window.getComputedStyle(el);
|
|
910
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
911
|
+
if (Number(style.opacity) === 0) return false;
|
|
912
|
+
if (style.pointerEvents === 'none') return false;
|
|
913
|
+
const rect = el.getBoundingClientRect();
|
|
914
|
+
return rect.width > 0 && rect.height > 0;
|
|
915
|
+
};
|
|
916
|
+
|
|
917
|
+
const selector = 'a[href*="/app"]';
|
|
918
|
+
const navRoots = Array.from(document.querySelectorAll('nav, aside, [role="navigation"]'));
|
|
919
|
+
const rootsWithLinks = navRoots.filter((root) => root.querySelector(selector));
|
|
920
|
+
const roots = rootsWithLinks.length > 0 ? rootsWithLinks : [document];
|
|
921
|
+
|
|
922
|
+
const results = [];
|
|
923
|
+
const seen = new Set();
|
|
924
|
+
const maxLength = 200;
|
|
925
|
+
|
|
926
|
+
for (const root of roots) {
|
|
927
|
+
const anchors = Array.from(root.querySelectorAll(selector));
|
|
928
|
+
for (const anchor of anchors) {
|
|
929
|
+
if (!(anchor instanceof HTMLAnchorElement)) continue;
|
|
930
|
+
if (!isVisible(anchor)) continue;
|
|
931
|
+
const href = anchor.getAttribute('href') || '';
|
|
932
|
+
if (!href) continue;
|
|
933
|
+
let url = '';
|
|
934
|
+
try {
|
|
935
|
+
url = new URL(href, 'https://gemini.google.com').href;
|
|
936
|
+
} catch {
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
if (!url) continue;
|
|
940
|
+
const title = clampText(anchor.textContent || anchor.getAttribute('aria-label') || '', maxLength);
|
|
941
|
+
if (!title) continue;
|
|
942
|
+
const key = url + '::' + title;
|
|
943
|
+
if (seen.has(key)) continue;
|
|
944
|
+
seen.add(key);
|
|
945
|
+
results.push({ title, url });
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
return results;
|
|
950
|
+
})()
|
|
951
|
+
`;
|
|
952
|
+
}
|
|
953
|
+
function clickGeminiConversationByTitleScript(query) {
|
|
954
|
+
const normalizedQuery = normalizeGeminiTitle(query);
|
|
955
|
+
return `
|
|
956
|
+
((targetQuery) => {
|
|
957
|
+
const normalizeText = (value) => String(value || '').replace(/\\s+/g, ' ').trim().toLowerCase();
|
|
958
|
+
const isDisabled = (el) => {
|
|
959
|
+
if (!(el instanceof HTMLElement)) return true;
|
|
960
|
+
if ('disabled' in el && el.disabled) return true;
|
|
961
|
+
if (el.hasAttribute('disabled')) return true;
|
|
962
|
+
const ariaDisabled = (el.getAttribute('aria-disabled') || '').toLowerCase();
|
|
963
|
+
return ariaDisabled === 'true';
|
|
964
|
+
};
|
|
965
|
+
const isVisible = (el) => {
|
|
966
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
967
|
+
if (el.hidden || el.closest('[hidden]')) return false;
|
|
968
|
+
const ariaHidden = (el.getAttribute('aria-hidden') || '').toLowerCase();
|
|
969
|
+
if (ariaHidden === 'true' || el.closest('[aria-hidden="true"]')) return false;
|
|
970
|
+
const style = window.getComputedStyle(el);
|
|
971
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
972
|
+
if (Number(style.opacity) === 0 || style.pointerEvents === 'none') return false;
|
|
973
|
+
const rect = el.getBoundingClientRect();
|
|
974
|
+
return rect.width > 0 && rect.height > 0;
|
|
975
|
+
};
|
|
976
|
+
const selector = 'nav a[href*="/app"], aside a[href*="/app"], [role="navigation"] a[href*="/app"], a[href*="/app"]';
|
|
977
|
+
const anchors = Array.from(document.querySelectorAll(selector));
|
|
978
|
+
|
|
979
|
+
for (const anchor of anchors) {
|
|
980
|
+
if (!(anchor instanceof HTMLAnchorElement)) continue;
|
|
981
|
+
if (!isVisible(anchor)) continue;
|
|
982
|
+
if (isDisabled(anchor)) continue;
|
|
983
|
+
const title = normalizeText(anchor.textContent || anchor.getAttribute('aria-label') || '');
|
|
984
|
+
if (!title || !targetQuery) continue;
|
|
985
|
+
if (!title.includes(targetQuery)) continue;
|
|
986
|
+
anchor.click();
|
|
987
|
+
return true;
|
|
988
|
+
}
|
|
989
|
+
return false;
|
|
990
|
+
})(${JSON.stringify(normalizedQuery)})
|
|
991
|
+
`;
|
|
992
|
+
}
|
|
256
993
|
function currentUrlScript() {
|
|
257
994
|
return 'window.location.href';
|
|
258
995
|
}
|
|
@@ -274,6 +1011,40 @@ export async function ensureGeminiPage(page) {
|
|
|
274
1011
|
await page.wait(1);
|
|
275
1012
|
}
|
|
276
1013
|
}
|
|
1014
|
+
export async function getCurrentGeminiUrl(page) {
|
|
1015
|
+
await ensureGeminiPage(page);
|
|
1016
|
+
const url = await page.evaluate(currentUrlScript()).catch(() => '');
|
|
1017
|
+
if (typeof url === 'string' && url.trim())
|
|
1018
|
+
return url;
|
|
1019
|
+
return GEMINI_APP_URL;
|
|
1020
|
+
}
|
|
1021
|
+
export async function openGeminiToolsMenu(page) {
|
|
1022
|
+
await ensureGeminiPage(page);
|
|
1023
|
+
const opened = await page.evaluate(openGeminiToolsMenuScript());
|
|
1024
|
+
if (opened) {
|
|
1025
|
+
await page.wait(0.5);
|
|
1026
|
+
return true;
|
|
1027
|
+
}
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
export async function selectGeminiTool(page, labels) {
|
|
1031
|
+
await ensureGeminiPage(page);
|
|
1032
|
+
await openGeminiToolsMenu(page);
|
|
1033
|
+
const matched = await page.evaluate(selectGeminiToolScript(labels));
|
|
1034
|
+
return typeof matched === 'string' ? matched : '';
|
|
1035
|
+
}
|
|
1036
|
+
export async function waitForGeminiConfirmButton(page, labels, timeoutSeconds) {
|
|
1037
|
+
await ensureGeminiPage(page);
|
|
1038
|
+
const pollIntervalSeconds = 1;
|
|
1039
|
+
const maxPolls = Math.max(1, Math.ceil(timeoutSeconds / pollIntervalSeconds));
|
|
1040
|
+
for (let index = 0; index < maxPolls; index += 1) {
|
|
1041
|
+
await page.wait(index === 0 ? 0.5 : pollIntervalSeconds);
|
|
1042
|
+
const matched = await page.evaluate(clickGeminiConfirmButtonScript(labels));
|
|
1043
|
+
if (typeof matched === 'string' && matched)
|
|
1044
|
+
return matched;
|
|
1045
|
+
}
|
|
1046
|
+
return '';
|
|
1047
|
+
}
|
|
277
1048
|
export async function getGeminiPageState(page) {
|
|
278
1049
|
await ensureGeminiPage(page);
|
|
279
1050
|
return await page.evaluate(getStateScript());
|
|
@@ -287,24 +1058,690 @@ export async function startNewGeminiChat(page) {
|
|
|
287
1058
|
await page.wait(1);
|
|
288
1059
|
return action;
|
|
289
1060
|
}
|
|
290
|
-
export async function
|
|
1061
|
+
export async function getGeminiConversationList(page) {
|
|
1062
|
+
await ensureGeminiPage(page);
|
|
1063
|
+
const raw = await page.evaluate(getGeminiConversationListScript());
|
|
1064
|
+
if (!Array.isArray(raw))
|
|
1065
|
+
return [];
|
|
1066
|
+
return raw
|
|
1067
|
+
.filter((item) => item && typeof item.title === 'string' && typeof item.url === 'string')
|
|
1068
|
+
.map((item) => ({ Title: item.title, Url: item.url }));
|
|
1069
|
+
}
|
|
1070
|
+
export async function clickGeminiConversationByTitle(page, query) {
|
|
291
1071
|
await ensureGeminiPage(page);
|
|
292
|
-
const
|
|
1072
|
+
const normalizedQuery = normalizeGeminiTitle(query);
|
|
1073
|
+
if (!normalizedQuery)
|
|
1074
|
+
return false;
|
|
1075
|
+
const clicked = await page.evaluate(clickGeminiConversationByTitleScript(normalizedQuery));
|
|
1076
|
+
if (clicked)
|
|
1077
|
+
await page.wait(1);
|
|
1078
|
+
return !!clicked;
|
|
1079
|
+
}
|
|
1080
|
+
export async function getGeminiVisibleTurns(page) {
|
|
1081
|
+
const turns = await getGeminiStructuredTurns(page);
|
|
293
1082
|
if (Array.isArray(turns) && turns.length > 0)
|
|
294
1083
|
return turns;
|
|
295
1084
|
const lines = await getGeminiTranscriptLines(page);
|
|
296
1085
|
return lines.map((line) => ({ Role: 'System', Text: line }));
|
|
297
1086
|
}
|
|
1087
|
+
async function getGeminiStructuredTurns(page) {
|
|
1088
|
+
await ensureGeminiPage(page);
|
|
1089
|
+
const turns = collapseAdjacentGeminiTurns(await page.evaluate(getTurnsScript()));
|
|
1090
|
+
return Array.isArray(turns) ? turns : [];
|
|
1091
|
+
}
|
|
298
1092
|
export async function getGeminiTranscriptLines(page) {
|
|
299
1093
|
await ensureGeminiPage(page);
|
|
300
1094
|
return await page.evaluate(getTranscriptLinesScript());
|
|
301
1095
|
}
|
|
1096
|
+
export async function waitForGeminiTranscript(page, attempts = 5) {
|
|
1097
|
+
let lines = [];
|
|
1098
|
+
for (let index = 0; index < attempts; index += 1) {
|
|
1099
|
+
lines = await getGeminiTranscriptLines(page);
|
|
1100
|
+
if (lines.length > 0)
|
|
1101
|
+
return lines;
|
|
1102
|
+
if (index < attempts - 1)
|
|
1103
|
+
await page.wait(1);
|
|
1104
|
+
}
|
|
1105
|
+
return lines;
|
|
1106
|
+
}
|
|
1107
|
+
export async function getLatestGeminiAssistantResponse(page) {
|
|
1108
|
+
await ensureGeminiPage(page);
|
|
1109
|
+
const turns = await getGeminiVisibleTurns(page);
|
|
1110
|
+
const assistantTurn = [...turns].reverse().find((turn) => turn.Role === 'Assistant');
|
|
1111
|
+
if (assistantTurn?.Text) {
|
|
1112
|
+
return sanitizeGeminiResponseText(assistantTurn.Text, '');
|
|
1113
|
+
}
|
|
1114
|
+
const lines = await getGeminiTranscriptLines(page);
|
|
1115
|
+
return lines.join('\n').trim();
|
|
1116
|
+
}
|
|
1117
|
+
export async function readGeminiSnapshot(page) {
|
|
1118
|
+
await ensureGeminiPage(page);
|
|
1119
|
+
return await page.evaluate(readGeminiSnapshotScript());
|
|
1120
|
+
}
|
|
1121
|
+
function findLastUserTurnIndex(turns) {
|
|
1122
|
+
for (let index = turns.length - 1; index >= 0; index -= 1) {
|
|
1123
|
+
if (turns[index]?.Role === 'User')
|
|
1124
|
+
return index;
|
|
1125
|
+
}
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
function findLastUserTurn(turns) {
|
|
1129
|
+
const index = findLastUserTurnIndex(turns);
|
|
1130
|
+
return index === null ? null : turns[index] ?? null;
|
|
1131
|
+
}
|
|
1132
|
+
export async function waitForGeminiSubmission(page, before, timeoutSeconds) {
|
|
1133
|
+
const preSendAssistantCount = before.turns.filter((turn) => turn.Role === 'Assistant').length;
|
|
1134
|
+
const maxPolls = Math.max(1, Math.ceil(timeoutSeconds));
|
|
1135
|
+
for (let index = 0; index < maxPolls; index += 1) {
|
|
1136
|
+
await page.wait(index === 0 ? 0.5 : 1);
|
|
1137
|
+
const current = await readGeminiSnapshot(page);
|
|
1138
|
+
const structuredAppend = diffTrustedStructuredTurns(before, current);
|
|
1139
|
+
const transcriptDelta = diffTranscriptLines(before, current);
|
|
1140
|
+
if (structuredAppend.hasTrustedAppend && structuredAppend.hasNewUserTurn) {
|
|
1141
|
+
return {
|
|
1142
|
+
snapshot: current,
|
|
1143
|
+
preSendAssistantCount,
|
|
1144
|
+
userAnchorTurn: findLastUserTurn(current.turns),
|
|
1145
|
+
reason: 'user_turn',
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
if (!current.composerHasText && current.isGenerating) {
|
|
1149
|
+
return {
|
|
1150
|
+
snapshot: current,
|
|
1151
|
+
preSendAssistantCount,
|
|
1152
|
+
userAnchorTurn: findLastUserTurn(current.turns),
|
|
1153
|
+
reason: 'composer_generating',
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
// Transcript-only growth is noisy on /app root. When URL is available,
|
|
1157
|
+
// trust this signal only after Gemini has navigated into a concrete
|
|
1158
|
+
// conversation URL. (Keep backwards compatibility for mocked snapshots
|
|
1159
|
+
// that don't carry url.)
|
|
1160
|
+
const transcriptSubmissionAllowed = !current.url || isGeminiConversationUrl(String(current.url));
|
|
1161
|
+
if (!current.composerHasText && transcriptDelta.length > 0 && transcriptSubmissionAllowed) {
|
|
1162
|
+
return {
|
|
1163
|
+
snapshot: current,
|
|
1164
|
+
preSendAssistantCount,
|
|
1165
|
+
userAnchorTurn: findLastUserTurn(current.turns),
|
|
1166
|
+
reason: 'composer_transcript',
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return null;
|
|
1171
|
+
}
|
|
302
1172
|
export async function sendGeminiMessage(page, text) {
|
|
303
1173
|
await ensureGeminiPage(page);
|
|
304
|
-
|
|
1174
|
+
let prepared;
|
|
1175
|
+
for (let attempt = 0; attempt < GEMINI_COMPOSER_PREPARE_ATTEMPTS; attempt += 1) {
|
|
1176
|
+
prepared = await page.evaluate(prepareComposerScript());
|
|
1177
|
+
if (prepared?.ok)
|
|
1178
|
+
break;
|
|
1179
|
+
if (attempt < GEMINI_COMPOSER_PREPARE_ATTEMPTS - 1)
|
|
1180
|
+
await page.wait(GEMINI_COMPOSER_PREPARE_WAIT_SECONDS);
|
|
1181
|
+
}
|
|
1182
|
+
if (!prepared?.ok) {
|
|
1183
|
+
throw new CommandExecutionError(prepared?.reason || 'Could not find Gemini composer');
|
|
1184
|
+
}
|
|
1185
|
+
let hasText = false;
|
|
1186
|
+
if (page.nativeType) {
|
|
1187
|
+
try {
|
|
1188
|
+
await page.nativeType(text);
|
|
1189
|
+
await page.wait(0.2);
|
|
1190
|
+
const nativeState = await page.evaluate(composerHasTextScript());
|
|
1191
|
+
hasText = !!nativeState?.hasText;
|
|
1192
|
+
}
|
|
1193
|
+
catch { }
|
|
1194
|
+
}
|
|
1195
|
+
if (!hasText) {
|
|
1196
|
+
const fallbackState = await page.evaluate(insertComposerTextFallbackScript(text));
|
|
1197
|
+
hasText = !!fallbackState?.hasText;
|
|
1198
|
+
}
|
|
1199
|
+
if (!hasText) {
|
|
1200
|
+
throw new CommandExecutionError('Failed to insert text into Gemini composer');
|
|
1201
|
+
}
|
|
1202
|
+
const submitAction = await page.evaluate(submitComposerScript());
|
|
1203
|
+
if (submitAction === 'button') {
|
|
1204
|
+
await page.wait(1);
|
|
1205
|
+
return 'button';
|
|
1206
|
+
}
|
|
1207
|
+
if (page.nativeKeyPress) {
|
|
1208
|
+
try {
|
|
1209
|
+
await page.nativeKeyPress('Enter');
|
|
1210
|
+
}
|
|
1211
|
+
catch {
|
|
1212
|
+
await page.evaluate(dispatchComposerEnterScript());
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
else {
|
|
1216
|
+
await page.evaluate(dispatchComposerEnterScript());
|
|
1217
|
+
}
|
|
305
1218
|
await page.wait(1);
|
|
306
|
-
return
|
|
1219
|
+
return 'enter';
|
|
1220
|
+
}
|
|
1221
|
+
function normalizeGeminiExportUrls(value) {
|
|
1222
|
+
if (!Array.isArray(value))
|
|
1223
|
+
return [];
|
|
1224
|
+
const seen = new Set();
|
|
1225
|
+
const urls = [];
|
|
1226
|
+
for (const item of value) {
|
|
1227
|
+
const raw = String(item ?? '').trim();
|
|
1228
|
+
if (!raw || seen.has(raw))
|
|
1229
|
+
continue;
|
|
1230
|
+
seen.add(raw);
|
|
1231
|
+
urls.push(raw);
|
|
1232
|
+
}
|
|
1233
|
+
return urls;
|
|
1234
|
+
}
|
|
1235
|
+
export function pickGeminiDeepResearchExportUrl(rawUrls, currentUrl) {
|
|
1236
|
+
let bestScore = -Infinity;
|
|
1237
|
+
let bestUrl = '';
|
|
1238
|
+
let bestSource = 'none';
|
|
1239
|
+
const sourceWeight = {
|
|
1240
|
+
fetch: 50,
|
|
1241
|
+
xhr: 45,
|
|
1242
|
+
'fetch-body': 72,
|
|
1243
|
+
'xhr-body': 72,
|
|
1244
|
+
'fetch-body-docs-id': 95,
|
|
1245
|
+
'xhr-body-docs-id': 95,
|
|
1246
|
+
open: 55,
|
|
1247
|
+
anchor: 55,
|
|
1248
|
+
performance: 35,
|
|
1249
|
+
};
|
|
1250
|
+
for (const rawEntry of rawUrls) {
|
|
1251
|
+
const match = rawEntry.match(/^([a-z-]+)::(.+)$/i);
|
|
1252
|
+
const sourceKey = (match?.[1] ?? 'performance').toLowerCase();
|
|
1253
|
+
const rawUrl = (match?.[2] ?? rawEntry).trim();
|
|
1254
|
+
if (!rawUrl)
|
|
1255
|
+
continue;
|
|
1256
|
+
let parsedUrl = rawUrl;
|
|
1257
|
+
let isBlob = false;
|
|
1258
|
+
if (rawUrl.startsWith('blob:')) {
|
|
1259
|
+
isBlob = true;
|
|
1260
|
+
}
|
|
1261
|
+
else {
|
|
1262
|
+
try {
|
|
1263
|
+
parsedUrl = new URL(rawUrl, currentUrl).href;
|
|
1264
|
+
}
|
|
1265
|
+
catch {
|
|
1266
|
+
continue;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
if (!isBlob) {
|
|
1270
|
+
try {
|
|
1271
|
+
const parsed = new URL(parsedUrl);
|
|
1272
|
+
if (!['http:', 'https:'].includes(parsed.protocol))
|
|
1273
|
+
continue;
|
|
1274
|
+
}
|
|
1275
|
+
catch {
|
|
1276
|
+
continue;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
const hasMarkdownSignal = /\.md(?:$|[?#])/i.test(parsedUrl) || /markdown/i.test(parsedUrl);
|
|
1280
|
+
const hasExportSignal = /export|download|attachment|file|save-report/i.test(parsedUrl);
|
|
1281
|
+
const isGoogleDocUrl = /docs\.google\.com\/document\//i.test(parsedUrl);
|
|
1282
|
+
const isGoogleSheetUrl = /docs\.google\.com\/spreadsheets\//i.test(parsedUrl);
|
|
1283
|
+
const isNoiseEndpoint = /cspreport|allowlist|gen_204|telemetry|metrics|analytics|doubleclick|logging|collect|favicon/i.test(parsedUrl);
|
|
1284
|
+
let score = sourceWeight[sourceKey] ?? 20;
|
|
1285
|
+
if (hasMarkdownSignal)
|
|
1286
|
+
score += 45;
|
|
1287
|
+
if (hasExportSignal)
|
|
1288
|
+
score += 25;
|
|
1289
|
+
if (isGoogleDocUrl)
|
|
1290
|
+
score += 100;
|
|
1291
|
+
if (isGoogleSheetUrl)
|
|
1292
|
+
score -= 160;
|
|
1293
|
+
if (/gemini\.google\.com\/app\//i.test(parsedUrl))
|
|
1294
|
+
score -= 60;
|
|
1295
|
+
if (/googleapis\.com|gstatic\.com|doubleclick\.net|google-analytics/i.test(parsedUrl))
|
|
1296
|
+
score -= 40;
|
|
1297
|
+
if (!hasMarkdownSignal && !hasExportSignal && !isBlob)
|
|
1298
|
+
score -= 40;
|
|
1299
|
+
if (isNoiseEndpoint)
|
|
1300
|
+
score -= 120;
|
|
1301
|
+
if (parsedUrl === currentUrl)
|
|
1302
|
+
score -= 80;
|
|
1303
|
+
if (isBlob)
|
|
1304
|
+
score += 25;
|
|
1305
|
+
if (score > bestScore) {
|
|
1306
|
+
bestScore = score;
|
|
1307
|
+
bestUrl = parsedUrl;
|
|
1308
|
+
if (isBlob)
|
|
1309
|
+
bestSource = 'blob';
|
|
1310
|
+
else if (sourceKey === 'open')
|
|
1311
|
+
bestSource = 'window-open';
|
|
1312
|
+
else if (sourceKey === 'anchor')
|
|
1313
|
+
bestSource = 'anchor';
|
|
1314
|
+
else if (sourceKey === 'performance')
|
|
1315
|
+
bestSource = 'performance';
|
|
1316
|
+
else
|
|
1317
|
+
bestSource = 'network';
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
if (!bestUrl || bestScore < 60) {
|
|
1321
|
+
return { url: '', source: 'none' };
|
|
1322
|
+
}
|
|
1323
|
+
return { url: bestUrl, source: bestSource };
|
|
1324
|
+
}
|
|
1325
|
+
function exportGeminiDeepResearchReportScript(maxWaitMs) {
|
|
1326
|
+
return `
|
|
1327
|
+
(async () => {
|
|
1328
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1329
|
+
const labels = {
|
|
1330
|
+
actionMenu: ['open menu for conversation actions', 'conversation actions', '会话操作'],
|
|
1331
|
+
share: ['share & export', 'share and export', 'share/export', '分享与导出', '分享和导出', '分享并导出', '共享和导出'],
|
|
1332
|
+
shareConversation: ['share conversation', '分享会话', '分享对话'],
|
|
1333
|
+
export: ['export', '导出'],
|
|
1334
|
+
exportDocs: ['export to docs', 'export to google docs', 'export to doc', '导出到 docs', '导出到文档', '导出到 google docs'],
|
|
1335
|
+
};
|
|
1336
|
+
|
|
1337
|
+
const recorderKey = '__opencliGeminiExportUrls';
|
|
1338
|
+
const patchedKey = '__opencliGeminiExportPatched';
|
|
1339
|
+
const trace = [];
|
|
1340
|
+
const tracePush = (step, detail = '') => {
|
|
1341
|
+
const entry = detail ? step + ':' + detail : step;
|
|
1342
|
+
trace.push(entry);
|
|
1343
|
+
if (trace.length > 80) trace.shift();
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1346
|
+
const normalize = (value) => (value || '').replace(/\\s+/g, ' ').trim().toLowerCase();
|
|
1347
|
+
const normalizeLabels = (values) => {
|
|
1348
|
+
if (!Array.isArray(values)) return [];
|
|
1349
|
+
return values.map((value) => normalize(value)).filter(Boolean);
|
|
1350
|
+
};
|
|
1351
|
+
const includesAny = (value, candidates) => {
|
|
1352
|
+
const text = normalize(value);
|
|
1353
|
+
if (!text) return false;
|
|
1354
|
+
return candidates.some((candidate) => text.includes(candidate));
|
|
1355
|
+
};
|
|
1356
|
+
const labelsNormalized = {
|
|
1357
|
+
actionMenu: normalizeLabels(labels.actionMenu),
|
|
1358
|
+
share: normalizeLabels(labels.share),
|
|
1359
|
+
shareConversation: normalizeLabels(labels.shareConversation),
|
|
1360
|
+
export: normalizeLabels(labels.export),
|
|
1361
|
+
exportDocs: normalizeLabels(labels.exportDocs),
|
|
1362
|
+
};
|
|
1363
|
+
|
|
1364
|
+
const queryAllDeep = (roots, selector) => {
|
|
1365
|
+
const seed = Array.isArray(roots) && roots.length > 0 ? roots : [document];
|
|
1366
|
+
const seenScopes = new Set();
|
|
1367
|
+
const seenElements = new Set();
|
|
1368
|
+
const out = [];
|
|
1369
|
+
const queue = [...seed];
|
|
1370
|
+
while (queue.length > 0) {
|
|
1371
|
+
const scope = queue.shift();
|
|
1372
|
+
const isValidScope = scope === document
|
|
1373
|
+
|| scope instanceof Document
|
|
1374
|
+
|| scope instanceof Element
|
|
1375
|
+
|| scope instanceof ShadowRoot;
|
|
1376
|
+
if (!isValidScope || seenScopes.has(scope)) continue;
|
|
1377
|
+
seenScopes.add(scope);
|
|
1378
|
+
|
|
1379
|
+
let nodes = [];
|
|
1380
|
+
try {
|
|
1381
|
+
nodes = Array.from(scope.querySelectorAll(selector));
|
|
1382
|
+
} catch {}
|
|
1383
|
+
|
|
1384
|
+
for (const node of nodes) {
|
|
1385
|
+
if (!(node instanceof Element)) continue;
|
|
1386
|
+
if (!seenElements.has(node)) {
|
|
1387
|
+
seenElements.add(node);
|
|
1388
|
+
out.push(node);
|
|
1389
|
+
}
|
|
1390
|
+
if (node.shadowRoot) queue.push(node.shadowRoot);
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
let descendants = [];
|
|
1394
|
+
try {
|
|
1395
|
+
descendants = Array.from(scope.querySelectorAll('*'));
|
|
1396
|
+
} catch {}
|
|
1397
|
+
for (const child of descendants) {
|
|
1398
|
+
if (child instanceof Element && child.shadowRoot) queue.push(child.shadowRoot);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
return out;
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
const isVisible = (el) => {
|
|
1405
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
1406
|
+
if (el.hidden || el.closest('[hidden]')) return false;
|
|
1407
|
+
const ariaHidden = (el.getAttribute('aria-hidden') || '').toLowerCase();
|
|
1408
|
+
if (ariaHidden === 'true' || el.closest('[aria-hidden="true"]')) return false;
|
|
1409
|
+
const style = window.getComputedStyle(el);
|
|
1410
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
1411
|
+
if (Number(style.opacity) === 0 || style.pointerEvents === 'none') return false;
|
|
1412
|
+
const rect = el.getBoundingClientRect();
|
|
1413
|
+
return rect.width > 0 && rect.height > 0;
|
|
1414
|
+
};
|
|
1415
|
+
const isDisabled = (el) => {
|
|
1416
|
+
if (!(el instanceof HTMLElement)) return true;
|
|
1417
|
+
if ('disabled' in el && el.disabled) return true;
|
|
1418
|
+
if (el.hasAttribute('disabled')) return true;
|
|
1419
|
+
return (el.getAttribute('aria-disabled') || '').toLowerCase() === 'true';
|
|
1420
|
+
};
|
|
1421
|
+
const isInteractable = (el) => isVisible(el) && !isDisabled(el);
|
|
1422
|
+
const textOf = (node) => [
|
|
1423
|
+
node?.textContent || '',
|
|
1424
|
+
node instanceof HTMLElement ? (node.innerText || '') : '',
|
|
1425
|
+
node?.getAttribute?.('aria-label') || '',
|
|
1426
|
+
node?.getAttribute?.('title') || '',
|
|
1427
|
+
node?.getAttribute?.('data-tooltip') || '',
|
|
1428
|
+
node?.getAttribute?.('mattooltip') || '',
|
|
1429
|
+
].join(' ');
|
|
1430
|
+
const hasTokens = (value, tokens) => {
|
|
1431
|
+
const normalized = normalize(value);
|
|
1432
|
+
if (!normalized) return false;
|
|
1433
|
+
return tokens.every((token) => normalized.includes(token));
|
|
1434
|
+
};
|
|
1435
|
+
const isKindMatch = (kind, combined, targetLabels) => {
|
|
1436
|
+
if (includesAny(combined, targetLabels)) return true;
|
|
1437
|
+
if (kind === 'share') return hasTokens(combined, ['share', 'export']) || hasTokens(combined, ['分享', '导出']);
|
|
1438
|
+
if (kind === 'export') return hasTokens(combined, ['export']) || hasTokens(combined, ['导出']);
|
|
1439
|
+
if (kind === 'export-docs') {
|
|
1440
|
+
return hasTokens(combined, ['export', 'docs'])
|
|
1441
|
+
|| hasTokens(combined, ['导出', '文档'])
|
|
1442
|
+
|| hasTokens(combined, ['导出', 'docs']);
|
|
1443
|
+
}
|
|
1444
|
+
if (kind === 'action-menu') {
|
|
1445
|
+
return hasTokens(combined, ['conversation', 'action']) || hasTokens(combined, ['会话', '操作']);
|
|
1446
|
+
}
|
|
1447
|
+
return false;
|
|
1448
|
+
};
|
|
1449
|
+
const triggerClick = (node) => {
|
|
1450
|
+
if (!(node instanceof HTMLElement)) return false;
|
|
1451
|
+
try { node.scrollIntoView({ block: 'center', inline: 'center' }); } catch {}
|
|
1452
|
+
try { node.focus({ preventScroll: true }); } catch {}
|
|
1453
|
+
try {
|
|
1454
|
+
const EventCtor = window.PointerEvent || window.MouseEvent;
|
|
1455
|
+
node.dispatchEvent(new EventCtor('pointerdown', { bubbles: true, cancelable: true, composed: true, button: 0 }));
|
|
1456
|
+
} catch {}
|
|
1457
|
+
try { node.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, composed: true, button: 0 })); } catch {}
|
|
1458
|
+
try { node.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true, composed: true, button: 0 })); } catch {}
|
|
1459
|
+
try { node.click(); } catch { return false; }
|
|
1460
|
+
return true;
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
const ensureRecorder = () => {
|
|
1464
|
+
if (!Array.isArray(window[recorderKey])) window[recorderKey] = [];
|
|
1465
|
+
const push = (prefix, raw) => {
|
|
1466
|
+
const url = String(raw || '').trim();
|
|
1467
|
+
if (!url) return;
|
|
1468
|
+
window[recorderKey].push(prefix + '::' + url);
|
|
1469
|
+
};
|
|
1470
|
+
const extractUrlsFromText = (rawText) => {
|
|
1471
|
+
const text = String(rawText || '');
|
|
1472
|
+
const urls = [];
|
|
1473
|
+
const direct = text.match(/https?:\\/\\/[^\\s"'<>\\\\]+/g) || [];
|
|
1474
|
+
urls.push(...direct);
|
|
1475
|
+
const escaped = text.match(/https?:\\\\\\/\\\\\\/[^\\s"'<>]+/g) || [];
|
|
1476
|
+
for (const item of escaped) {
|
|
1477
|
+
urls.push(
|
|
1478
|
+
item
|
|
1479
|
+
.split('\\\\/').join('/')
|
|
1480
|
+
.split('\\\\u003d').join('=')
|
|
1481
|
+
.split('\\\\u0026').join('&'),
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
return Array.from(new Set(urls.map((value) => String(value || '').trim()).filter(Boolean)));
|
|
1485
|
+
};
|
|
1486
|
+
const extractDocsIdsFromText = (rawText) => {
|
|
1487
|
+
const text = String(rawText || '');
|
|
1488
|
+
const ids = [];
|
|
1489
|
+
const patterns = [
|
|
1490
|
+
/"id"\\s*:\\s*"([a-zA-Z0-9_-]{15,})"/g,
|
|
1491
|
+
/'id'\\s*:\\s*'([a-zA-Z0-9_-]{15,})'/g,
|
|
1492
|
+
];
|
|
1493
|
+
for (const pattern of patterns) {
|
|
1494
|
+
let match;
|
|
1495
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
1496
|
+
const docId = String(match[1] || '').trim();
|
|
1497
|
+
if (docId) ids.push(docId);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
return Array.from(new Set(ids));
|
|
1501
|
+
};
|
|
1502
|
+
const docsUrlFromId = (id) => {
|
|
1503
|
+
const docId = String(id || '').trim();
|
|
1504
|
+
if (!/^[a-zA-Z0-9_-]{15,}$/.test(docId)) return '';
|
|
1505
|
+
return 'https://docs.google.com/document/d/' + docId + '/edit';
|
|
1506
|
+
};
|
|
1507
|
+
const isDriveDocCreateRequest = (url) => /\\/upload\\/drive\\/v3\\/files/i.test(String(url || ''));
|
|
1508
|
+
|
|
1509
|
+
if (window[patchedKey]) return push;
|
|
1510
|
+
window[patchedKey] = true;
|
|
1511
|
+
|
|
1512
|
+
const originalFetch = window.fetch.bind(window);
|
|
1513
|
+
window.fetch = (...args) => {
|
|
1514
|
+
let reqUrl = '';
|
|
1515
|
+
try {
|
|
1516
|
+
const input = args[0];
|
|
1517
|
+
reqUrl = typeof input === 'string' ? input : (input && input.url) || '';
|
|
1518
|
+
push('fetch', reqUrl);
|
|
1519
|
+
} catch {}
|
|
1520
|
+
return originalFetch(...args).then((response) => {
|
|
1521
|
+
try {
|
|
1522
|
+
response.clone().text().then((text) => {
|
|
1523
|
+
const embeddedUrls = extractUrlsFromText(text);
|
|
1524
|
+
for (const embeddedUrl of embeddedUrls) push('fetch-body', embeddedUrl);
|
|
1525
|
+
if (isDriveDocCreateRequest(reqUrl)) {
|
|
1526
|
+
const docIds = extractDocsIdsFromText(text);
|
|
1527
|
+
for (const docId of docIds) {
|
|
1528
|
+
const docUrl = docsUrlFromId(docId);
|
|
1529
|
+
if (docUrl) push('fetch-body-docs-id', docUrl);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
}).catch(() => {});
|
|
1533
|
+
} catch {}
|
|
1534
|
+
return response;
|
|
1535
|
+
});
|
|
1536
|
+
};
|
|
1537
|
+
|
|
1538
|
+
const originalXhrOpen = XMLHttpRequest.prototype.open;
|
|
1539
|
+
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
|
1540
|
+
try { push('xhr', url); } catch {}
|
|
1541
|
+
try { this.__opencliReqUrl = String(url || ''); } catch {}
|
|
1542
|
+
return originalXhrOpen.call(this, method, url, ...rest);
|
|
1543
|
+
};
|
|
1544
|
+
const originalXhrSend = XMLHttpRequest.prototype.send;
|
|
1545
|
+
XMLHttpRequest.prototype.send = function(...args) {
|
|
1546
|
+
try {
|
|
1547
|
+
this.addEventListener('load', () => {
|
|
1548
|
+
try {
|
|
1549
|
+
const embeddedUrls = extractUrlsFromText(this.responseText || '');
|
|
1550
|
+
for (const embeddedUrl of embeddedUrls) push('xhr-body', embeddedUrl);
|
|
1551
|
+
const reqUrl = String(this.__opencliReqUrl || '');
|
|
1552
|
+
if (isDriveDocCreateRequest(reqUrl)) {
|
|
1553
|
+
const docIds = extractDocsIdsFromText(this.responseText || '');
|
|
1554
|
+
for (const docId of docIds) {
|
|
1555
|
+
const docUrl = docsUrlFromId(docId);
|
|
1556
|
+
if (docUrl) push('xhr-body-docs-id', docUrl);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
} catch {}
|
|
1560
|
+
});
|
|
1561
|
+
} catch {}
|
|
1562
|
+
return originalXhrSend.apply(this, args);
|
|
1563
|
+
};
|
|
1564
|
+
|
|
1565
|
+
const originalOpen = window.open.bind(window);
|
|
1566
|
+
window.open = (...args) => {
|
|
1567
|
+
try { push('open', args[0]); } catch {}
|
|
1568
|
+
return originalOpen(...args);
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
const originalAnchorClick = HTMLAnchorElement.prototype.click;
|
|
1572
|
+
HTMLAnchorElement.prototype.click = function(...args) {
|
|
1573
|
+
try { push('anchor', this.href || this.getAttribute('href')); } catch {}
|
|
1574
|
+
return originalAnchorClick.apply(this, args);
|
|
1575
|
+
};
|
|
1576
|
+
|
|
1577
|
+
return push;
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
const pushUrl = ensureRecorder();
|
|
1581
|
+
const collectUrls = () => {
|
|
1582
|
+
try {
|
|
1583
|
+
const entries = performance.getEntriesByType('resource');
|
|
1584
|
+
for (const entry of entries) {
|
|
1585
|
+
if (!entry || !entry.name) continue;
|
|
1586
|
+
pushUrl('performance', entry.name);
|
|
1587
|
+
}
|
|
1588
|
+
} catch {}
|
|
1589
|
+
try {
|
|
1590
|
+
const anchors = queryAllDeep([document], 'a[href]');
|
|
1591
|
+
for (const anchor of anchors) {
|
|
1592
|
+
const href = anchor.getAttribute('href') || '';
|
|
1593
|
+
if (!href) continue;
|
|
1594
|
+
if (/docs\\.google\\.com\\/document\\//i.test(href)) pushUrl('anchor', href);
|
|
1595
|
+
}
|
|
1596
|
+
} catch {}
|
|
1597
|
+
const all = Array.isArray(window[recorderKey]) ? window[recorderKey] : [];
|
|
1598
|
+
return Array.from(new Set(all.map((value) => String(value || '').trim()).filter(Boolean)));
|
|
1599
|
+
};
|
|
1600
|
+
|
|
1601
|
+
const clickByLabels = (kind, targetLabels, roots) => {
|
|
1602
|
+
const allRoots = Array.isArray(roots) && roots.length > 0 ? roots : [document];
|
|
1603
|
+
const selector = 'button, [role="button"], [role="menuitem"], [role="option"], a, li';
|
|
1604
|
+
|
|
1605
|
+
for (const root of allRoots) {
|
|
1606
|
+
if (!(root instanceof Document || root instanceof Element)) continue;
|
|
1607
|
+
let nodes = [];
|
|
1608
|
+
try {
|
|
1609
|
+
nodes = Array.from(root.querySelectorAll(selector));
|
|
1610
|
+
} catch {
|
|
1611
|
+
continue;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
for (const node of nodes) {
|
|
1615
|
+
if (!isInteractable(node)) continue;
|
|
1616
|
+
const combined = normalize(textOf(node));
|
|
1617
|
+
if (!combined) continue;
|
|
1618
|
+
if (!isKindMatch(kind, combined, targetLabels)) continue;
|
|
1619
|
+
if (triggerClick(node)) {
|
|
1620
|
+
const clickedText = (textOf(node) || targetLabels[0] || '').trim();
|
|
1621
|
+
tracePush('clicked', kind + '|' + clickedText.slice(0, 120));
|
|
1622
|
+
return clickedText;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
tracePush('miss', kind);
|
|
1627
|
+
return '';
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
const getDialogRoots = () =>
|
|
1631
|
+
queryAllDeep([document], '[role="dialog"], [aria-modal="true"], [role="menu"], [role="listbox"]')
|
|
1632
|
+
.filter((node) => isVisible(node));
|
|
1633
|
+
const buildRoots = () => {
|
|
1634
|
+
const dialogRoots = getDialogRoots();
|
|
1635
|
+
if (dialogRoots.length > 0) return [...dialogRoots, document];
|
|
1636
|
+
return [document];
|
|
1637
|
+
};
|
|
1638
|
+
const clickWithRetry = async (kind, targetLabels, attempts, delayMs, includeDialogs = true) => {
|
|
1639
|
+
for (let index = 0; index < attempts; index += 1) {
|
|
1640
|
+
const roots = includeDialogs ? buildRoots() : [document];
|
|
1641
|
+
const clicked = clickByLabels(kind, targetLabels, roots);
|
|
1642
|
+
if (clicked) return clicked;
|
|
1643
|
+
await sleep(delayMs);
|
|
1644
|
+
}
|
|
1645
|
+
return '';
|
|
1646
|
+
};
|
|
1647
|
+
|
|
1648
|
+
tracePush('start', window.location.href);
|
|
1649
|
+
let exportDocsBtn = await clickWithRetry('export-docs', labelsNormalized.exportDocs, 2, 250, true);
|
|
1650
|
+
let share = '';
|
|
1651
|
+
if (!exportDocsBtn) {
|
|
1652
|
+
share = await clickWithRetry('share', labelsNormalized.share, 4, 280, true);
|
|
1653
|
+
}
|
|
1654
|
+
if (!exportDocsBtn && !share) {
|
|
1655
|
+
await clickWithRetry('action-menu', labelsNormalized.actionMenu, 2, 250, false);
|
|
1656
|
+
await clickWithRetry('share-conversation', labelsNormalized.shareConversation, 2, 250, true);
|
|
1657
|
+
share = await clickWithRetry('share', labelsNormalized.share, 4, 280, true);
|
|
1658
|
+
}
|
|
1659
|
+
if (!exportDocsBtn) {
|
|
1660
|
+
await sleep(350);
|
|
1661
|
+
exportDocsBtn = await clickWithRetry('export-docs', labelsNormalized.exportDocs, 8, 280, true);
|
|
1662
|
+
}
|
|
1663
|
+
if (!exportDocsBtn) {
|
|
1664
|
+
const exportEntry = await clickWithRetry('export', labelsNormalized.export, 2, 220, true);
|
|
1665
|
+
if (exportEntry) {
|
|
1666
|
+
await sleep(240);
|
|
1667
|
+
exportDocsBtn = await clickWithRetry('export-docs', labelsNormalized.exportDocs, 6, 280, true);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
if (!share && !exportDocsBtn) {
|
|
1672
|
+
return { ok: false, step: 'share', currentUrl: window.location.href, trace, urls: collectUrls() };
|
|
1673
|
+
}
|
|
1674
|
+
if (!exportDocsBtn) {
|
|
1675
|
+
return { ok: false, step: 'export-docs', currentUrl: window.location.href, share, trace, urls: collectUrls() };
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
const deadline = Date.now() + ${Math.max(5000, Math.min(maxWaitMs, 180000))};
|
|
1679
|
+
while (Date.now() < deadline) {
|
|
1680
|
+
const urls = collectUrls();
|
|
1681
|
+
const hasDocsSignal = urls.some((value) => /docs\\.google\\.com\\/document\\//i.test(String(value || '')));
|
|
1682
|
+
const sameTabDocs = /docs\\.google\\.com\\/document\\//i.test(window.location.href || '');
|
|
1683
|
+
if (hasDocsSignal) {
|
|
1684
|
+
return { ok: true, step: 'done', currentUrl: window.location.href, share, exportDocs: exportDocsBtn, trace, urls };
|
|
1685
|
+
}
|
|
1686
|
+
if (sameTabDocs) {
|
|
1687
|
+
urls.push('open::' + window.location.href);
|
|
1688
|
+
return { ok: true, step: 'same-tab-docs', currentUrl: window.location.href, share, exportDocs: exportDocsBtn, trace, urls };
|
|
1689
|
+
}
|
|
1690
|
+
await sleep(300);
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
return { ok: true, step: 'timeout', currentUrl: window.location.href, share, exportDocs: exportDocsBtn, trace, urls: collectUrls() };
|
|
1694
|
+
})()
|
|
1695
|
+
`;
|
|
1696
|
+
}
|
|
1697
|
+
function extractDocsUrlFromTabs(tabs) {
|
|
1698
|
+
if (!Array.isArray(tabs))
|
|
1699
|
+
return '';
|
|
1700
|
+
for (const tab of tabs) {
|
|
1701
|
+
if (!tab || typeof tab !== 'object')
|
|
1702
|
+
continue;
|
|
1703
|
+
const url = String(tab.url ?? '').trim();
|
|
1704
|
+
if (/^https:\/\/docs\.google\.com\/document\//i.test(url))
|
|
1705
|
+
return url;
|
|
1706
|
+
}
|
|
1707
|
+
return '';
|
|
307
1708
|
}
|
|
1709
|
+
export async function exportGeminiDeepResearchReport(page, timeoutSeconds = 120) {
|
|
1710
|
+
await ensureGeminiPage(page);
|
|
1711
|
+
const timeoutMs = Math.max(1, timeoutSeconds) * 1000;
|
|
1712
|
+
const tabsBefore = await page.tabs().catch(() => []);
|
|
1713
|
+
const exportScript = exportGeminiDeepResearchReportScript(timeoutMs);
|
|
1714
|
+
const raw = await page.evaluate(exportScript).catch(() => null);
|
|
1715
|
+
const tabsAfter = await page.tabs().catch(() => []);
|
|
1716
|
+
const docsUrlFromTabs = extractDocsUrlFromTabs(tabsAfter) || extractDocsUrlFromTabs(tabsBefore);
|
|
1717
|
+
if (docsUrlFromTabs) {
|
|
1718
|
+
return { url: docsUrlFromTabs, source: 'tab' };
|
|
1719
|
+
}
|
|
1720
|
+
const docsUrlFromCurrent = typeof raw?.currentUrl === 'string' && /^https:\/\/docs\.google\.com\/document\//i.test(raw.currentUrl)
|
|
1721
|
+
? raw.currentUrl
|
|
1722
|
+
: '';
|
|
1723
|
+
if (docsUrlFromCurrent) {
|
|
1724
|
+
return { url: docsUrlFromCurrent, source: 'window-open' };
|
|
1725
|
+
}
|
|
1726
|
+
const urls = normalizeGeminiExportUrls(raw?.urls);
|
|
1727
|
+
const currentUrl = typeof raw?.currentUrl === 'string' && raw.currentUrl
|
|
1728
|
+
? raw.currentUrl
|
|
1729
|
+
: await getCurrentGeminiUrl(page);
|
|
1730
|
+
return pickGeminiDeepResearchExportUrl(urls, currentUrl);
|
|
1731
|
+
}
|
|
1732
|
+
export const __test__ = {
|
|
1733
|
+
GEMINI_COMPOSER_SELECTORS,
|
|
1734
|
+
GEMINI_COMPOSER_MARKER_ATTR,
|
|
1735
|
+
collapseAdjacentGeminiTurns,
|
|
1736
|
+
clickNewChatScript,
|
|
1737
|
+
diffTranscriptLines,
|
|
1738
|
+
diffTrustedStructuredTurns,
|
|
1739
|
+
hasGeminiTurnPrefix,
|
|
1740
|
+
readGeminiSnapshot,
|
|
1741
|
+
readGeminiSnapshotScript,
|
|
1742
|
+
submitComposerScript,
|
|
1743
|
+
insertComposerTextFallbackScript,
|
|
1744
|
+
};
|
|
308
1745
|
export async function getGeminiVisibleImageUrls(page) {
|
|
309
1746
|
await ensureGeminiPage(page);
|
|
310
1747
|
return await page.evaluate(`
|
|
@@ -429,35 +1866,77 @@ export async function exportGeminiImages(page, urls) {
|
|
|
429
1866
|
})(${urlsJson})
|
|
430
1867
|
`);
|
|
431
1868
|
}
|
|
432
|
-
export async function waitForGeminiResponse(page,
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
return
|
|
441
|
-
const
|
|
442
|
-
|
|
1869
|
+
export async function waitForGeminiResponse(page, baseline, promptText, timeoutSeconds) {
|
|
1870
|
+
if (timeoutSeconds <= 0)
|
|
1871
|
+
return '';
|
|
1872
|
+
// Reply ownership must survive Gemini prepending older history later.
|
|
1873
|
+
// Re-anchor on the submitted user turn when possible, and otherwise only
|
|
1874
|
+
// accept assistants that are appended to the exact submission snapshot.
|
|
1875
|
+
const pickStructuredReplyCandidate = (current) => {
|
|
1876
|
+
if (!current.structuredTurnsTrusted)
|
|
1877
|
+
return '';
|
|
1878
|
+
const userAnchorTurnIndex = findLastMatchingGeminiTurnIndex(current.turns, baseline.userAnchorTurn);
|
|
1879
|
+
if (userAnchorTurnIndex !== null) {
|
|
1880
|
+
const candidate = current.turns
|
|
1881
|
+
.slice(userAnchorTurnIndex + 1)
|
|
1882
|
+
.filter((turn) => turn.Role === 'Assistant')
|
|
1883
|
+
.at(-1);
|
|
1884
|
+
return candidate ? sanitizeGeminiResponseText(candidate.Text, promptText) : '';
|
|
1885
|
+
}
|
|
1886
|
+
if (hasGeminiTurnPrefix(baseline.snapshot.turns, current.turns)) {
|
|
1887
|
+
const appendedAssistant = current.turns
|
|
1888
|
+
.slice(baseline.snapshot.turns.length)
|
|
1889
|
+
.filter((turn) => turn.Role === 'Assistant')
|
|
1890
|
+
.at(-1);
|
|
1891
|
+
if (appendedAssistant) {
|
|
1892
|
+
return sanitizeGeminiResponseText(appendedAssistant.Text, promptText);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
return '';
|
|
443
1896
|
};
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
1897
|
+
const pickFallbackGeminiTranscriptReply = (current) => current.transcriptLines
|
|
1898
|
+
.filter((line) => !baseline.snapshot.transcriptLines.includes(line))
|
|
1899
|
+
.map((line) => extractGeminiTranscriptLineCandidate(line, promptText))
|
|
1900
|
+
.filter(Boolean)
|
|
1901
|
+
.join('\n')
|
|
1902
|
+
.trim();
|
|
1903
|
+
const maxPolls = Math.max(1, Math.ceil(timeoutSeconds / 2));
|
|
1904
|
+
let lastStructured = '';
|
|
1905
|
+
let structuredStableCount = 0;
|
|
1906
|
+
let lastTranscript = '';
|
|
1907
|
+
let transcriptStableCount = 0;
|
|
1908
|
+
let transcriptMissCount = 0;
|
|
448
1909
|
for (let index = 0; index < maxPolls; index += 1) {
|
|
449
|
-
await page.wait(index === 0 ? 1
|
|
450
|
-
const
|
|
451
|
-
|
|
1910
|
+
await page.wait(index === 0 ? 1 : 2);
|
|
1911
|
+
const current = await readGeminiSnapshot(page);
|
|
1912
|
+
const structuredCandidate = pickStructuredReplyCandidate(current);
|
|
1913
|
+
if (structuredCandidate) {
|
|
1914
|
+
if (structuredCandidate === lastStructured)
|
|
1915
|
+
structuredStableCount += 1;
|
|
1916
|
+
else {
|
|
1917
|
+
lastStructured = structuredCandidate;
|
|
1918
|
+
structuredStableCount = 1;
|
|
1919
|
+
}
|
|
1920
|
+
if (!current.isGenerating && structuredStableCount >= 2) {
|
|
1921
|
+
return structuredCandidate;
|
|
1922
|
+
}
|
|
452
1923
|
continue;
|
|
453
|
-
|
|
454
|
-
|
|
1924
|
+
}
|
|
1925
|
+
transcriptMissCount += 1;
|
|
1926
|
+
if (transcriptMissCount < 2)
|
|
1927
|
+
continue;
|
|
1928
|
+
const transcriptCandidate = pickFallbackGeminiTranscriptReply(current);
|
|
1929
|
+
if (!transcriptCandidate)
|
|
1930
|
+
continue;
|
|
1931
|
+
if (transcriptCandidate === lastTranscript)
|
|
1932
|
+
transcriptStableCount += 1;
|
|
455
1933
|
else {
|
|
456
|
-
|
|
457
|
-
|
|
1934
|
+
lastTranscript = transcriptCandidate;
|
|
1935
|
+
transcriptStableCount = 1;
|
|
1936
|
+
}
|
|
1937
|
+
if (!current.isGenerating && transcriptStableCount >= 2) {
|
|
1938
|
+
return transcriptCandidate;
|
|
458
1939
|
}
|
|
459
|
-
if (stableCount >= 2 || index === maxPolls - 1)
|
|
460
|
-
return candidate;
|
|
461
1940
|
}
|
|
462
|
-
return
|
|
1941
|
+
return '';
|
|
463
1942
|
}
|