publishport-opencli 1.8.5-pp.2 → 1.8.5-pp.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +24 -0
- package/cli-manifest.json +3116 -305
- package/clis/12306/auth.js +2 -36
- package/clis/12306/me.js +3 -67
- package/clis/12306/orders.js +3 -86
- package/clis/12306/passengers.js +4 -80
- package/clis/12306/price.js +1 -166
- package/clis/12306/stations.js +1 -66
- package/clis/12306/train.js +1 -91
- package/clis/12306/trains.js +1 -166
- package/clis/12306/utils.js +1 -272
- package/clis/1688/assets.js +2 -80
- package/clis/1688/auth.js +1 -46
- package/clis/1688/download.js +1 -77
- package/clis/1688/item.js +4 -171
- package/clis/1688/search.js +4 -185
- package/clis/1688/shared.js +6 -552
- package/clis/1688/store.js +5 -206
- package/clis/1point3acres/auth.js +2 -36
- package/clis/1point3acres/digest.js +1 -35
- package/clis/1point3acres/forum.js +1 -51
- package/clis/1point3acres/forums.js +1 -44
- package/clis/1point3acres/hot.js +1 -35
- package/clis/1point3acres/latest.js +1 -35
- package/clis/1point3acres/notifications.js +1 -64
- package/clis/1point3acres/search.js +1 -71
- package/clis/1point3acres/thread.js +2 -117
- package/clis/1point3acres/user.js +1 -77
- package/clis/1point3acres/utils.js +5 -246
- package/clis/36kr/article.js +3 -49
- package/clis/36kr/hot.js +2 -73
- package/clis/36kr/news.js +1 -52
- package/clis/36kr/search.js +2 -45
- package/clis/51job/company.js +2 -92
- package/clis/51job/detail.js +2 -76
- package/clis/51job/hot.js +1 -56
- package/clis/51job/search.js +1 -80
- package/clis/51job/utils.js +7 -288
- package/clis/_atlassian/shared.js +21 -577
- package/clis/_shared/article/auth.js +15 -123
- package/clis/_shared/article/douban-md2draft.js +4 -110
- package/clis/_shared/article/format.js +1 -71
- package/clis/_shared/article/images.js +7 -125
- package/clis/_shared/article/login.js +1 -90
- package/clis/_shared/article/page-runtime.js +148 -35
- package/clis/_shared/article/publish.js +29 -182
- package/clis/_shared/common.js +1 -32
- package/clis/_shared/content-guard.js +1 -0
- package/clis/_shared/desktop-commands.js +1 -112
- package/clis/_shared/search-adapter.js +1 -70
- package/clis/_shared/site-auth.js +1 -118
- package/clis/_shared/token-auth.js +2 -0
- package/clis/_shared/video-publish.js +62 -0
- package/clis/aibase/news.js +2 -81
- package/clis/amazon/auth.js +2 -36
- package/clis/amazon/bestsellers.js +1 -8
- package/clis/amazon/discussion.js +3 -106
- package/clis/amazon/movers-shakers.js +1 -8
- package/clis/amazon/new-releases.js +1 -8
- package/clis/amazon/offer.js +3 -115
- package/clis/amazon/product.js +5 -73
- package/clis/amazon/rankings.js +2 -161
- package/clis/amazon/search.js +2 -74
- package/clis/amazon/shared.js +6 -360
- package/clis/antigravity/_actions.js +14 -131
- package/clis/antigravity/audit-extras.js +10 -273
- package/clis/antigravity/delete.js +1 -60
- package/clis/antigravity/dump.js +1 -29
- package/clis/antigravity/extract-code.js +2 -17
- package/clis/antigravity/history.js +1 -26
- package/clis/antigravity/mark-read.js +1 -52
- package/clis/antigravity/model.js +6 -77
- package/clis/antigravity/new.js +2 -19
- package/clis/antigravity/read.js +2 -27
- package/clis/antigravity/rename.js +1 -33
- package/clis/antigravity/send.js +3 -28
- package/clis/antigravity/serve.js +18 -479
- package/clis/antigravity/status.js +1 -19
- package/clis/antigravity/storage.js +6 -360
- package/clis/antigravity/watch.js +2 -39
- package/clis/apple-podcasts/episodes.js +1 -29
- package/clis/apple-podcasts/search.js +1 -31
- package/clis/apple-podcasts/top.js +1 -45
- package/clis/apple-podcasts/utils.js +1 -30
- package/clis/archive/item.js +1 -92
- package/clis/archive/search.js +1 -115
- package/clis/archive/snapshots.js +1 -129
- package/clis/archive/wayback.js +1 -83
- package/clis/arxiv/author.js +1 -44
- package/clis/arxiv/paper.js +1 -22
- package/clis/arxiv/recent.js +1 -33
- package/clis/arxiv/search.js +1 -36
- package/clis/arxiv/utils.js +1 -112
- package/clis/autohome/brand.js +1 -108
- package/clis/autohome/score.js +1 -103
- package/clis/autohome/utils.js +1 -157
- package/clis/baidu-scholar/search.js +3 -27
- package/clis/baijiahao/article.js +1 -392
- package/clis/baijiahao/lists.js +1 -70
- package/clis/baijiahao/login.js +1 -15
- package/clis/baijiahao/publish.js +57 -0
- package/clis/baijiahao/stats.js +1 -0
- package/clis/baijiahao/whoami.js +1 -33
- package/clis/band/auth.js +2 -35
- package/clis/band/bands.js +2 -38
- package/clis/band/mentions.js +2 -124
- package/clis/band/post.js +4 -104
- package/clis/band/posts.js +3 -48
- package/clis/barchart/flow.js +4 -50
- package/clis/barchart/greeks.js +5 -125
- package/clis/barchart/options.js +5 -51
- package/clis/barchart/quote.js +3 -51
- package/clis/bbc/news.js +1 -42
- package/clis/bbc/topic.js +1 -57
- package/clis/bbc/utils.js +1 -79
- package/clis/bilibili/article.js +1 -393
- package/clis/bilibili/auth.js +1 -36
- package/clis/bilibili/categories.js +1 -56
- package/clis/bilibili/comment.js +1 -107
- package/clis/bilibili/comments.js +1 -136
- package/clis/bilibili/download.js +2 -173
- package/clis/bilibili/drafts.js +1 -60
- package/clis/bilibili/dynamic-post.js +3 -60
- package/clis/bilibili/dynamic.js +1 -34
- package/clis/bilibili/favorite.js +1 -47
- package/clis/bilibili/feed.js +2 -220
- package/clis/bilibili/follow.js +1 -140
- package/clis/bilibili/following.js +1 -44
- package/clis/bilibili/history.js +1 -45
- package/clis/bilibili/hot.js +2 -27
- package/clis/bilibili/me.js +1 -13
- package/clis/bilibili/partitions.js +1 -0
- package/clis/bilibili/ranking.js +1 -25
- package/clis/bilibili/search.js +1 -24
- package/clis/bilibili/stats.js +1 -0
- package/clis/bilibili/subtitle.js +3 -123
- package/clis/bilibili/summary.js +1 -167
- package/clis/bilibili/topics.js +1 -0
- package/clis/bilibili/unfollow.js +1 -121
- package/clis/bilibili/upload.js +1 -0
- package/clis/bilibili/user-videos.js +1 -39
- package/clis/bilibili/utils.js +7 -249
- package/clis/bilibili/video-drafts.js +1 -0
- package/clis/bilibili/video.js +1 -155
- package/clis/binance/asks.js +1 -22
- package/clis/binance/depth.js +1 -21
- package/clis/binance/gainers.js +1 -23
- package/clis/binance/klines.js +1 -22
- package/clis/binance/losers.js +1 -23
- package/clis/binance/pairs.js +1 -22
- package/clis/binance/price.js +1 -19
- package/clis/binance/prices.js +1 -20
- package/clis/binance/ticker.js +1 -22
- package/clis/binance/top.js +1 -22
- package/clis/binance/trades.js +1 -21
- package/clis/bloomberg/businessweek.js +4 -117
- package/clis/bloomberg/crypto.js +1 -18
- package/clis/bloomberg/economics.js +1 -18
- package/clis/bloomberg/feeds.js +1 -16
- package/clis/bloomberg/green.js +1 -18
- package/clis/bloomberg/industries.js +1 -18
- package/clis/bloomberg/main.js +1 -18
- package/clis/bloomberg/markets.js +1 -18
- package/clis/bloomberg/news.js +2 -51
- package/clis/bloomberg/opinions.js +1 -18
- package/clis/bloomberg/politics.js +1 -18
- package/clis/bloomberg/pursuits.js +1 -18
- package/clis/bloomberg/tech.js +1 -18
- package/clis/bloomberg/utils.js +17 -380
- package/clis/booking/search.js +2 -260
- package/clis/boss/auth.js +2 -36
- package/clis/boss/batchgreet.js +1 -61
- package/clis/boss/chatlist.js +1 -116
- package/clis/boss/chatmsg.js +1 -117
- package/clis/boss/detail.js +1 -63
- package/clis/boss/exchange.js +1 -46
- package/clis/boss/greet.js +1 -49
- package/clis/boss/invite.js +4 -64
- package/clis/boss/joblist.js +1 -31
- package/clis/boss/mark.js +1 -70
- package/clis/boss/recommend.js +1 -45
- package/clis/boss/resume.js +2 -62
- package/clis/boss/search.js +1 -197
- package/clis/boss/send.js +1 -44
- package/clis/boss/stats.js +1 -66
- package/clis/boss/utils.js +13 -320
- package/clis/brave/search.js +3 -60
- package/clis/chaoxing/assignments.js +1 -76
- package/clis/chaoxing/auth.js +2 -35
- package/clis/chaoxing/exams.js +1 -75
- package/clis/chaoxing/utils.js +9 -174
- package/clis/chatgpt/ask.js +1 -129
- package/clis/chatgpt/auth.js +2 -37
- package/clis/chatgpt/detail.js +1 -63
- package/clis/chatgpt/history.js +1 -39
- package/clis/chatgpt/image.js +1 -167
- package/clis/chatgpt/model.js +1 -31
- package/clis/chatgpt/new.js +1 -32
- package/clis/chatgpt/project-file-add.js +1 -74
- package/clis/chatgpt/project-list.js +1 -37
- package/clis/chatgpt/read.js +1 -44
- package/clis/chatgpt/send.js +1 -68
- package/clis/chatgpt/status.js +1 -29
- package/clis/chatgpt/utils.js +62 -1196
- package/clis/chatgpt-app/ask.js +1 -87
- package/clis/chatgpt-app/ax.js +9 -100
- package/clis/chatgpt-app/model.js +1 -25
- package/clis/chatgpt-app/new.js +1 -61
- package/clis/chatgpt-app/read.js +1 -32
- package/clis/chatgpt-app/send.js +1 -37
- package/clis/chatgpt-app/status.js +1 -26
- package/clis/chatwise/ask.js +1 -54
- package/clis/chatwise/export.js +2 -28
- package/clis/chatwise/history.js +2 -37
- package/clis/chatwise/model.js +6 -43
- package/clis/chatwise/new.js +1 -2
- package/clis/chatwise/read.js +2 -17
- package/clis/chatwise/screenshot.js +1 -2
- package/clis/chatwise/send.js +1 -28
- package/clis/chatwise/status.js +1 -2
- package/clis/chatwise/utils.js +8 -76
- package/clis/chess/analyze.js +1 -35
- package/clis/chess/game.js +1 -114
- package/clis/chess/games.js +1 -67
- package/clis/chess/stats.js +1 -32
- package/clis/chess/utils.js +1 -170
- package/clis/claude/ask.js +2 -142
- package/clis/claude/auth.js +2 -38
- package/clis/claude/detail.js +1 -38
- package/clis/claude/history.js +1 -33
- package/clis/claude/new.js +1 -29
- package/clis/claude/read.js +1 -27
- package/clis/claude/send.js +1 -48
- package/clis/claude/status.js +1 -26
- package/clis/claude/utils.js +23 -307
- package/clis/cnblogs/article.js +1 -308
- package/clis/cnblogs/login.js +1 -15
- package/clis/cnblogs/stats.js +37 -0
- package/clis/cnblogs/whoami.js +1 -27
- package/clis/cnki/search.js +3 -26
- package/clis/codex/_actions.js +3 -201
- package/clis/codex/archive.js +1 -37
- package/clis/codex/ask.js +6 -61
- package/clis/codex/dump.js +1 -2
- package/clis/codex/export.js +2 -28
- package/clis/codex/extract-diff.js +2 -19
- package/clis/codex/history.js +1 -27
- package/clis/codex/model.js +8 -154
- package/clis/codex/new.js +1 -2
- package/clis/codex/pin.js +1 -30
- package/clis/codex/projects.js +1 -28
- package/clis/codex/read.js +2 -27
- package/clis/codex/rename.js +4 -56
- package/clis/codex/screenshot.js +1 -2
- package/clis/codex/send.js +3 -38
- package/clis/codex/sidebar.js +1 -356
- package/clis/codex/status.js +1 -2
- package/clis/coingecko/categories.js +1 -75
- package/clis/coingecko/coin.js +1 -107
- package/clis/coingecko/derivatives.js +1 -84
- package/clis/coingecko/exchanges.js +1 -74
- package/clis/coingecko/global.js +1 -71
- package/clis/coingecko/top.js +1 -64
- package/clis/coingecko/trending.js +1 -55
- package/clis/confluence/create.js +1 -39
- package/clis/confluence/page.js +1 -23
- package/clis/confluence/search.js +1 -34
- package/clis/confluence/shared.js +1 -173
- package/clis/confluence/update.js +1 -38
- package/clis/coupang/add-to-cart.js +3 -66
- package/clis/coupang/auth.js +2 -34
- package/clis/coupang/product.js +3 -99
- package/clis/coupang/search.js +8 -97
- package/clis/coupang/utils.js +1 -316
- package/clis/crates/crate.js +1 -62
- package/clis/crates/search.js +1 -44
- package/clis/crates/utils.js +1 -72
- package/clis/csdn/article.js +19 -373
- package/clis/csdn/columns.js +1 -41
- package/clis/csdn/login.js +1 -17
- package/clis/csdn/stats.js +71 -0
- package/clis/csdn/whoami.js +1 -37
- package/clis/cto51/article.js +1 -271
- package/clis/cto51/whoami.js +1 -28
- package/clis/ctrip/auth.js +1 -50
- package/clis/ctrip/flight.js +2 -121
- package/clis/ctrip/hotel-search.js +3 -111
- package/clis/ctrip/hotel-suggest.js +1 -45
- package/clis/ctrip/search.js +1 -41
- package/clis/ctrip/utils.js +6 -360
- package/clis/cursor/ask.js +5 -57
- package/clis/cursor/composer.js +2 -33
- package/clis/cursor/dump.js +1 -2
- package/clis/cursor/export.js +3 -32
- package/clis/cursor/extract-code.js +2 -20
- package/clis/cursor/history.js +2 -20
- package/clis/cursor/model.js +4 -40
- package/clis/cursor/new.js +1 -2
- package/clis/cursor/read.js +2 -20
- package/clis/cursor/screenshot.js +1 -2
- package/clis/cursor/send.js +2 -31
- package/clis/cursor/status.js +1 -2
- package/clis/dblp/author.js +1 -133
- package/clis/dblp/paper.js +1 -40
- package/clis/dblp/search.js +1 -45
- package/clis/dblp/utils.js +1 -290
- package/clis/dblp/venue.js +1 -64
- package/clis/deepseek/ask.js +1 -158
- package/clis/deepseek/auth.js +2 -34
- package/clis/deepseek/detail.js +1 -46
- package/clis/deepseek/history.js +1 -27
- package/clis/deepseek/new.js +1 -33
- package/clis/deepseek/read.js +1 -25
- package/clis/deepseek/send.js +7 -97
- package/clis/deepseek/status.js +1 -26
- package/clis/deepseek/utils.js +25 -310
- package/clis/defillama/protocol.js +1 -84
- package/clis/defillama/protocols.js +1 -55
- package/clis/defillama/utils.js +1 -99
- package/clis/devto/auth.js +9 -0
- package/clis/devto/latest.js +1 -74
- package/clis/devto/publish.js +17 -0
- package/clis/devto/read.js +2 -102
- package/clis/devto/tag.js +1 -36
- package/clis/devto/top.js +1 -30
- package/clis/devto/user.js +1 -35
- package/clis/dianping/auth.js +2 -40
- package/clis/dianping/cityResolver.js +1 -185
- package/clis/dianping/search.js +1 -157
- package/clis/dianping/shop.js +1 -173
- package/clis/dianping/utils.js +1 -157
- package/clis/dictionary/examples.js +1 -28
- package/clis/dictionary/search.js +1 -30
- package/clis/dictionary/synonyms.js +1 -28
- package/clis/discord-app/channels.js +1 -26
- package/clis/discord-app/delete.js +3 -52
- package/clis/discord-app/goto.js +1 -38
- package/clis/discord-app/members.js +2 -20
- package/clis/discord-app/read.js +1 -42
- package/clis/discord-app/search.js +4 -42
- package/clis/discord-app/send.js +3 -21
- package/clis/discord-app/servers.js +1 -26
- package/clis/discord-app/status.js +1 -17
- package/clis/discord-app/thread-read.js +1 -45
- package/clis/discord-app/threads.js +1 -37
- package/clis/discord-app/utils.js +8 -392
- package/clis/dockerhub/image.js +1 -52
- package/clis/dockerhub/search.js +1 -47
- package/clis/dockerhub/utils.js +1 -100
- package/clis/dongchedi/koubei.js +1 -85
- package/clis/dongchedi/models.js +1 -91
- package/clis/dongchedi/score.js +1 -83
- package/clis/dongchedi/search.js +1 -83
- package/clis/dongchedi/series.js +1 -87
- package/clis/dongchedi/specs.js +1 -115
- package/clis/dongchedi/utils.js +1 -180
- package/clis/douban/article.js +51 -199
- package/clis/douban/auth.js +2 -39
- package/clis/douban/book-hot.js +1 -15
- package/clis/douban/download.js +1 -68
- package/clis/douban/marks.js +3 -60
- package/clis/douban/movie-hot.js +1 -15
- package/clis/douban/photos.js +1 -35
- package/clis/douban/reviews.js +3 -57
- package/clis/douban/search.js +1 -18
- package/clis/douban/subject.js +1 -46
- package/clis/douban/top250.js +2 -20
- package/clis/douban/utils.js +24 -337
- package/clis/doubao/ask.js +1 -40
- package/clis/doubao/auth.js +3 -41
- package/clis/doubao/detail.js +1 -35
- package/clis/doubao/history.js +1 -30
- package/clis/doubao/meeting-summary.js +1 -41
- package/clis/doubao/meeting-transcript.js +1 -38
- package/clis/doubao/new.js +1 -22
- package/clis/doubao/read.js +1 -21
- package/clis/doubao/send.js +1 -24
- package/clis/doubao/status.js +1 -26
- package/clis/doubao/utils.js +40 -492
- package/clis/doubao-app/ask.js +1 -54
- package/clis/doubao-app/dump.js +1 -25
- package/clis/doubao-app/new.js +1 -21
- package/clis/doubao-app/read.js +1 -19
- package/clis/doubao-app/screenshot.js +1 -19
- package/clis/doubao-app/send.js +1 -28
- package/clis/doubao-app/status.js +1 -17
- package/clis/doubao-app/utils.js +6 -52
- package/clis/douyin/_shared/browser-fetch.js +7 -45
- package/clis/douyin/_shared/creation-id.js +1 -5
- package/clis/douyin/_shared/evaluate-result.js +1 -16
- package/clis/douyin/_shared/imagex-upload.js +1 -53
- package/clis/douyin/_shared/public-api.js +1 -29
- package/clis/douyin/_shared/sts2.js +1 -21
- package/clis/douyin/_shared/text-extra.js +1 -15
- package/clis/douyin/_shared/timing.js +1 -22
- package/clis/douyin/_shared/tos-upload.js +5 -331
- package/clis/douyin/_shared/transcode.js +1 -45
- package/clis/douyin/_shared/types.js +1 -1
- package/clis/douyin/_shared/vod-upload.js +5 -212
- package/clis/douyin/activities.js +1 -23
- package/clis/douyin/auth.js +1 -39
- package/clis/douyin/collections.js +1 -23
- package/clis/douyin/delete.js +4 -88
- package/clis/douyin/draft.js +18 -337
- package/clis/douyin/drafts.js +1 -24
- package/clis/douyin/hashtag.js +1 -114
- package/clis/douyin/location.js +1 -25
- package/clis/douyin/profile.js +1 -29
- package/clis/douyin/publish-image.js +62 -0
- package/clis/douyin/publish.js +10 -337
- package/clis/douyin/search.js +3 -260
- package/clis/douyin/stats.js +1 -28
- package/clis/douyin/update.js +1 -32
- package/clis/douyin/user-videos.js +1 -82
- package/clis/douyin/videos.js +1 -52
- package/clis/duckduckgo/search.js +1 -131
- package/clis/duckduckgo/suggest.js +1 -45
- package/clis/eastmoney/_secid.js +1 -78
- package/clis/eastmoney/announcement.js +1 -53
- package/clis/eastmoney/article.js +1 -340
- package/clis/eastmoney/convertible.js +1 -74
- package/clis/eastmoney/etf.js +1 -66
- package/clis/eastmoney/holders.js +1 -79
- package/clis/eastmoney/hot-rank.js +2 -23
- package/clis/eastmoney/index-board.js +1 -97
- package/clis/eastmoney/kline.js +1 -88
- package/clis/eastmoney/kuaixun.js +1 -55
- package/clis/eastmoney/longhu.js +1 -68
- package/clis/eastmoney/money-flow.js +1 -79
- package/clis/eastmoney/northbound.js +1 -58
- package/clis/eastmoney/quote.js +1 -108
- package/clis/eastmoney/rank.js +1 -95
- package/clis/eastmoney/sectors.js +1 -77
- package/clis/eastmoney/whoami.js +1 -18
- package/clis/endoflife/product.js +1 -55
- package/clis/endoflife/utils.js +1 -89
- package/clis/facebook/add-friend.js +2 -22
- package/clis/facebook/auth.js +1 -43
- package/clis/facebook/events.js +2 -17
- package/clis/facebook/feed.js +3 -99
- package/clis/facebook/friends.js +2 -17
- package/clis/facebook/groups.js +2 -17
- package/clis/facebook/join-group.js +2 -22
- package/clis/facebook/marketplace-inbox.js +2 -52
- package/clis/facebook/marketplace-listings.js +2 -53
- package/clis/facebook/memories.js +2 -17
- package/clis/facebook/notifications.js +3 -305
- package/clis/facebook/profile.js +2 -22
- package/clis/facebook/search.js +2 -19
- package/clis/flathub/app.js +1 -71
- package/clis/flathub/search.js +1 -80
- package/clis/flathub/utils.js +1 -114
- package/clis/flomo/auth.js +2 -35
- package/clis/flomo/memos.js +2 -217
- package/clis/gemini/ask.js +1 -51
- package/clis/gemini/auth.js +2 -36
- package/clis/gemini/deep-research-result.js +4 -96
- package/clis/gemini/deep-research.js +1 -103
- package/clis/gemini/detail.js +1 -82
- package/clis/gemini/history.js +1 -70
- package/clis/gemini/image.js +2 -110
- package/clis/gemini/new.js +1 -22
- package/clis/gemini/read.js +1 -36
- package/clis/gemini/status.js +1 -32
- package/clis/gemini/utils.js +51 -873
- package/clis/geogebra/add-circle.js +1 -46
- package/clis/geogebra/add-line.js +1 -35
- package/clis/geogebra/add-point.js +1 -27
- package/clis/geogebra/add-polygon.js +1 -25
- package/clis/geogebra/eval.js +1 -35
- package/clis/geogebra/hexagon.js +1 -62
- package/clis/geogebra/info.js +3 -62
- package/clis/geogebra/list.js +1 -35
- package/clis/geogebra/triangle.js +1 -60
- package/clis/geogebra/utils.js +11 -183
- package/clis/ghost/publish.js +1 -0
- package/clis/ghost/shared.js +1 -0
- package/clis/ghost/whoami.js +1 -0
- package/clis/gitee/auth.js +2 -31
- package/clis/gitee/index.js +1 -3
- package/clis/gitee/search.js +1 -137
- package/clis/gitee/trending.js +3 -331
- package/clis/gitee/user.js +2 -131
- package/clis/github/auth.js +2 -39
- package/clis/github-trending/repos.js +1 -168
- package/clis/google/news.js +1 -59
- package/clis/google/search.js +3 -51
- package/clis/google/suggest.js +1 -35
- package/clis/google/trends.js +1 -39
- package/clis/google/utils.js +1 -23
- package/clis/google-scholar/cite.js +8 -62
- package/clis/google-scholar/profile.js +4 -60
- package/clis/google-scholar/search.js +3 -41
- package/clis/goproxy/module.js +1 -47
- package/clis/goproxy/utils.js +1 -165
- package/clis/goproxy/versions.js +1 -59
- package/clis/gov-law/recent.js +1 -22
- package/clis/gov-law/search.js +3 -30
- package/clis/gov-law/shared.js +5 -27
- package/clis/gov-policy/recent.js +2 -84
- package/clis/gov-policy/search.js +2 -85
- package/clis/gov-policy/utils.js +1 -54
- package/clis/grok/ask.js +1 -77
- package/clis/grok/auth.js +2 -37
- package/clis/grok/delete.js +1 -54
- package/clis/grok/detail.js +1 -60
- package/clis/grok/export-all.js +7 -246
- package/clis/grok/export-utils.js +1 -94
- package/clis/grok/export.js +4 -87
- package/clis/grok/history.js +1 -48
- package/clis/grok/image.js +8 -232
- package/clis/grok/new.js +1 -20
- package/clis/grok/pin.js +1 -68
- package/clis/grok/read.js +1 -39
- package/clis/grok/send.js +1 -50
- package/clis/grok/status.js +1 -41
- package/clis/grok/utils.js +21 -324
- package/clis/guazi/browse.js +1 -95
- package/clis/guazi/car.js +1 -110
- package/clis/guazi/utils.js +1 -133
- package/clis/hackernews/ask.js +1 -31
- package/clis/hackernews/best.js +1 -31
- package/clis/hackernews/jobs.js +1 -29
- package/clis/hackernews/new.js +1 -31
- package/clis/hackernews/read.js +11 -188
- package/clis/hackernews/search.js +1 -38
- package/clis/hackernews/show.js +1 -31
- package/clis/hackernews/top.js +1 -31
- package/clis/hackernews/user.js +1 -23
- package/clis/hashnode/auth.js +11 -0
- package/clis/hashnode/publish.js +92 -0
- package/clis/hf/auth.js +2 -31
- package/clis/hf/datasets.js +1 -88
- package/clis/hf/models.js +1 -91
- package/clis/hf/paper.js +1 -79
- package/clis/hf/spaces.js +1 -101
- package/clis/hf/top.js +1 -121
- package/clis/homebrew/cask.js +1 -39
- package/clis/homebrew/formula.js +1 -41
- package/clis/homebrew/popular.js +1 -54
- package/clis/homebrew/utils.js +1 -100
- package/clis/huodongxing/events.js +1 -322
- package/clis/hupu/auth.js +2 -35
- package/clis/hupu/detail.js +7 -72
- package/clis/hupu/hot.js +3 -152
- package/clis/hupu/like.js +1 -76
- package/clis/hupu/mentions.js +6 -75
- package/clis/hupu/reply.js +1 -72
- package/clis/hupu/search.js +1 -60
- package/clis/hupu/unlike.js +1 -76
- package/clis/hupu/utils.js +10 -86
- package/clis/imdb/person.js +2 -66
- package/clis/imdb/reviews.js +3 -52
- package/clis/imdb/search.js +2 -51
- package/clis/imdb/title.js +1 -94
- package/clis/imdb/top.js +1 -54
- package/clis/imdb/trending.js +1 -53
- package/clis/imdb/utils.js +13 -136
- package/clis/imooc/article.js +1 -192
- package/clis/imooc/login.js +1 -15
- package/clis/imooc/whoami.js +1 -33
- package/clis/indeed/job.js +2 -68
- package/clis/indeed/search.js +2 -75
- package/clis/indeed/utils.js +1 -152
- package/clis/instagram/_shared/private-publish.js +4 -959
- package/clis/instagram/_shared/protocol-capture.js +9 -111
- package/clis/instagram/_shared/runtime-info.js +2 -50
- package/clis/instagram/auth.js +2 -37
- package/clis/instagram/collection-create.js +2 -22
- package/clis/instagram/collection-delete.js +2 -22
- package/clis/instagram/comment.js +2 -24
- package/clis/instagram/detail.js +2 -150
- package/clis/instagram/download.js +5 -149
- package/clis/instagram/explore.js +2 -17
- package/clis/instagram/follow.js +2 -22
- package/clis/instagram/followers.js +2 -18
- package/clis/instagram/following.js +2 -18
- package/clis/instagram/like.js +2 -23
- package/clis/instagram/note.js +8 -69
- package/clis/instagram/post.js +35 -814
- package/clis/instagram/profile.js +2 -17
- package/clis/instagram/reel.js +18 -393
- package/clis/instagram/save.js +2 -23
- package/clis/instagram/saved.js +2 -18
- package/clis/instagram/search.js +2 -18
- package/clis/instagram/story.js +4 -99
- package/clis/instagram/unfollow.js +2 -22
- package/clis/instagram/unlike.js +2 -23
- package/clis/instagram/unsave.js +2 -23
- package/clis/instagram/user.js +1 -476
- package/clis/jd/add-cart.js +3 -53
- package/clis/jd/auth.js +2 -36
- package/clis/jd/cart.js +2 -23
- package/clis/jd/detail.js +4 -25
- package/clis/jd/item.js +65 -697
- package/clis/jd/reviews.js +3 -27
- package/clis/jd/search.js +3 -27
- package/clis/jianshu/article.js +1 -0
- package/clis/jianshu/login.js +1 -0
- package/clis/jianshu/notebooks.js +1 -0
- package/clis/jianshu/whoami.js +1 -0
- package/clis/jianyu/auth.js +3 -37
- package/clis/jianyu/detail.js +1 -21
- package/clis/jianyu/search.js +6 -567
- package/clis/jianyu/shared/china-bid-search.js +4 -83
- package/clis/jianyu/shared/procurement-contract.js +1 -324
- package/clis/jianyu/shared/procurement-detail.js +2 -91
- package/clis/jike/auth.js +2 -67
- package/clis/jike/comment.js +6 -60
- package/clis/jike/create.js +6 -61
- package/clis/jike/feed.js +3 -39
- package/clis/jike/like.js +3 -41
- package/clis/jike/notifications.js +3 -57
- package/clis/jike/post.js +2 -41
- package/clis/jike/repost.js +10 -95
- package/clis/jike/search.js +3 -42
- package/clis/jike/topic.js +2 -47
- package/clis/jike/user.js +2 -48
- package/clis/jike/utils.js +2 -12
- package/clis/jimeng/auth.js +2 -35
- package/clis/jimeng/generate.js +2 -33
- package/clis/jimeng/history.js +2 -27
- package/clis/jimeng/new.js +2 -20
- package/clis/jimeng/workspaces.js +2 -22
- package/clis/jira/attachments.js +1 -28
- package/clis/jira/comments.js +1 -28
- package/clis/jira/issue.js +1 -28
- package/clis/jira/links.js +1 -28
- package/clis/jira/search.js +1 -47
- package/clis/jira/shared.js +1 -256
- package/clis/juejin/article.js +5 -503
- package/clis/juejin/categories.js +1 -36
- package/clis/juejin/hot.js +1 -37
- package/clis/juejin/login.js +1 -15
- package/clis/juejin/recommend.js +1 -61
- package/clis/juejin/stats.js +53 -0
- package/clis/juejin/tags.js +1 -37
- package/clis/juejin/utils.js +1 -199
- package/clis/juejin/whoami.js +1 -34
- package/clis/ke/auth.js +2 -34
- package/clis/ke/chengjiao.js +2 -35
- package/clis/ke/ershoufang.js +2 -53
- package/clis/ke/utils.js +4 -87
- package/clis/ke/xiaoqu.js +2 -35
- package/clis/ke/zufang.js +3 -48
- package/clis/kimi/_utils.js +9 -81
- package/clis/kimi/audit-extras.js +14 -218
- package/clis/kimi/auth.js +3 -43
- package/clis/kimi/chat.js +15 -408
- package/clis/kimi/storage.js +5 -160
- package/clis/kimi/ui.js +14 -239
- package/clis/kimi/usage.js +5 -98
- package/clis/kuaishou/auth.js +1 -0
- package/clis/kuaishou/publish.js +53 -0
- package/clis/lesswrong/_helpers.js +5 -71
- package/clis/lesswrong/comments.js +5 -61
- package/clis/lesswrong/curated.js +3 -29
- package/clis/lesswrong/frontpage.js +3 -29
- package/clis/lesswrong/new.js +3 -29
- package/clis/lesswrong/read.js +3 -44
- package/clis/lesswrong/sequences.js +3 -26
- package/clis/lesswrong/shortform.js +3 -29
- package/clis/lesswrong/tag.js +3 -44
- package/clis/lesswrong/tags.js +3 -26
- package/clis/lesswrong/top-month.js +3 -29
- package/clis/lesswrong/top-week.js +3 -29
- package/clis/lesswrong/top-year.js +3 -29
- package/clis/lesswrong/top.js +3 -29
- package/clis/lesswrong/user-posts.js +3 -40
- package/clis/lesswrong/user.js +3 -43
- package/clis/lichess/top.js +1 -46
- package/clis/lichess/user.js +1 -91
- package/clis/lichess/utils.js +1 -97
- package/clis/linkedin/auth.js +2 -37
- package/clis/linkedin/connect.js +11 -291
- package/clis/linkedin/inbox.js +1 -234
- package/clis/linkedin/job-detail.js +4 -167
- package/clis/linkedin/jobs-preferences.js +3 -82
- package/clis/linkedin/people-search.js +2 -301
- package/clis/linkedin/post-analytics.js +1 -74
- package/clis/linkedin/posts-core.js +2 -105
- package/clis/linkedin/posts.js +1 -22
- package/clis/linkedin/profile-analytics.js +2 -95
- package/clis/linkedin/profile-experience.js +6 -380
- package/clis/linkedin/profile-projects.js +4 -185
- package/clis/linkedin/profile-read.js +3 -90
- package/clis/linkedin/safe-send.js +8 -313
- package/clis/linkedin/salesnav-inbox.js +5 -194
- package/clis/linkedin/salesnav-message.js +10 -337
- package/clis/linkedin/salesnav-search.js +4 -175
- package/clis/linkedin/salesnav-thread.js +1 -212
- package/clis/linkedin/search.js +10 -371
- package/clis/linkedin/sent-invitations.js +2 -51
- package/clis/linkedin/services-read.js +6 -162
- package/clis/linkedin/shared.js +2 -116
- package/clis/linkedin/thread-snapshot.js +4 -130
- package/clis/linkedin/timeline.js +2 -110
- package/clis/linkedin-learning/auth.js +2 -37
- package/clis/linkedin-learning/course.js +4 -125
- package/clis/linkedin-learning/search.js +4 -142
- package/clis/linkedin-learning/trending.js +4 -120
- package/clis/linux-do/auth.js +2 -37
- package/clis/linux-do/categories.js +1 -50
- package/clis/linux-do/feed.js +4 -380
- package/clis/linux-do/search.js +1 -29
- package/clis/linux-do/tags.js +1 -28
- package/clis/linux-do/topic-content.js +9 -136
- package/clis/linux-do/topic.js +1 -53
- package/clis/linux-do/user-posts.js +1 -57
- package/clis/linux-do/user-topics.js +1 -37
- package/clis/lobsters/active.js +1 -29
- package/clis/lobsters/domain.js +1 -92
- package/clis/lobsters/hot.js +1 -29
- package/clis/lobsters/newest.js +1 -29
- package/clis/lobsters/read.js +11 -196
- package/clis/lobsters/tag.js +1 -35
- package/clis/maimai/auth.js +2 -30
- package/clis/maimai/search-talents.js +4 -159
- package/clis/manus/_utils.js +2 -107
- package/clis/manus/auth.js +2 -36
- package/clis/manus/connectors.js +3 -39
- package/clis/manus/credits.js +3 -38
- package/clis/manus/list.js +4 -63
- package/clis/manus/read.js +3 -59
- package/clis/manus/skills.js +3 -60
- package/clis/manus/status.js +3 -38
- package/clis/maven/artifact.js +1 -49
- package/clis/maven/search.js +1 -51
- package/clis/maven/utils.js +1 -110
- package/clis/mdn/search.js +1 -97
- package/clis/medium/article.js +12 -0
- package/clis/medium/feed.js +1 -16
- package/clis/medium/login.js +1 -0
- package/clis/medium/search.js +1 -16
- package/clis/medium/tag.js +1 -135
- package/clis/medium/user.js +1 -16
- package/clis/medium/utils.js +3 -20
- package/clis/medium/whoami.js +1 -0
- package/clis/mubu/doc.js +1 -41
- package/clis/mubu/docs.js +1 -44
- package/clis/mubu/notes.js +1 -245
- package/clis/mubu/recent.js +1 -28
- package/clis/mubu/search.js +1 -63
- package/clis/mubu/utils.js +16 -289
- package/clis/note/auth.js +12 -0
- package/clis/note/note-utils.js +2 -0
- package/clis/note/publish.js +17 -0
- package/clis/notebooklm/add-source.js +8 -231
- package/clis/notebooklm/auth.js +2 -36
- package/clis/notebooklm/create.js +1 -76
- package/clis/notebooklm/current.js +1 -28
- package/clis/notebooklm/generate-audio.js +1 -91
- package/clis/notebooklm/generate-slides.js +1 -106
- package/clis/notebooklm/get.js +1 -37
- package/clis/notebooklm/history.js +1 -25
- package/clis/notebooklm/list.js +1 -36
- package/clis/notebooklm/note-list.js +1 -28
- package/clis/notebooklm/notes-get.js +1 -47
- package/clis/notebooklm/open.js +1 -42
- package/clis/notebooklm/rpc.js +8 -175
- package/clis/notebooklm/shared.js +1 -3
- package/clis/notebooklm/source-fulltext.js +1 -44
- package/clis/notebooklm/source-get.js +1 -40
- package/clis/notebooklm/source-guide.js +1 -44
- package/clis/notebooklm/source-list.js +1 -30
- package/clis/notebooklm/status.js +1 -31
- package/clis/notebooklm/summary.js +1 -30
- package/clis/notebooklm/utils.js +10 -652
- package/clis/notebooklm/write-note.js +1 -103
- package/clis/nowcoder/auth.js +2 -43
- package/clis/nowcoder/comment.js +1 -0
- package/clis/nowcoder/comments.js +1 -0
- package/clis/nowcoder/companies.js +1 -24
- package/clis/nowcoder/creators.js +1 -28
- package/clis/nowcoder/delete.js +1 -0
- package/clis/nowcoder/detail.js +2 -18
- package/clis/nowcoder/dm-list.js +1 -0
- package/clis/nowcoder/dm-read.js +1 -0
- package/clis/nowcoder/dm-send.js +1 -0
- package/clis/nowcoder/drafts.js +1 -0
- package/clis/nowcoder/experience.js +2 -21
- package/clis/nowcoder/hot.js +1 -25
- package/clis/nowcoder/inbox.js +1 -0
- package/clis/nowcoder/jobs.js +1 -22
- package/clis/nowcoder/like.js +1 -0
- package/clis/nowcoder/my.js +1 -0
- package/clis/nowcoder/notifications.js +2 -16
- package/clis/nowcoder/papers.js +2 -21
- package/clis/nowcoder/post.js +1 -0
- package/clis/nowcoder/practice.js +2 -19
- package/clis/nowcoder/recommend.js +1 -31
- package/clis/nowcoder/referral.js +2 -21
- package/clis/nowcoder/salary.js +2 -21
- package/clis/nowcoder/search.js +2 -21
- package/clis/nowcoder/suggest.js +2 -19
- package/clis/nowcoder/topics.js +1 -28
- package/clis/nowcoder/trending.js +1 -26
- package/clis/nowcoder/utils.js +68 -0
- package/clis/npm/downloads.js +1 -59
- package/clis/npm/package.js +1 -70
- package/clis/npm/search.js +1 -49
- package/clis/npm/utils.js +1 -76
- package/clis/nuget/package.js +1 -101
- package/clis/nuget/search.js +1 -69
- package/clis/nuget/utils.js +1 -87
- package/clis/nvd/cve.js +1 -121
- package/clis/oeis/search.js +1 -63
- package/clis/oeis/sequence.js +1 -71
- package/clis/oeis/utils.js +1 -88
- package/clis/ones/common.js +6 -127
- package/clis/ones/enrich-tasks.js +1 -37
- package/clis/ones/login.js +2 -81
- package/clis/ones/logout.js +1 -18
- package/clis/ones/me.js +1 -31
- package/clis/ones/my-tasks.js +1 -121
- package/clis/ones/resolve-labels.js +1 -64
- package/clis/ones/task-helpers.js +1 -212
- package/clis/ones/task.js +1 -67
- package/clis/ones/tasks.js +1 -80
- package/clis/ones/token-info.js +1 -43
- package/clis/ones/worklog.js +7 -261
- package/clis/openalex/search.js +1 -69
- package/clis/openalex/utils.js +1 -160
- package/clis/openalex/work.js +1 -65
- package/clis/openfda/drug-label.js +1 -74
- package/clis/openfda/food-recall.js +1 -65
- package/clis/openfda/utils.js +1 -67
- package/clis/openreview/author.js +1 -58
- package/clis/openreview/paper.js +1 -43
- package/clis/openreview/reviews.js +3 -130
- package/clis/openreview/search.js +1 -46
- package/clis/openreview/utils.js +1 -172
- package/clis/openreview/venue.js +1 -63
- package/clis/oschina/article.js +1 -237
- package/clis/oschina/catalogs.js +1 -31
- package/clis/oschina/login.js +1 -16
- package/clis/oschina/stats.js +54 -0
- package/clis/oschina/whoami.js +1 -35
- package/clis/osv/query.js +1 -72
- package/clis/osv/utils.js +1 -169
- package/clis/osv/vulnerability.js +1 -54
- package/clis/packagist/package.js +1 -49
- package/clis/packagist/search.js +1 -43
- package/clis/packagist/utils.js +1 -113
- package/clis/paperreview/feedback.js +1 -53
- package/clis/paperreview/review.js +1 -38
- package/clis/paperreview/submit.js +1 -86
- package/clis/paperreview/utils.js +1 -197
- package/clis/pinterest/api.js +1 -0
- package/clis/pinterest/auth.js +1 -0
- package/clis/pinterest/boards.js +1 -0
- package/clis/pinterest/client.js +20 -0
- package/clis/pinterest/publish.js +13 -0
- package/clis/pixiv/auth.js +2 -40
- package/clis/pixiv/detail.js +1 -66
- package/clis/pixiv/download.js +1 -82
- package/clis/pixiv/illusts.js +1 -66
- package/clis/pixiv/ranking.js +2 -36
- package/clis/pixiv/search.js +1 -44
- package/clis/pixiv/user.js +1 -59
- package/clis/pixiv/utils.js +3 -83
- package/clis/powerchina/auth.js +2 -37
- package/clis/powerchina/search.js +1 -251
- package/clis/producthunt/browse.js +2 -48
- package/clis/producthunt/hot.js +2 -49
- package/clis/producthunt/posts.js +1 -29
- package/clis/producthunt/today.js +1 -36
- package/clis/producthunt/utils.js +1 -99
- package/clis/pubmed/article.js +1 -55
- package/clis/pubmed/author.js +1 -64
- package/clis/pubmed/citations.js +1 -36
- package/clis/pubmed/clinical-trial.js +1 -59
- package/clis/pubmed/journal.js +1 -59
- package/clis/pubmed/mesh.js +1 -47
- package/clis/pubmed/related.js +1 -45
- package/clis/pubmed/review.js +1 -58
- package/clis/pubmed/search.js +1 -75
- package/clis/pubmed/utils.js +1 -325
- package/clis/pypi/downloads.js +1 -66
- package/clis/pypi/package.js +1 -79
- package/clis/pypi/utils.js +1 -55
- package/clis/qiita/auth.js +1 -0
- package/clis/qiita/gql.js +32 -0
- package/clis/qiita/publish.js +7 -0
- package/clis/qoder/_utils.js +18 -96
- package/clis/qoder/composer.js +1 -45
- package/clis/qoder/history.js +3 -27
- package/clis/qoder/quest.js +1 -147
- package/clis/qoder/read.js +1 -29
- package/clis/qoder/status.js +1 -21
- package/clis/qoder/ui.js +14 -287
- package/clis/quark/auth.js +2 -33
- package/clis/quark/ls.js +1 -64
- package/clis/quark/mkdir.js +1 -37
- package/clis/quark/mv.js +1 -54
- package/clis/quark/rename.js +1 -27
- package/clis/quark/rm.js +1 -25
- package/clis/quark/save.js +1 -81
- package/clis/quark/share-tree.js +1 -46
- package/clis/quark/utils.js +4 -137
- package/clis/qwen/ask.js +1 -104
- package/clis/qwen/auth.js +3 -42
- package/clis/qwen/detail.js +1 -62
- package/clis/qwen/history.js +1 -61
- package/clis/qwen/image.js +5 -153
- package/clis/qwen/new.js +1 -23
- package/clis/qwen/read.js +1 -41
- package/clis/qwen/send.js +1 -55
- package/clis/qwen/status.js +1 -37
- package/clis/qwen/utils.js +16 -292
- package/clis/reddit/auth.js +2 -37
- package/clis/reddit/comment.js +4 -26
- package/clis/reddit/frontpage.js +2 -32
- package/clis/reddit/home.js +3 -117
- package/clis/reddit/hot.js +2 -37
- package/clis/reddit/popular.js +2 -35
- package/clis/reddit/read.js +10 -200
- package/clis/reddit/reply.js +4 -130
- package/clis/reddit/save.js +4 -26
- package/clis/reddit/saved.js +3 -29
- package/clis/reddit/search.js +2 -53
- package/clis/reddit/subreddit-info.js +3 -90
- package/clis/reddit/subreddit.js +2 -47
- package/clis/reddit/subscribe.js +4 -26
- package/clis/reddit/subscribed.js +4 -101
- package/clis/reddit/upvote.js +4 -26
- package/clis/reddit/upvoted.js +3 -29
- package/clis/reddit/user-comments.js +2 -27
- package/clis/reddit/user-posts.js +2 -28
- package/clis/reddit/user.js +2 -20
- package/clis/reddit/whoami.js +2 -66
- package/clis/rednote/auth.js +2 -35
- package/clis/rednote/comments.js +1 -85
- package/clis/rednote/download.js +1 -59
- package/clis/rednote/feed.js +1 -27
- package/clis/rednote/note.js +1 -68
- package/clis/rednote/notifications.js +3 -75
- package/clis/rednote/search.js +2 -77
- package/clis/rednote/user.js +1 -55
- package/clis/rest-countries/country.js +1 -65
- package/clis/rest-countries/region.js +1 -64
- package/clis/rest-countries/utils.js +1 -126
- package/clis/reuters/article-detail.js +1 -53
- package/clis/reuters/auth.js +3 -31
- package/clis/reuters/search.js +1 -63
- package/clis/reuters/utils.js +5 -114
- package/clis/rfc/rfc.js +1 -52
- package/clis/rfc/utils.js +1 -72
- package/clis/rubygems/gem.js +1 -42
- package/clis/rubygems/search.js +1 -47
- package/clis/rubygems/utils.js +1 -86
- package/clis/segmentfault/_signed-request.js +43 -0
- package/clis/segmentfault/article.js +3 -406
- package/clis/segmentfault/channels.js +1 -64
- package/clis/segmentfault/login.js +1 -15
- package/clis/segmentfault/stats.js +82 -0
- package/clis/segmentfault/tags.js +1 -67
- package/clis/segmentfault/whoami.js +1 -53
- package/clis/semanticscholar/citations.js +1 -61
- package/clis/semanticscholar/paper.js +1 -52
- package/clis/semanticscholar/recommendations.js +1 -47
- package/clis/semanticscholar/search.js +1 -48
- package/clis/semanticscholar/utils.js +1 -196
- package/clis/sinablog/article.js +1 -15
- package/clis/sinablog/hot.js +1 -15
- package/clis/sinablog/search.js +1 -52
- package/clis/sinablog/user.js +1 -16
- package/clis/sinablog/utils.js +9 -42
- package/clis/sinafinance/news.js +1 -62
- package/clis/sinafinance/rolling-news.js +2 -23
- package/clis/sinafinance/stock-rank.js +3 -28
- package/clis/sinafinance/stock.js +1 -121
- package/clis/slock/attachment-download.js +1 -72
- package/clis/slock/attachment-upload.js +7 -85
- package/clis/slock/attachment-url.js +1 -53
- package/clis/slock/auth-verify.js +1 -19
- package/clis/slock/bookmark-add.js +5 -37
- package/clis/slock/bookmark-list.js +4 -44
- package/clis/slock/bookmark-remove.js +4 -39
- package/clis/slock/channel-action.js +1 -63
- package/clis/slock/channel-archive.js +1 -9
- package/clis/slock/channel-create.js +1 -48
- package/clis/slock/channel-files.js +1 -51
- package/clis/slock/channel-info.js +1 -42
- package/clis/slock/channel-join.js +1 -9
- package/clis/slock/channel-leave.js +1 -9
- package/clis/slock/channel-list.js +1 -40
- package/clis/slock/channel-mark.js +1 -71
- package/clis/slock/channel-members.js +1 -64
- package/clis/slock/channel-unarchive.js +1 -11
- package/clis/slock/dm-list.js +1 -41
- package/clis/slock/errors.js +1 -30
- package/clis/slock/in-page.js +30 -130
- package/clis/slock/inbox-done.js +5 -36
- package/clis/slock/inbox-read-all.js +1 -32
- package/clis/slock/inbox.js +1 -74
- package/clis/slock/login.js +1 -3
- package/clis/slock/message-read.js +24 -131
- package/clis/slock/message-search.js +10 -58
- package/clis/slock/message-send.js +25 -119
- package/clis/slock/reaction-add.js +1 -42
- package/clis/slock/reaction-remove.js +1 -42
- package/clis/slock/resolve.js +1 -74
- package/clis/slock/server-list.js +3 -32
- package/clis/slock/server-use.js +6 -41
- package/clis/slock/shared.js +1 -14
- package/clis/slock/task-claim.js +4 -62
- package/clis/slock/task-convert.js +13 -84
- package/clis/slock/task-create.js +6 -64
- package/clis/slock/task-delete.js +5 -51
- package/clis/slock/task-get.js +6 -54
- package/clis/slock/task-list-server.js +5 -56
- package/clis/slock/task-list.js +6 -62
- package/clis/slock/task-status.js +6 -80
- package/clis/slock/task-unclaim.js +4 -57
- package/clis/slock/thread-done.js +1 -9
- package/clis/slock/thread-follow.js +1 -46
- package/clis/slock/thread-list.js +1 -44
- package/clis/slock/thread-state.js +1 -45
- package/clis/slock/thread-undone.js +1 -9
- package/clis/slock/thread-unfollow.js +1 -9
- package/clis/slock/unread-summary.js +5 -36
- package/clis/slock/whoami.js +1 -12
- package/clis/smzdm/search.js +3 -81
- package/clis/sohu/article.js +1 -501
- package/clis/sohu/attributes.js +1 -36
- package/clis/sohu/categories.js +1 -48
- package/clis/sohu/channels.js +1 -34
- package/clis/sohu/columns.js +1 -36
- package/clis/sohu/login.js +1 -15
- package/clis/sohu/stats.js +95 -0
- package/clis/sohu/topics.js +1 -50
- package/clis/sohu/whoami.js +1 -27
- package/clis/spotify/spotify.js +1 -327
- package/clis/spotify/utils.js +8 -66
- package/clis/stackoverflow/bounties.js +1 -35
- package/clis/stackoverflow/hot.js +1 -32
- package/clis/stackoverflow/read.js +10 -311
- package/clis/stackoverflow/related.js +1 -66
- package/clis/stackoverflow/search.js +1 -35
- package/clis/stackoverflow/tag.js +1 -60
- package/clis/stackoverflow/unanswered.js +1 -33
- package/clis/stackoverflow/user.js +1 -50
- package/clis/stackoverflow/utils.js +1 -118
- package/clis/steam/app.js +1 -67
- package/clis/steam/search.js +1 -58
- package/clis/steam/top-sellers.js +1 -26
- package/clis/steam/utils.js +1 -107
- package/clis/substack/auth.js +11 -0
- package/clis/substack/feed.js +1 -16
- package/clis/substack/post-utils.js +2 -0
- package/clis/substack/publication.js +1 -16
- package/clis/substack/publish.js +10 -0
- package/clis/substack/search.js +1 -79
- package/clis/substack/utils.js +6 -34
- package/clis/suno/auth.js +2 -40
- package/clis/suno/download.js +5 -128
- package/clis/suno/generate.js +4 -231
- package/clis/suno/list.js +4 -69
- package/clis/suno/status.js +1 -63
- package/clis/suno/utils.js +29 -476
- package/clis/taobao/add-cart.js +6 -63
- package/clis/taobao/auth.js +3 -53
- package/clis/taobao/cart.js +3 -31
- package/clis/taobao/detail.js +5 -28
- package/clis/taobao/reviews.js +4 -29
- package/clis/taobao/search.js +3 -36
- package/clis/tdx/hot-rank.js +2 -25
- package/clis/test-utils.js +1 -61
- package/clis/ths/hot-rank.js +2 -25
- package/clis/tieba/hot.js +3 -35
- package/clis/tieba/posts.js +1 -86
- package/clis/tieba/read.js +2 -59
- package/clis/tieba/search.js +3 -58
- package/clis/tieba/utils.js +1 -240
- package/clis/tiktok/auth.js +2 -37
- package/clis/tiktok/comment.js +5 -81
- package/clis/tiktok/creator-videos.js +3 -228
- package/clis/tiktok/explore.js +8 -76
- package/clis/tiktok/follow.js +8 -81
- package/clis/tiktok/following.js +8 -76
- package/clis/tiktok/friends.js +8 -75
- package/clis/tiktok/like.js +2 -17
- package/clis/tiktok/live.js +7 -72
- package/clis/tiktok/notifications.js +10 -86
- package/clis/tiktok/profile.js +2 -31
- package/clis/tiktok/publish.js +82 -0
- package/clis/tiktok/save.js +2 -17
- package/clis/tiktok/search.js +2 -18
- package/clis/tiktok/unfollow.js +7 -79
- package/clis/tiktok/unlike.js +2 -17
- package/clis/tiktok/unsave.js +2 -17
- package/clis/tiktok/user.js +9 -82
- package/clis/tiktok/utils.js +7 -240
- package/clis/toutiao/article.js +1 -0
- package/clis/toutiao/articles.js +2 -51
- package/clis/toutiao/auth.js +2 -35
- package/clis/toutiao/hot.js +1 -63
- package/clis/toutiao/utils.js +2 -161
- package/clis/trae-cn/activity.js +1 -22
- package/clis/trae-cn/approve.js +1 -52
- package/clis/trae-cn/ask.js +1 -99
- package/clis/trae-cn/dump.js +1 -5
- package/clis/trae-cn/export.js +3 -40
- package/clis/trae-cn/model.js +1 -22
- package/clis/trae-cn/new.js +1 -63
- package/clis/trae-cn/read.js +1 -23
- package/clis/trae-cn/screenshot.js +1 -5
- package/clis/trae-cn/select-model.js +1 -25
- package/clis/trae-cn/send.js +1 -23
- package/clis/trae-cn/setup.js +1 -75
- package/clis/trae-cn/status.js +1 -27
- package/clis/trae-cn/targets.js +1 -96
- package/clis/trae-cn/utils.js +24 -318
- package/clis/trae-cn/watch.js +3 -119
- package/clis/trae-solo/_actions.js +5 -24
- package/clis/trae-solo/_fs.js +6 -118
- package/clis/trae-solo/_state.js +2 -111
- package/clis/trae-solo/automation.js +4 -58
- package/clis/trae-solo/history.js +2 -41
- package/clis/trae-solo/mode.js +4 -54
- package/clis/trae-solo/model.js +4 -88
- package/clis/trae-solo/renderer-storage.js +4 -163
- package/clis/trae-solo/settings.js +1 -54
- package/clis/trae-solo/skill-fs.js +1 -123
- package/clis/trae-solo/skill.js +12 -151
- package/clis/trae-solo/state-fs.js +2 -156
- package/clis/trae-solo/status.js +1 -2
- package/clis/trae-solo/task-fs.js +5 -181
- package/clis/trae-solo/user-rules.js +1 -29
- package/clis/trae-solo/workspaces-fs.js +1 -113
- package/clis/tumblr/auth.js +24 -0
- package/clis/tumblr/publish.js +14 -0
- package/clis/tvmaze/search.js +1 -61
- package/clis/tvmaze/show.js +1 -60
- package/clis/tvmaze/utils.js +1 -110
- package/clis/twitter/accept.js +7 -95
- package/clis/twitter/article.js +7 -61
- package/clis/twitter/auth.js +2 -39
- package/clis/twitter/block.js +4 -32
- package/clis/twitter/bookmark-folder.js +3 -189
- package/clis/twitter/bookmark-folders.js +3 -113
- package/clis/twitter/bookmark.js +3 -33
- package/clis/twitter/bookmarks.js +4 -158
- package/clis/twitter/delete.js +5 -123
- package/clis/twitter/device-follow.js +3 -184
- package/clis/twitter/dm-list.js +1 -0
- package/clis/twitter/dm-read.js +1 -0
- package/clis/twitter/dm-send.js +13 -0
- package/clis/twitter/dm-shared.js +6 -0
- package/clis/twitter/download.js +6 -449
- package/clis/twitter/follow-batch.js +5 -124
- package/clis/twitter/follow.js +4 -32
- package/clis/twitter/followers.js +5 -139
- package/clis/twitter/following.js +2 -272
- package/clis/twitter/hide-reply.js +3 -33
- package/clis/twitter/like.js +3 -35
- package/clis/twitter/likes.js +8 -235
- package/clis/twitter/list-add-batch.js +1 -32
- package/clis/twitter/list-add-core.js +9 -219
- package/clis/twitter/list-add.js +1 -20
- package/clis/twitter/list-batch-utils.js +1 -95
- package/clis/twitter/list-create.js +5 -148
- package/clis/twitter/list-delete.js +4 -126
- package/clis/twitter/list-remove-batch.js +1 -32
- package/clis/twitter/list-remove-core.js +9 -173
- package/clis/twitter/list-remove.js +1 -20
- package/clis/twitter/list-tweets.js +7 -179
- package/clis/twitter/lists.js +6 -157
- package/clis/twitter/notifications.js +2 -126
- package/clis/twitter/post.js +32 -357
- package/clis/twitter/profile.js +7 -115
- package/clis/twitter/quote.js +7 -118
- package/clis/twitter/reply-dm.js +7 -78
- package/clis/twitter/reply.js +12 -167
- package/clis/twitter/retweet.js +3 -35
- package/clis/twitter/schedule.js +11 -167
- package/clis/twitter/scheduled-delete.js +3 -48
- package/clis/twitter/scheduled-list.js +2 -30
- package/clis/twitter/scheduled-utils.js +3 -17
- package/clis/twitter/search.js +5 -339
- package/clis/twitter/shared.js +6 -494
- package/clis/twitter/thread.js +4 -164
- package/clis/twitter/timeline.js +3 -210
- package/clis/twitter/trending.js +2 -42
- package/clis/twitter/tweets.js +6 -341
- package/clis/twitter/unblock.js +4 -32
- package/clis/twitter/unbookmark.js +3 -33
- package/clis/twitter/unfollow.js +4 -32
- package/clis/twitter/unlike.js +3 -35
- package/clis/twitter/unretweet.js +3 -35
- package/clis/twitter/utils.js +11 -279
- package/clis/uisdc/news.js +2 -82
- package/clis/uiverse/_shared.js +11 -181
- package/clis/uiverse/code.js +1 -49
- package/clis/uiverse/preview.js +1 -73
- package/clis/upwork/auth.js +2 -36
- package/clis/upwork/detail.js +2 -112
- package/clis/upwork/feed.js +3 -91
- package/clis/upwork/search.js +2 -96
- package/clis/upwork/utils.js +1 -323
- package/clis/v2ex/auth.js +2 -36
- package/clis/v2ex/daily.js +3 -61
- package/clis/v2ex/hot.js +1 -26
- package/clis/v2ex/latest.js +1 -26
- package/clis/v2ex/me.js +2 -44
- package/clis/v2ex/member.js +1 -28
- package/clis/v2ex/node.js +1 -39
- package/clis/v2ex/nodes.js +1 -26
- package/clis/v2ex/notifications.js +2 -34
- package/clis/v2ex/replies.js +1 -27
- package/clis/v2ex/topic.js +1 -31
- package/clis/v2ex/user.js +1 -34
- package/clis/wanfang/search.js +4 -28
- package/clis/web/read.js +9 -240
- package/clis/wechat-channels/auth.js +2 -47
- package/clis/wechat-channels/publish.js +37 -534
- package/clis/weibo/article.js +1 -0
- package/clis/weibo/auth.js +3 -39
- package/clis/weibo/comments.js +4 -29
- package/clis/weibo/delete.js +3 -91
- package/clis/weibo/favorites.js +8 -151
- package/clis/weibo/feed.js +5 -41
- package/clis/weibo/hot.js +2 -24
- package/clis/weibo/me.js +3 -27
- package/clis/weibo/post.js +3 -32
- package/clis/weibo/publish.js +10 -244
- package/clis/weibo/search.js +2 -35
- package/clis/weibo/user-posts.js +7 -149
- package/clis/weibo/user.js +3 -29
- package/clis/weibo/utils.js +3 -46
- package/clis/weixin/article.js +1 -332
- package/clis/weixin/create-draft.js +26 -226
- package/clis/weixin/download.js +2 -273
- package/clis/weixin/drafts.js +2 -41
- package/clis/weixin/login.js +1 -0
- package/clis/weixin/search.js +2 -115
- package/clis/weixin/stats.js +43 -0
- package/clis/weixin/whoami.js +1 -26
- package/clis/weread/ai-outline.js +2 -171
- package/clis/weread/auth.js +2 -37
- package/clis/weread/book-search.js +2 -438
- package/clis/weread/book.js +2 -232
- package/clis/weread/highlights.js +1 -24
- package/clis/weread/notebooks.js +1 -22
- package/clis/weread/notes.js +1 -30
- package/clis/weread/ranking.js +1 -29
- package/clis/weread/search.js +1 -186
- package/clis/weread/shelf.js +1 -66
- package/clis/weread/utils.js +6 -260
- package/clis/weread-official/book.js +1 -135
- package/clis/weread-official/discover.js +1 -107
- package/clis/weread-official/list-apis.js +1 -95
- package/clis/weread-official/notes.js +1 -171
- package/clis/weread-official/readdata.js +1 -158
- package/clis/weread-official/review.js +1 -93
- package/clis/weread-official/search.js +1 -106
- package/clis/weread-official/shelf.js +1 -97
- package/clis/weread-official/utils.js +1 -293
- package/clis/wikidata/entity.js +1 -60
- package/clis/wikidata/search.js +1 -50
- package/clis/wikidata/utils.js +1 -117
- package/clis/wikipedia/page.js +2 -94
- package/clis/wikipedia/random.js +1 -20
- package/clis/wikipedia/search.js +1 -31
- package/clis/wikipedia/summary.js +1 -24
- package/clis/wikipedia/trending.js +1 -40
- package/clis/wikipedia/utils.js +1 -31
- package/clis/wordpress/publish.js +1 -0
- package/clis/wordpress/shared.js +1 -0
- package/clis/wordpress/whoami.js +1 -0
- package/clis/woshipm/article.js +1 -301
- package/clis/woshipm/login.js +1 -15
- package/clis/woshipm/stats.js +52 -0
- package/clis/woshipm/whoami.js +1 -34
- package/clis/wttr/current.js +1 -63
- package/clis/wttr/forecast.js +1 -71
- package/clis/wttr/utils.js +1 -50
- package/clis/xianyu/auth.js +2 -59
- package/clis/xianyu/chat.js +1 -74
- package/clis/xianyu/im.js +13 -95
- package/clis/xianyu/inbox.js +1 -96
- package/clis/xianyu/item.js +5 -61
- package/clis/xianyu/messages.js +1 -91
- package/clis/xianyu/publish.js +19 -299
- package/clis/xianyu/reply.js +1 -82
- package/clis/xianyu/search.js +8 -129
- package/clis/xianyu/utils.js +1 -8
- package/clis/xiaoe/auth.js +2 -47
- package/clis/xiaoe/catalog.js +2 -95
- package/clis/xiaoe/content.js +2 -161
- package/clis/xiaoe/courses.js +2 -86
- package/clis/xiaoe/detail.js +2 -19
- package/clis/xiaoe/play-url.js +2 -26
- package/clis/xiaohongshu/ask.js +8 -304
- package/clis/xiaohongshu/auth.js +2 -42
- package/clis/xiaohongshu/collection-helpers.js +5 -224
- package/clis/xiaohongshu/comments.js +5 -144
- package/clis/xiaohongshu/creator-note-detail.js +7 -409
- package/clis/xiaohongshu/creator-notes-summary.js +1 -98
- package/clis/xiaohongshu/creator-notes.js +13 -385
- package/clis/xiaohongshu/creator-profile.js +2 -44
- package/clis/xiaohongshu/creator-stats.js +2 -65
- package/clis/xiaohongshu/delete-note.js +7 -207
- package/clis/xiaohongshu/download.js +4 -71
- package/clis/xiaohongshu/draft-clear.js +5 -52
- package/clis/xiaohongshu/draft-delete.js +9 -75
- package/clis/xiaohongshu/draft-open.js +1 -43
- package/clis/xiaohongshu/draft-utils.js +5 -111
- package/clis/xiaohongshu/drafts.js +1 -28
- package/clis/xiaohongshu/feed.js +2 -127
- package/clis/xiaohongshu/follow.js +3 -154
- package/clis/xiaohongshu/liked.js +1 -29
- package/clis/xiaohongshu/note-helpers.js +1 -69
- package/clis/xiaohongshu/note.js +2 -74
- package/clis/xiaohongshu/notifications.js +1 -46
- package/clis/xiaohongshu/publish-video.js +87 -0
- package/clis/xiaohongshu/publish.js +54 -910
- package/clis/xiaohongshu/saved.js +1 -29
- package/clis/xiaohongshu/search.js +8 -194
- package/clis/xiaohongshu/unfollow.js +5 -192
- package/clis/xiaohongshu/user-helpers.js +1 -78
- package/clis/xiaohongshu/user.js +2 -112
- package/clis/xiaoyuzhou/auth.js +3 -303
- package/clis/xiaoyuzhou/download.js +1 -54
- package/clis/xiaoyuzhou/episode.js +1 -34
- package/clis/xiaoyuzhou/podcast-episodes.js +1 -41
- package/clis/xiaoyuzhou/podcast.js +1 -33
- package/clis/xiaoyuzhou/transcript.js +1 -77
- package/clis/xiaoyuzhou/utils.js +1 -15
- package/clis/xueqiu/article.js +4 -388
- package/clis/xueqiu/auth.js +2 -38
- package/clis/xueqiu/comments.js +4 -321
- package/clis/xueqiu/danjuan-utils.js +4 -46
- package/clis/xueqiu/earnings-date.js +1 -45
- package/clis/xueqiu/events.js +17 -58
- package/clis/xueqiu/feed.js +1 -39
- package/clis/xueqiu/fund-holdings.js +1 -29
- package/clis/xueqiu/fund-snapshot.js +1 -26
- package/clis/xueqiu/groups.js +1 -23
- package/clis/xueqiu/hashtags.js +26 -71
- package/clis/xueqiu/hot-stock.js +1 -32
- package/clis/xueqiu/hot.js +1 -37
- package/clis/xueqiu/kline.js +1 -44
- package/clis/xueqiu/search.js +1 -37
- package/clis/xueqiu/stock.js +1 -65
- package/clis/xueqiu/stocks.js +13 -49
- package/clis/xueqiu/users.js +12 -48
- package/clis/xueqiu/utils.js +3 -42
- package/clis/xueqiu/watchlist.js +1 -37
- package/clis/yahoo/search.js +3 -74
- package/clis/yahoo-finance/quote.js +3 -27
- package/clis/yollomi/background.js +1 -46
- package/clis/yollomi/edit.js +1 -57
- package/clis/yollomi/face-swap.js +1 -44
- package/clis/yollomi/generate.js +1 -101
- package/clis/yollomi/models.js +1 -34
- package/clis/yollomi/object-remover.js +1 -43
- package/clis/yollomi/remove-bg.js +1 -39
- package/clis/yollomi/restore.js +1 -39
- package/clis/yollomi/try-on.js +1 -47
- package/clis/yollomi/upload.js +4 -59
- package/clis/yollomi/upscale.js +1 -54
- package/clis/yollomi/utils.js +4 -168
- package/clis/yollomi/video.js +1 -57
- package/clis/youdao/note.js +5 -150
- package/clis/youtube/auth.js +2 -36
- package/clis/youtube/channel.js +4 -113
- package/clis/youtube/comments.js +4 -36
- package/clis/youtube/feed.js +3 -35
- package/clis/youtube/history.js +3 -35
- package/clis/youtube/like.js +5 -39
- package/clis/youtube/playlist.js +7 -58
- package/clis/youtube/publish.js +56 -0
- package/clis/youtube/search.js +3 -64
- package/clis/youtube/subscribe.js +7 -41
- package/clis/youtube/subscriptions.js +4 -36
- package/clis/youtube/transcript-group.js +2 -226
- package/clis/youtube/transcript.js +13 -252
- package/clis/youtube/unlike.js +5 -39
- package/clis/youtube/unsubscribe.js +7 -41
- package/clis/youtube/utils.js +4 -190
- package/clis/youtube/video.js +4 -60
- package/clis/youtube/watch-later.js +6 -42
- package/clis/yuanbao/ask.js +25 -242
- package/clis/yuanbao/auth.js +2 -38
- package/clis/yuanbao/detail.js +1 -65
- package/clis/yuanbao/history.js +1 -51
- package/clis/yuanbao/new.js +4 -60
- package/clis/yuanbao/read.js +1 -38
- package/clis/yuanbao/send.js +1 -57
- package/clis/yuanbao/shared.js +10 -224
- package/clis/yuanbao/status.js +1 -44
- package/clis/yuque/article.js +1 -293
- package/clis/yuque/whoami.js +1 -60
- package/clis/zhihu/answer-comments.js +3 -272
- package/clis/zhihu/answer-detail.js +3 -208
- package/clis/zhihu/answer.js +4 -43
- package/clis/zhihu/article-transform.js +1 -100
- package/clis/zhihu/article.js +6 -129
- package/clis/zhihu/auth.js +2 -50
- package/clis/zhihu/collection.js +3 -195
- package/clis/zhihu/collections.js +3 -124
- package/clis/zhihu/comment.js +5 -43
- package/clis/zhihu/download.js +2 -43
- package/clis/zhihu/favorite.js +6 -54
- package/clis/zhihu/follow.js +4 -35
- package/clis/zhihu/followers.js +1 -40
- package/clis/zhihu/following.js +1 -40
- package/clis/zhihu/hot.js +2 -25
- package/clis/zhihu/like.js +4 -35
- package/clis/zhihu/paginate.js +3 -120
- package/clis/zhihu/pin.js +4 -59
- package/clis/zhihu/pins.js +1 -41
- package/clis/zhihu/question.js +3 -109
- package/clis/zhihu/recommend.js +3 -99
- package/clis/zhihu/search.js +3 -198
- package/clis/zhihu/stats.js +41 -0
- package/clis/zhihu/target.js +1 -91
- package/clis/zhihu/text.js +4 -27
- package/clis/zhihu/user-answers.js +1 -41
- package/clis/zhihu/user-arg.js +1 -34
- package/clis/zhihu/user-articles.js +1 -40
- package/clis/zhihu/user.js +3 -51
- package/clis/zhihu/write-shared.js +7 -176
- package/clis/zlibrary/info.js +1 -48
- package/clis/zlibrary/search.js +1 -47
- package/clis/zlibrary/utils.js +6 -94
- package/clis/zsxq/auth.js +3 -38
- package/clis/zsxq/dynamics.js +1 -48
- package/clis/zsxq/groups.js +1 -33
- package/clis/zsxq/search.js +1 -44
- package/clis/zsxq/topic.js +1 -50
- package/clis/zsxq/topics.js +1 -26
- package/clis/zsxq/utils.js +5 -166
- package/dist/src/adapter-shadow.js +2 -72
- package/dist/src/adapter-source.js +1 -24
- package/dist/src/browser/analyze.js +1 -405
- package/dist/src/browser/article-extract.js +2 -169
- package/dist/src/browser/ax-snapshot.js +2 -217
- package/dist/src/browser/base-page.js +26 -861
- package/dist/src/browser/bridge-readiness.js +1 -24
- package/dist/src/browser/bridge.js +1 -58
- package/dist/src/browser/cdp.d.ts +5 -0
- package/dist/src/browser/cdp.js +1 -536
- package/dist/src/browser/compound.js +2 -32
- package/dist/src/browser/config.js +1 -14
- package/dist/src/browser/daemon-client.js +1 -135
- package/dist/src/browser/daemon-lifecycle.js +12 -150
- package/dist/src/browser/daemon-transport.js +1 -68
- package/dist/src/browser/daemon-version.js +2 -12
- package/dist/src/browser/dom-helpers.js +36 -109
- package/dist/src/browser/dom-snapshot.js +21 -106
- package/dist/src/browser/errors.js +5 -78
- package/dist/src/browser/extract.js +6 -96
- package/dist/src/browser/find.js +13 -83
- package/dist/src/browser/fingerprint.d.ts +44 -0
- package/dist/src/browser/fingerprint.js +82 -0
- package/dist/src/browser/html-tree.js +7 -58
- package/dist/src/browser/index.js +1 -12
- package/dist/src/browser/managed-chrome.d.ts +89 -0
- package/dist/src/browser/managed-chrome.js +1 -0
- package/dist/src/browser/network-cache.js +1 -78
- package/dist/src/browser/network-key.js +1 -66
- package/dist/src/browser/page.js +7 -445
- package/dist/src/browser/profile.d.ts +82 -0
- package/dist/src/browser/profile.js +2 -85
- package/dist/src/browser/proxy-test.d.ts +28 -0
- package/dist/src/browser/proxy-test.js +12 -0
- package/dist/src/browser/shape-filter.js +1 -101
- package/dist/src/browser/shape.js +1 -95
- package/dist/src/browser/stealth.js +2 -25
- package/dist/src/browser/tabs.js +2 -70
- package/dist/src/browser/target-errors.js +1 -45
- package/dist/src/browser/target-resolver.js +27 -174
- package/dist/src/browser/trace.js +2 -91
- package/dist/src/browser/utils.js +1 -64
- package/dist/src/browser/verify-fixture.js +2 -318
- package/dist/src/browser/visual-refs.js +6 -20
- package/dist/src/browser-session-lock.d.ts +13 -0
- package/dist/src/browser-session-lock.js +1 -0
- package/dist/src/browser-session-lock.test.d.ts +1 -0
- package/dist/src/build-manifest.js +15 -362
- package/dist/src/capabilityRouting.js +1 -56
- package/dist/src/cli-argv-preprocess.js +1 -303
- package/dist/src/cli.js +29 -3319
- package/dist/src/commanderAdapter.js +3 -210
- package/dist/src/commands/auth.js +2 -434
- package/dist/src/commands/daemon.d.ts +16 -0
- package/dist/src/commands/daemon.js +1 -98
- package/dist/src/completion-fast.js +1 -88
- package/dist/src/completion-shared.js +4 -34
- package/dist/src/completion.js +1 -68
- package/dist/src/constants.js +1 -38
- package/dist/src/convention-audit.js +2 -553
- package/dist/src/daemon-utils.js +1 -37
- package/dist/src/daemon.js +1 -455
- package/dist/src/discovery.js +2 -280
- package/dist/src/doctor.js +17 -230
- package/dist/src/download/article-download.js +21 -305
- package/dist/src/download/index.js +7 -369
- package/dist/src/download/media-download.js +1 -127
- package/dist/src/download/progress.js +5 -120
- package/dist/src/electron-apps.js +1 -91
- package/dist/src/errors.js +2 -193
- package/dist/src/execution.js +2 -513
- package/dist/src/external.js +1 -227
- package/dist/src/help.js +8 -555
- package/dist/src/hooks.js +1 -58
- package/dist/src/interceptor.js +25 -85
- package/dist/src/launcher.d.ts +1 -1
- package/dist/src/launcher.js +7 -232
- package/dist/src/logger.js +9 -49
- package/dist/src/main.js +9 -175
- package/dist/src/manifest-types.js +1 -9
- package/dist/src/node-network.js +1 -177
- package/dist/src/observation/artifact.js +8 -260
- package/dist/src/observation/events.js +1 -1
- package/dist/src/observation/index.js +1 -7
- package/dist/src/observation/manager.js +1 -27
- package/dist/src/observation/redaction.js +2 -81
- package/dist/src/observation/retention.js +1 -160
- package/dist/src/observation/ring-buffer.js +1 -45
- package/dist/src/observation/session.js +1 -50
- package/dist/src/output.js +2 -159
- package/dist/src/package-paths.js +1 -41
- package/dist/src/pipeline/executor.js +1 -93
- package/dist/src/pipeline/index.js +1 -5
- package/dist/src/pipeline/registry.js +1 -55
- package/dist/src/pipeline/steps/browser.js +1 -86
- package/dist/src/pipeline/steps/download.js +1 -252
- package/dist/src/pipeline/steps/fetch.js +6 -112
- package/dist/src/pipeline/steps/intercept.js +1 -50
- package/dist/src/pipeline/steps/tap.js +17 -57
- package/dist/src/pipeline/steps/transform.js +1 -97
- package/dist/src/pipeline/template.js +1 -354
- package/dist/src/plugin-manifest.js +1 -160
- package/dist/src/plugin-scaffold.js +19 -87
- package/dist/src/plugin.js +20 -1250
- package/dist/src/rate-limit.js +2 -125
- package/dist/src/registry-api.js +1 -10
- package/dist/src/registry.js +1 -125
- package/dist/src/runtime-detect.js +1 -47
- package/dist/src/runtime.d.ts +10 -0
- package/dist/src/runtime.js +1 -54
- package/dist/src/scripts/framework.js +1 -25
- package/dist/src/scripts/interact.js +1 -20
- package/dist/src/scripts/store.js +1 -48
- package/dist/src/serialization.js +4 -102
- package/dist/src/skills.js +6 -127
- package/dist/src/snapshotFormatter.js +3 -338
- package/dist/src/tui.js +16 -179
- package/dist/src/types.js +1 -7
- package/dist/src/update-check.js +8 -202
- package/dist/src/utils.js +6 -120
- package/dist/src/validate.js +3 -129
- package/dist/src/verify.js +2 -71
- package/dist/src/version.js +1 -22
- package/package.json +7 -4
- package/scripts/minify-release.mjs +115 -0
- package/clis/12306/utils.test.js +0 -424
- package/clis/1688/assets.test.js +0 -39
- package/clis/1688/download.test.js +0 -31
- package/clis/1688/item.test.js +0 -67
- package/clis/1688/search.test.js +0 -75
- package/clis/1688/shared.test.js +0 -57
- package/clis/1688/store.test.js +0 -62
- package/clis/36kr/article.test.js +0 -46
- package/clis/36kr/hot.test.js +0 -15
- package/clis/36kr/news.test.js +0 -85
- package/clis/51job/utils.test.js +0 -69
- package/clis/_atlassian/shared.test.js +0 -170
- package/clis/_shared/article/auth.test.js +0 -98
- package/clis/_shared/article/format.test.js +0 -68
- package/clis/_shared/article/images.test.js +0 -182
- package/clis/_shared/article/page-runtime.test.js +0 -155
- package/clis/_shared/article/publish.test.js +0 -104
- package/clis/_shared/site-auth.test.js +0 -98
- package/clis/aibase/news.test.js +0 -59
- package/clis/amazon/bestsellers.test.js +0 -29
- package/clis/amazon/discussion.test.js +0 -124
- package/clis/amazon/offer.test.js +0 -29
- package/clis/amazon/product.test.js +0 -24
- package/clis/amazon/rankings.test.js +0 -41
- package/clis/amazon/search.test.js +0 -22
- package/clis/amazon/shared.test.js +0 -44
- package/clis/antigravity/antigravity.test.js +0 -172
- package/clis/apple-podcasts/commands.test.js +0 -119
- package/clis/apple-podcasts/utils.test.js +0 -57
- package/clis/archive/archive.test.js +0 -262
- package/clis/arxiv/arxiv.test.js +0 -112
- package/clis/autohome/autohome.test.js +0 -115
- package/clis/baidu-scholar/search.test.js +0 -23
- package/clis/baijiahao/article.test.js +0 -395
- package/clis/barchart/greeks.test.js +0 -138
- package/clis/bilibili/article.test.js +0 -384
- package/clis/bilibili/comment.test.js +0 -153
- package/clis/bilibili/comments.test.js +0 -142
- package/clis/bilibili/download.test.js +0 -173
- package/clis/bilibili/dynamic.test.js +0 -68
- package/clis/bilibili/follow.test.js +0 -203
- package/clis/bilibili/hot.test.js +0 -17
- package/clis/bilibili/subtitle.test.js +0 -240
- package/clis/bilibili/summary.test.js +0 -210
- package/clis/bilibili/utils.test.js +0 -97
- package/clis/bilibili/video.test.js +0 -308
- package/clis/binance/commands.test.js +0 -70
- package/clis/bloomberg/businessweek.test.js +0 -149
- package/clis/bloomberg/utils.test.js +0 -129
- package/clis/bluesky/feeds.js +0 -28
- package/clis/bluesky/followers.js +0 -28
- package/clis/bluesky/following.js +0 -28
- package/clis/bluesky/profile.js +0 -30
- package/clis/bluesky/search.js +0 -29
- package/clis/bluesky/starter-packs.js +0 -29
- package/clis/bluesky/thread.js +0 -31
- package/clis/bluesky/trending.js +0 -20
- package/clis/bluesky/user.js +0 -35
- package/clis/booking/booking.test.js +0 -356
- package/clis/boss/chatlist.test.js +0 -211
- package/clis/boss/chatmsg.test.js +0 -230
- package/clis/boss/search.test.js +0 -78
- package/clis/boss/utils.test.js +0 -34
- package/clis/brave/search.test.js +0 -76
- package/clis/chaoxing/utils.test.js +0 -45
- package/clis/chatgpt/commands.test.js +0 -204
- package/clis/chatgpt/envelope.test.js +0 -108
- package/clis/chatgpt/image.test.js +0 -207
- package/clis/chatgpt/model.test.js +0 -36
- package/clis/chatgpt/utils.test.js +0 -1453
- package/clis/chatgpt-app/ax.test.js +0 -95
- package/clis/chatgpt-app/commands.test.js +0 -45
- package/clis/chatwise/composer.test.js +0 -186
- package/clis/chess/analyze.test.js +0 -79
- package/clis/chess/game.test.js +0 -178
- package/clis/chess/games.test.js +0 -164
- package/clis/chess/stats.test.js +0 -79
- package/clis/chess/utils.test.js +0 -230
- package/clis/claude/ask.test.js +0 -338
- package/clis/claude/commands.test.js +0 -118
- package/clis/claude/utils.test.js +0 -148
- package/clis/cnblogs/article.test.js +0 -346
- package/clis/cnki/search.test.js +0 -18
- package/clis/codex/sidebar.test.js +0 -388
- package/clis/coingecko/coingecko.test.js +0 -109
- package/clis/confluence/commands.test.js +0 -195
- package/clis/coupang/coupang.test.js +0 -159
- package/clis/coupang/utils.test.js +0 -62
- package/clis/csdn/article.test.js +0 -378
- package/clis/cto51/article.test.js +0 -326
- package/clis/ctrip/ctrip.test.js +0 -719
- package/clis/dblp/dblp.test.js +0 -397
- package/clis/deepseek/ask.test.js +0 -399
- package/clis/deepseek/detail.test.js +0 -81
- package/clis/deepseek/send.test.js +0 -107
- package/clis/deepseek/utils.test.js +0 -370
- package/clis/defillama/defillama.test.js +0 -99
- package/clis/devto/devto.test.js +0 -236
- package/clis/dianping/dianping.test.js +0 -578
- package/clis/discord-app/commands.test.js +0 -395
- package/clis/dongchedi/dongchedi.test.js +0 -191
- package/clis/douban/article.test.js +0 -136
- package/clis/douban/download.test.js +0 -170
- package/clis/douban/movie-hot.test.js +0 -14
- package/clis/douban/search.test.js +0 -11
- package/clis/douban/subject.test.js +0 -11
- package/clis/douban/utils.test.js +0 -488
- package/clis/doubao/detail.test.js +0 -42
- package/clis/doubao/history.test.js +0 -37
- package/clis/doubao/utils.test.js +0 -396
- package/clis/douyin/_shared/browser-fetch.test.js +0 -64
- package/clis/douyin/_shared/creation-id.test.js +0 -22
- package/clis/douyin/_shared/imagex-upload.test.js +0 -87
- package/clis/douyin/_shared/sts2.test.js +0 -27
- package/clis/douyin/_shared/text-extra.test.js +0 -37
- package/clis/douyin/_shared/timing.test.js +0 -28
- package/clis/douyin/_shared/tos-upload-short-read.test.js +0 -83
- package/clis/douyin/_shared/tos-upload.test.js +0 -229
- package/clis/douyin/_shared/transcode.test.js +0 -91
- package/clis/douyin/_shared/vod-upload.test.js +0 -38
- package/clis/douyin/activities.test.js +0 -55
- package/clis/douyin/collections.test.js +0 -45
- package/clis/douyin/delete.test.js +0 -100
- package/clis/douyin/draft.test.js +0 -347
- package/clis/douyin/drafts.test.js +0 -11
- package/clis/douyin/hashtag.test.js +0 -171
- package/clis/douyin/location.test.js +0 -23
- package/clis/douyin/profile.test.js +0 -46
- package/clis/douyin/publish-upload-id.test.js +0 -206
- package/clis/douyin/publish.test.js +0 -38
- package/clis/douyin/search.test.js +0 -307
- package/clis/douyin/stats.test.js +0 -22
- package/clis/douyin/update.test.js +0 -11
- package/clis/douyin/user-videos.test.js +0 -151
- package/clis/douyin/videos.test.js +0 -54
- package/clis/duckduckgo/search.test.js +0 -128
- package/clis/duckduckgo/suggest.test.js +0 -66
- package/clis/eastmoney/article.test.js +0 -427
- package/clis/eastmoney/hot-rank.test.js +0 -59
- package/clis/endoflife/endoflife.test.js +0 -51
- package/clis/facebook/feed.test.js +0 -169
- package/clis/facebook/marketplace.test.js +0 -91
- package/clis/facebook/notifications.test.js +0 -458
- package/clis/facebook/search.test.js +0 -55
- package/clis/flathub/flathub.test.js +0 -90
- package/clis/flomo/memos.test.js +0 -144
- package/clis/gemini/ask.test.js +0 -100
- package/clis/gemini/commands.test.js +0 -212
- package/clis/gemini/deep-research-result.test.js +0 -155
- package/clis/gemini/deep-research.test.js +0 -181
- package/clis/gemini/reply-state.test.js +0 -671
- package/clis/gemini/utils.test.js +0 -392
- package/clis/geogebra/geogebra.test.js +0 -175
- package/clis/gitee/search.test.js +0 -65
- package/clis/gitee/user.test.js +0 -63
- package/clis/github-trending/repos.test.js +0 -149
- package/clis/google/utils.test.js +0 -75
- package/clis/google-scholar/cite.test.js +0 -47
- package/clis/google-scholar/profile.test.js +0 -49
- package/clis/google-scholar/search.test.js +0 -71
- package/clis/goproxy/goproxy.test.js +0 -103
- package/clis/gov-law/commands.test.js +0 -39
- package/clis/gov-policy/gov-policy.test.js +0 -224
- package/clis/grok/ask.test.js +0 -29
- package/clis/grok/export.test.js +0 -210
- package/clis/grok/utils.test.js +0 -141
- package/clis/guazi/guazi.test.js +0 -126
- package/clis/hackernews/hackernews.test.js +0 -132
- package/clis/hf/hf.test.js +0 -16
- package/clis/huodongxing/events.test.js +0 -296
- package/clis/hupu/hot.test.js +0 -224
- package/clis/imdb/utils.test.js +0 -88
- package/clis/imooc/article.test.js +0 -264
- package/clis/indeed/indeed.test.js +0 -375
- package/clis/instagram/_shared/private-publish.test.js +0 -705
- package/clis/instagram/_shared/protocol-capture.test.js +0 -114
- package/clis/instagram/detail.test.js +0 -137
- package/clis/instagram/download.test.js +0 -118
- package/clis/instagram/instagram.test.js +0 -381
- package/clis/instagram/note.test.js +0 -53
- package/clis/instagram/post.test.js +0 -1647
- package/clis/instagram/reel.test.js +0 -167
- package/clis/instagram/story.test.js +0 -134
- package/clis/instagram/user.test.js +0 -282
- package/clis/jd/commands.test.js +0 -41
- package/clis/jd/item.test.js +0 -354
- package/clis/jianyu/search.test.js +0 -153
- package/clis/jianyu/shared/procurement-contract.test.js +0 -72
- package/clis/jianyu/shared/procurement-detail.test.js +0 -84
- package/clis/jike/read.test.js +0 -86
- package/clis/jira/commands.test.js +0 -287
- package/clis/juejin/article.test.js +0 -299
- package/clis/juejin/juejin.test.js +0 -241
- package/clis/kimi/kimi.test.js +0 -187
- package/clis/lesswrong/frontpage.test.js +0 -37
- package/clis/lichess/lichess.test.js +0 -85
- package/clis/linkedin/connect.test.js +0 -328
- package/clis/linkedin/inbox.test.js +0 -152
- package/clis/linkedin/job-detail.test.js +0 -64
- package/clis/linkedin/jobs-preferences.test.js +0 -43
- package/clis/linkedin/people-search.test.js +0 -216
- package/clis/linkedin/post-analytics.test.js +0 -40
- package/clis/linkedin/posts.test.js +0 -40
- package/clis/linkedin/profile-analytics.test.js +0 -67
- package/clis/linkedin/profile-experience.test.js +0 -152
- package/clis/linkedin/profile-projects.test.js +0 -111
- package/clis/linkedin/profile-read.test.js +0 -77
- package/clis/linkedin/safe-send.test.js +0 -255
- package/clis/linkedin/salesnav-inbox.test.js +0 -113
- package/clis/linkedin/salesnav-message.test.js +0 -172
- package/clis/linkedin/salesnav-search.test.js +0 -76
- package/clis/linkedin/salesnav-thread.test.js +0 -79
- package/clis/linkedin/search.test.js +0 -222
- package/clis/linkedin/sent-invitations.test.js +0 -62
- package/clis/linkedin/services-read.test.js +0 -105
- package/clis/linkedin/thread-snapshot.test.js +0 -89
- package/clis/linkedin/timeline.test.js +0 -81
- package/clis/linkedin-learning/course.test.js +0 -114
- package/clis/linkedin-learning/search.test.js +0 -144
- package/clis/linkedin-learning/trending.test.js +0 -123
- package/clis/linux-do/feed.test.js +0 -153
- package/clis/linux-do/topic-content.test.js +0 -59
- package/clis/lobsters/lobsters.test.js +0 -169
- package/clis/maimai/search-talents.test.js +0 -29
- package/clis/manus/manus.test.js +0 -382
- package/clis/notebooklm/add-source.test.js +0 -97
- package/clis/notebooklm/compat.test.js +0 -16
- package/clis/notebooklm/create.test.js +0 -58
- package/clis/notebooklm/generate-audio.test.js +0 -63
- package/clis/notebooklm/generate-slides.test.js +0 -75
- package/clis/notebooklm/history.test.js +0 -58
- package/clis/notebooklm/note-list.test.js +0 -56
- package/clis/notebooklm/notes-get.test.js +0 -72
- package/clis/notebooklm/open.test.js +0 -63
- package/clis/notebooklm/rpc.test.js +0 -131
- package/clis/notebooklm/source-fulltext.test.js +0 -106
- package/clis/notebooklm/source-get.test.js +0 -84
- package/clis/notebooklm/source-guide.test.js +0 -104
- package/clis/notebooklm/summary.test.js +0 -78
- package/clis/notebooklm/utils.test.js +0 -449
- package/clis/notebooklm/write-note.test.js +0 -70
- package/clis/nuget/nuget.test.js +0 -111
- package/clis/oeis/oeis.test.js +0 -88
- package/clis/ones/task-helpers.test.js +0 -12
- package/clis/ones/worklog.test.js +0 -20
- package/clis/openfda/openfda.test.js +0 -114
- package/clis/openreview/openreview.test.js +0 -427
- package/clis/oschina/article.test.js +0 -361
- package/clis/osv/osv.test.js +0 -97
- package/clis/paperreview/commands.test.js +0 -243
- package/clis/paperreview/utils.test.js +0 -49
- package/clis/pixiv/detail.test.js +0 -93
- package/clis/pixiv/download.test.js +0 -97
- package/clis/pixiv/illusts.test.js +0 -99
- package/clis/pixiv/search.test.js +0 -83
- package/clis/pixiv/user.test.js +0 -100
- package/clis/powerchina/search.test.js +0 -93
- package/clis/producthunt/utils.test.js +0 -64
- package/clis/pubmed/pubmed.test.js +0 -464
- package/clis/qoder/qoder.test.js +0 -125
- package/clis/quark/utils.test.js +0 -58
- package/clis/qwen/ask.test.js +0 -36
- package/clis/qwen/utils.test.js +0 -128
- package/clis/reddit/extract-media.test.js +0 -149
- package/clis/reddit/frontpage.test.js +0 -34
- package/clis/reddit/home.test.js +0 -170
- package/clis/reddit/hot.test.js +0 -32
- package/clis/reddit/popular.test.js +0 -26
- package/clis/reddit/read.test.js +0 -402
- package/clis/reddit/reply.test.js +0 -89
- package/clis/reddit/search.test.js +0 -26
- package/clis/reddit/subreddit-info.test.js +0 -163
- package/clis/reddit/subreddit.test.js +0 -31
- package/clis/reddit/subscribed.test.js +0 -168
- package/clis/reddit/whoami.test.js +0 -105
- package/clis/rednote/navigation.test.js +0 -26
- package/clis/rednote/rednote.test.js +0 -240
- package/clis/rest-countries/rest-countries.test.js +0 -83
- package/clis/reuters/reuters.test.js +0 -299
- package/clis/rfc/rfc.test.js +0 -74
- package/clis/segmentfault/article.test.js +0 -470
- package/clis/semanticscholar/semanticscholar.test.js +0 -279
- package/clis/sinafinance/stock.test.js +0 -59
- package/clis/slock/api-base-canary.test.js +0 -62
- package/clis/slock/attachment-download.test.js +0 -102
- package/clis/slock/attachment-upload.test.js +0 -131
- package/clis/slock/attachment-url.test.js +0 -41
- package/clis/slock/bookmark-add.test.js +0 -38
- package/clis/slock/bookmark-list.test.js +0 -47
- package/clis/slock/bookmark-remove.test.js +0 -24
- package/clis/slock/channel-action.test.js +0 -65
- package/clis/slock/channel-create.test.js +0 -40
- package/clis/slock/channel-files.test.js +0 -32
- package/clis/slock/channel-info.test.js +0 -25
- package/clis/slock/channel-list.test.js +0 -37
- package/clis/slock/channel-mark.test.js +0 -49
- package/clis/slock/channel-members.test.js +0 -44
- package/clis/slock/cross-command.test.js +0 -21
- package/clis/slock/dm-list.test.js +0 -26
- package/clis/slock/error-detail-canary.test.js +0 -144
- package/clis/slock/errors.test.js +0 -29
- package/clis/slock/in-page.test.js +0 -362
- package/clis/slock/inbox-done.test.js +0 -21
- package/clis/slock/inbox-read-all.test.js +0 -20
- package/clis/slock/inbox.test.js +0 -46
- package/clis/slock/message-read.test.js +0 -83
- package/clis/slock/message-search.test.js +0 -61
- package/clis/slock/message-send.test.js +0 -127
- package/clis/slock/reaction-add.test.js +0 -36
- package/clis/slock/reaction-remove.test.js +0 -29
- package/clis/slock/resolve.test.js +0 -102
- package/clis/slock/server-list.test.js +0 -24
- package/clis/slock/server-override-canary.test.js +0 -87
- package/clis/slock/server-use.test.js +0 -48
- package/clis/slock/short-id-canary.test.js +0 -86
- package/clis/slock/site-session-canary.test.js +0 -49
- package/clis/slock/task-claim.test.js +0 -81
- package/clis/slock/task-convert.test.js +0 -82
- package/clis/slock/task-create.test.js +0 -65
- package/clis/slock/task-delete.test.js +0 -52
- package/clis/slock/task-get.test.js +0 -45
- package/clis/slock/task-list-server.test.js +0 -48
- package/clis/slock/task-list.test.js +0 -59
- package/clis/slock/task-status.test.js +0 -76
- package/clis/slock/task-unclaim.test.js +0 -49
- package/clis/slock/thread-follow.test.js +0 -34
- package/clis/slock/thread-list.test.js +0 -24
- package/clis/slock/thread-state.test.js +0 -38
- package/clis/slock/unread-summary.test.js +0 -31
- package/clis/slock/whoami.test.js +0 -23
- package/clis/smzdm/search.test.js +0 -114
- package/clis/sohu/article.test.js +0 -397
- package/clis/spotify/utils.test.js +0 -67
- package/clis/stackoverflow/stackoverflow.test.js +0 -404
- package/clis/steam/steam.test.js +0 -46
- package/clis/substack/utils.test.js +0 -44
- package/clis/suno/commands.test.js +0 -188
- package/clis/suno/download.test.js +0 -151
- package/clis/suno/generate.test.js +0 -252
- package/clis/suno/utils.test.js +0 -329
- package/clis/taobao/commands.test.js +0 -41
- package/clis/tdx/hot-rank.test.js +0 -59
- package/clis/ths/hot-rank.test.js +0 -64
- package/clis/tieba/commands.test.js +0 -79
- package/clis/tieba/utils.test.js +0 -290
- package/clis/tiktok/creator-videos.test.js +0 -113
- package/clis/tiktok/refactor.test.js +0 -389
- package/clis/tiktok/write-refactor.test.js +0 -370
- package/clis/toutiao/toutiao.test.js +0 -378
- package/clis/trae-cn/trae-cn.test.js +0 -412
- package/clis/trae-solo/trae-solo.test.js +0 -67
- package/clis/tvmaze/tvmaze.test.js +0 -93
- package/clis/twitter/bookmark-folder.test.js +0 -396
- package/clis/twitter/bookmark-folders.test.js +0 -152
- package/clis/twitter/bookmark.test.js +0 -74
- package/clis/twitter/bookmarks.test.js +0 -206
- package/clis/twitter/delete.test.js +0 -103
- package/clis/twitter/device-follow.test.js +0 -287
- package/clis/twitter/download.test.js +0 -457
- package/clis/twitter/follow-batch.test.js +0 -137
- package/clis/twitter/followers.test.js +0 -62
- package/clis/twitter/following.test.js +0 -359
- package/clis/twitter/hide-reply.test.js +0 -76
- package/clis/twitter/like.test.js +0 -73
- package/clis/twitter/likes.test.js +0 -220
- package/clis/twitter/list-add.test.js +0 -133
- package/clis/twitter/list-batch.test.js +0 -113
- package/clis/twitter/list-create.test.js +0 -169
- package/clis/twitter/list-delete.test.js +0 -102
- package/clis/twitter/list-remove.test.js +0 -147
- package/clis/twitter/list-tweets.test.js +0 -198
- package/clis/twitter/lists.test.js +0 -253
- package/clis/twitter/post.test.js +0 -334
- package/clis/twitter/profile.test.js +0 -150
- package/clis/twitter/quote.test.js +0 -230
- package/clis/twitter/reply.test.js +0 -237
- package/clis/twitter/retweet.test.js +0 -73
- package/clis/twitter/schedule.test.js +0 -86
- package/clis/twitter/scheduled-delete.test.js +0 -58
- package/clis/twitter/scheduled-list.test.js +0 -36
- package/clis/twitter/search.test.js +0 -400
- package/clis/twitter/shared.test.js +0 -1012
- package/clis/twitter/thread.test.js +0 -58
- package/clis/twitter/timeline.test.js +0 -104
- package/clis/twitter/trending.test.js +0 -15
- package/clis/twitter/tweets.test.js +0 -487
- package/clis/twitter/unbookmark.test.js +0 -73
- package/clis/twitter/unlike.test.js +0 -75
- package/clis/twitter/unretweet.test.js +0 -73
- package/clis/twitter/utils.test.js +0 -169
- package/clis/uisdc/news.test.js +0 -66
- package/clis/uiverse/_shared.test.js +0 -62
- package/clis/uiverse/navigation.test.js +0 -12
- package/clis/upwork/upwork.test.js +0 -566
- package/clis/wanfang/search.test.js +0 -23
- package/clis/web/read.test.js +0 -392
- package/clis/wechat-channels/publish.test.js +0 -144
- package/clis/weibo/delete.test.js +0 -94
- package/clis/weibo/envelope.test.js +0 -85
- package/clis/weibo/favorites.test.js +0 -114
- package/clis/weibo/publish.test.js +0 -192
- package/clis/weibo/user-posts.test.js +0 -92
- package/clis/weibo/utils.test.js +0 -36
- package/clis/weixin/article.test.js +0 -299
- package/clis/weixin/download.test.js +0 -106
- package/clis/weixin/drafts.test.js +0 -69
- package/clis/weixin/search.test.js +0 -227
- package/clis/weread/ai-outline.test.js +0 -83
- package/clis/weread/book-search.test.js +0 -242
- package/clis/weread/commands.test.js +0 -398
- package/clis/weread/private-api-regression.test.js +0 -369
- package/clis/weread/search-regression.test.js +0 -494
- package/clis/weread/utils.test.js +0 -128
- package/clis/weread-official/commands.test.js +0 -385
- package/clis/weread-official/utils.test.js +0 -242
- package/clis/wikidata/wikidata.test.js +0 -83
- package/clis/wikipedia/trending.test.js +0 -57
- package/clis/woshipm/article.test.js +0 -305
- package/clis/wttr/wttr.test.js +0 -84
- package/clis/xianyu/chat.test.js +0 -84
- package/clis/xianyu/im.test.js +0 -253
- package/clis/xianyu/item.test.js +0 -56
- package/clis/xianyu/publish.test.js +0 -220
- package/clis/xianyu/search.test.js +0 -104
- package/clis/xiaoe/xiaoe.test.js +0 -486
- package/clis/xiaohongshu/ask.test.js +0 -271
- package/clis/xiaohongshu/collection-helpers.test.js +0 -125
- package/clis/xiaohongshu/comments.test.js +0 -320
- package/clis/xiaohongshu/creator-note-detail.test.js +0 -451
- package/clis/xiaohongshu/creator-notes-summary.test.js +0 -94
- package/clis/xiaohongshu/creator-notes.test.js +0 -281
- package/clis/xiaohongshu/creator-stats.test.js +0 -24
- package/clis/xiaohongshu/delete-note.test.js +0 -177
- package/clis/xiaohongshu/download.test.js +0 -415
- package/clis/xiaohongshu/drafts.test.js +0 -172
- package/clis/xiaohongshu/feed.test.js +0 -126
- package/clis/xiaohongshu/follow.test.js +0 -211
- package/clis/xiaohongshu/liked.test.js +0 -82
- package/clis/xiaohongshu/navigation.test.js +0 -38
- package/clis/xiaohongshu/note.test.js +0 -249
- package/clis/xiaohongshu/publish.test.js +0 -1155
- package/clis/xiaohongshu/saved.test.js +0 -143
- package/clis/xiaohongshu/search.test.js +0 -394
- package/clis/xiaohongshu/user-helpers.test.js +0 -160
- package/clis/xiaohongshu/user.test.js +0 -141
- package/clis/xiaoyuzhou/auth.test.js +0 -124
- package/clis/xiaoyuzhou/download.test.js +0 -135
- package/clis/xiaoyuzhou/podcast-episodes.test.js +0 -78
- package/clis/xiaoyuzhou/transcript.test.js +0 -195
- package/clis/xiaoyuzhou/utils.test.js +0 -39
- package/clis/xueqiu/article.test.js +0 -505
- package/clis/xueqiu/comments.test.js +0 -696
- package/clis/xueqiu/danjuan-utils.test.js +0 -41
- package/clis/xueqiu/utils.test.js +0 -26
- package/clis/yahoo/search.test.js +0 -94
- package/clis/youdao/note.test.js +0 -99
- package/clis/youtube/channel.test.js +0 -283
- package/clis/youtube/feed.test.js +0 -131
- package/clis/youtube/transcript-group.test.js +0 -99
- package/clis/youtube/transcript.test.js +0 -296
- package/clis/youtube/utils.test.js +0 -84
- package/clis/youtube/video.test.js +0 -111
- package/clis/yuanbao/ask.test.js +0 -124
- package/clis/yuanbao/new.test.js +0 -30
- package/clis/yuanbao/shared.test.js +0 -80
- package/clis/yuque/article.test.js +0 -415
- package/clis/zhihu/answer-comments.test.js +0 -287
- package/clis/zhihu/answer-detail.test.js +0 -338
- package/clis/zhihu/answer.test.js +0 -54
- package/clis/zhihu/article-transform.test.js +0 -43
- package/clis/zhihu/collection.test.js +0 -337
- package/clis/zhihu/collections.test.js +0 -182
- package/clis/zhihu/comment.test.js +0 -50
- package/clis/zhihu/download.test.js +0 -12
- package/clis/zhihu/favorite.test.js +0 -59
- package/clis/zhihu/follow.test.js +0 -42
- package/clis/zhihu/followers.test.js +0 -42
- package/clis/zhihu/following.test.js +0 -44
- package/clis/zhihu/like.test.js +0 -41
- package/clis/zhihu/pins.test.js +0 -44
- package/clis/zhihu/question.test.js +0 -251
- package/clis/zhihu/recommend.test.js +0 -143
- package/clis/zhihu/search.test.js +0 -198
- package/clis/zhihu/target.test.js +0 -77
- package/clis/zhihu/text.test.js +0 -24
- package/clis/zhihu/user-answers.test.js +0 -69
- package/clis/zhihu/user-articles.test.js +0 -44
- package/clis/zhihu/user.test.js +0 -73
- package/clis/zhihu/write-shared.test.js +0 -179
- package/clis/zlibrary/commands.test.js +0 -65
- package/clis/zsxq/search.test.js +0 -24
- package/clis/zsxq/topic.test.js +0 -30
- package/clis/zsxq/topics.test.js +0 -24
- package/clis/zsxq/utils.test.js +0 -31
- package/dist/src/adapter-shadow.test.js +0 -49
- package/dist/src/adapter-source.test.js +0 -29
- package/dist/src/browser/analyze.test.js +0 -209
- package/dist/src/browser/article-extract.e2e.test.js +0 -105
- package/dist/src/browser/article-extract.test.js +0 -94
- package/dist/src/browser/ax-snapshot.test.js +0 -91
- package/dist/src/browser/base-page.test.js +0 -803
- package/dist/src/browser/bridge-readiness.test.js +0 -57
- package/dist/src/browser/cdp-click-fixture.test.js +0 -87
- package/dist/src/browser/cdp.test.js +0 -79
- package/dist/src/browser/compound.test.js +0 -175
- package/dist/src/browser/daemon-client.test.js +0 -318
- package/dist/src/browser/dom-helpers.test.js +0 -106
- package/dist/src/browser/dom-snapshot.test.js +0 -313
- package/dist/src/browser/errors.test.js +0 -60
- package/dist/src/browser/extract.test.js +0 -129
- package/dist/src/browser/find.test.js +0 -180
- package/dist/src/browser/html-tree.test.js +0 -181
- package/dist/src/browser/network-cache.test.js +0 -75
- package/dist/src/browser/network-key.test.js +0 -49
- package/dist/src/browser/page.test.js +0 -406
- package/dist/src/browser/shape-filter.test.js +0 -101
- package/dist/src/browser/shape.test.js +0 -82
- package/dist/src/browser/stealth.test.js +0 -134
- package/dist/src/browser/target-errors.test.js +0 -94
- package/dist/src/browser/target-resolver.test.js +0 -118
- package/dist/src/browser/utils.test.js +0 -29
- package/dist/src/browser/verify-fixture.test.js +0 -219
- package/dist/src/browser.test.js +0 -291
- package/dist/src/build-manifest.test.js +0 -341
- package/dist/src/capabilityRouting.test.js +0 -63
- package/dist/src/cli-argv-preprocess.test.js +0 -304
- package/dist/src/cli.test.js +0 -3003
- package/dist/src/commanderAdapter.test.js +0 -386
- package/dist/src/commands/auth.test.js +0 -309
- package/dist/src/commands/daemon.test.js +0 -283
- package/dist/src/completion.test.js +0 -24
- package/dist/src/convention-audit.test.js +0 -247
- package/dist/src/daemon.test.js +0 -60
- package/dist/src/doctor.test.js +0 -263
- package/dist/src/download/article-download.test.js +0 -235
- package/dist/src/download/index.test.js +0 -177
- package/dist/src/download/media-download.test.js +0 -112
- package/dist/src/download/progress.test.js +0 -36
- package/dist/src/electron-apps.test.js +0 -76
- package/dist/src/engine.test.js +0 -337
- package/dist/src/errors.test.js +0 -109
- package/dist/src/execution.test.js +0 -645
- package/dist/src/extension-manifest-regression.test.js +0 -12
- package/dist/src/external.test.js +0 -188
- package/dist/src/help.test.js +0 -58
- package/dist/src/hooks.test.js +0 -92
- package/dist/src/interceptor.test.js +0 -81
- package/dist/src/launcher.test.js +0 -191
- package/dist/src/node-network.test.js +0 -81
- package/dist/src/observation/artifact.test.js +0 -121
- package/dist/src/observation/manager.test.js +0 -13
- package/dist/src/observation/redaction.test.js +0 -32
- package/dist/src/observation/retention.test.js +0 -118
- package/dist/src/observation/ring-buffer.test.js +0 -22
- package/dist/src/output.test.js +0 -79
- package/dist/src/package-exports.test.js +0 -112
- package/dist/src/pipeline/executor.test.js +0 -182
- package/dist/src/pipeline/steps/download.test.js +0 -102
- package/dist/src/pipeline/steps/fetch.test.js +0 -188
- package/dist/src/pipeline/template.test.js +0 -212
- package/dist/src/pipeline/transform.test.js +0 -174
- package/dist/src/plugin-manifest.test.js +0 -179
- package/dist/src/plugin-scaffold.test.js +0 -83
- package/dist/src/plugin.test.js +0 -1349
- package/dist/src/rate-limit.test.js +0 -66
- package/dist/src/registry.test.js +0 -209
- package/dist/src/runtime-detect.test.js +0 -39
- package/dist/src/serialization.test.js +0 -78
- package/dist/src/skills.test.js +0 -71
- package/dist/src/snapshotFormatter.test.js +0 -521
- package/dist/src/tui.test.js +0 -19
- package/dist/src/update-check.test.js +0 -116
- package/dist/src/utils.test.js +0 -155
- package/dist/src/validate.test.js +0 -90
- package/dist/src/verify.test.js +0 -63
- package/dist/src/weixin-download.test.js +0 -45
package/clis/chatgpt/utils.js
CHANGED
|
@@ -1,103 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* ChatGPT web browser automation helpers.
|
|
3
|
-
* Cross-platform: works on Linux/macOS/Windows via OpenCLI's CDP browser automation.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { htmlToMarkdown } from '@jackwener/opencli/utils';
|
|
7
|
-
import { ArgumentError, AuthRequiredError, CommandExecutionError, TimeoutError } from '@jackwener/opencli/errors';
|
|
8
|
-
|
|
9
|
-
export const CHATGPT_DOMAIN = 'chatgpt.com';
|
|
10
|
-
export const CHATGPT_URL = 'https://chatgpt.com';
|
|
11
|
-
|
|
12
|
-
const CHATGPT_MODEL_TARGETS = {
|
|
13
|
-
instant: {
|
|
14
|
-
label: 'Instant',
|
|
15
|
-
labels: ['Instant', '即时', '极速'],
|
|
16
|
-
optionLabels: ['Instant', '极速', '即时'],
|
|
17
|
-
testIds: ['model-switcher-gpt-5-5'],
|
|
18
|
-
intelligenceOrder: 0,
|
|
19
|
-
},
|
|
20
|
-
medium: {
|
|
21
|
-
label: 'Medium',
|
|
22
|
-
labels: ['Medium', '均衡'],
|
|
23
|
-
optionLabels: ['Medium', '均衡'],
|
|
24
|
-
testIds: [],
|
|
25
|
-
intelligenceOrder: 1,
|
|
26
|
-
},
|
|
27
|
-
high: {
|
|
28
|
-
label: 'High',
|
|
29
|
-
labels: ['High', '高级', 'Thinking', '思考'],
|
|
30
|
-
optionLabels: ['High', '高级', 'Thinking', '思考'],
|
|
31
|
-
testIds: ['model-switcher-gpt-5-5-thinking'],
|
|
32
|
-
intelligenceOrder: 2,
|
|
33
|
-
},
|
|
34
|
-
'extra-high': {
|
|
35
|
-
label: 'Extra High',
|
|
36
|
-
labels: ['Extra High', '超高'],
|
|
37
|
-
optionLabels: ['Extra High', '超高'],
|
|
38
|
-
testIds: [],
|
|
39
|
-
intelligenceOrder: 3,
|
|
40
|
-
},
|
|
41
|
-
pro: {
|
|
42
|
-
label: 'Pro',
|
|
43
|
-
labels: ['Pro', '进阶专业', '专业'],
|
|
44
|
-
optionLabels: ['专业', 'Pro', '进阶专业'],
|
|
45
|
-
testIds: ['model-switcher-gpt-5-5-pro'],
|
|
46
|
-
intelligenceOrder: 4,
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
const CHATGPT_MODEL_ALIASES = {
|
|
50
|
-
thinking: 'high',
|
|
51
|
-
};
|
|
52
|
-
export const CHATGPT_MODEL_CHOICES = [
|
|
53
|
-
...Object.keys(CHATGPT_MODEL_TARGETS),
|
|
54
|
-
...Object.keys(CHATGPT_MODEL_ALIASES),
|
|
55
|
-
];
|
|
56
|
-
|
|
57
|
-
const CHATGPT_TOOL_OPTIONS = {
|
|
58
|
-
'deep-research': { label: 'Deep Research', labels: ['深度研究', 'Deep Research'] },
|
|
59
|
-
'web-search': { label: 'Web Search', labels: ['网页搜索', '搜索', 'Web Search', 'Search'] },
|
|
60
|
-
};
|
|
61
|
-
export const CHATGPT_TOOL_CHOICES = Object.keys(CHATGPT_TOOL_OPTIONS);
|
|
62
|
-
|
|
63
|
-
// Selectors
|
|
64
|
-
const COMPOSER_SELECTORS = [
|
|
65
|
-
'[contenteditable="true"][role="textbox"]',
|
|
66
|
-
'#prompt-textarea[contenteditable="true"]',
|
|
67
|
-
'[aria-label="Chat with ChatGPT"]',
|
|
68
|
-
'[aria-label="与 ChatGPT 聊天"]',
|
|
69
|
-
'[placeholder="Ask anything"]',
|
|
70
|
-
'[placeholder="有问题,尽管问"]',
|
|
71
|
-
'#prompt-textarea',
|
|
72
|
-
'[data-testid="prompt-textarea"]',
|
|
73
|
-
];
|
|
74
|
-
const SEND_BUTTON_SELECTOR = 'button[data-testid="send-button"]:not([disabled])';
|
|
75
|
-
const SEND_BUTTON_FALLBACK_SELECTORS = [
|
|
76
|
-
'#composer-submit-button:not([disabled])',
|
|
77
|
-
];
|
|
78
|
-
const SEND_BUTTON_LABELS = [
|
|
79
|
-
'Send prompt',
|
|
80
|
-
'Send message',
|
|
81
|
-
'Send',
|
|
82
|
-
'发送',
|
|
83
|
-
'发送消息',
|
|
84
|
-
'发送提示',
|
|
85
|
-
];
|
|
86
|
-
const CLOSE_SIDEBAR_LABELS = [
|
|
87
|
-
'Close sidebar',
|
|
88
|
-
'关闭边栏',
|
|
89
|
-
];
|
|
90
|
-
|
|
91
|
-
function isSameChatGPTConversation(currentUrl, expectedUrl) {
|
|
92
|
-
if (!currentUrl || !expectedUrl) return false;
|
|
93
|
-
return currentUrl === expectedUrl
|
|
94
|
-
|| currentUrl.startsWith(`${expectedUrl}?`)
|
|
95
|
-
|| currentUrl.startsWith(`${expectedUrl}#`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function buildComposerLocatorScript() {
|
|
99
|
-
const markerAttr = 'data-opencli-chatgpt-composer';
|
|
100
|
-
return `
|
|
1
|
+
import{htmlToMarkdown as i}from"@jackwener/opencli/utils";import{ArgumentError as k,AuthRequiredError as _,CommandExecutionError as F,TimeoutError as O}from"@jackwener/opencli/errors";export const CHATGPT_DOMAIN="chatgpt.com",CHATGPT_URL="https://chatgpt.com";const I={instant:{label:"Instant",labels:["Instant","即时","极速"],optionLabels:["Instant","极速","即时"],testIds:["model-switcher-gpt-5-5"],intelligenceOrder:0},medium:{label:"Medium",labels:["Medium","均衡"],optionLabels:["Medium","均衡"],testIds:[],intelligenceOrder:1},high:{label:"High",labels:["High","高级","Thinking","思考"],optionLabels:["High","高级","Thinking","思考"],testIds:["model-switcher-gpt-5-5-thinking"],intelligenceOrder:2},"extra-high":{label:"Extra High",labels:["Extra High","超高"],optionLabels:["Extra High","超高"],testIds:[],intelligenceOrder:3},pro:{label:"Pro",labels:["Pro","进阶专业","专业"],optionLabels:["专业","Pro","进阶专业"],testIds:["model-switcher-gpt-5-5-pro"],intelligenceOrder:4}},w={thinking:"high"};export const CHATGPT_MODEL_CHOICES=[...Object.keys(I),...Object.keys(w)];const G={"deep-research":{label:"Deep Research",labels:["深度研究","Deep Research"]},"web-search":{label:"Web Search",labels:["网页搜索","搜索","Web Search","Search"]}};export const CHATGPT_TOOL_CHOICES=Object.keys(G);const x=['[contenteditable="true"][role="textbox"]','#prompt-textarea[contenteditable="true"]','[aria-label="Chat with ChatGPT"]','[aria-label="与 ChatGPT 聊天"]','[placeholder="Ask anything"]','[placeholder="有问题,尽管问"]',"#prompt-textarea",'[data-testid="prompt-textarea"]'],U='button[data-testid="send-button"]:not([disabled])',L=["#composer-submit-button:not([disabled])"],y=["Send prompt","Send message","Send","发送","发送消息","发送提示"],A=["Close sidebar","关闭边栏"];function N(Q,X){if(!Q||!X)return!1;return Q===X||Q.startsWith(`${X}?`)||Q.startsWith(`${X}#`)}function v(){return`
|
|
101
2
|
const isVisible = (el) => {
|
|
102
3
|
if (!(el instanceof HTMLElement)) return false;
|
|
103
4
|
const style = window.getComputedStyle(el);
|
|
@@ -106,7 +7,7 @@ function buildComposerLocatorScript() {
|
|
|
106
7
|
return rect.width > 0 && rect.height > 0;
|
|
107
8
|
};
|
|
108
9
|
|
|
109
|
-
const markerAttr = ${JSON.stringify(
|
|
10
|
+
const markerAttr = ${JSON.stringify("data-opencli-chatgpt-composer")};
|
|
110
11
|
const clearMarkers = (active) => {
|
|
111
12
|
document.querySelectorAll('[' + markerAttr + ']').forEach(node => {
|
|
112
13
|
if (node !== active) node.removeAttribute(markerAttr);
|
|
@@ -114,7 +15,7 @@ function buildComposerLocatorScript() {
|
|
|
114
15
|
};
|
|
115
16
|
|
|
116
17
|
const findComposer = () => {
|
|
117
|
-
for (const selector of ${JSON.stringify(
|
|
18
|
+
for (const selector of ${JSON.stringify(x)}) {
|
|
118
19
|
const candidates = Array.from(document.querySelectorAll(selector)).filter(c => c instanceof HTMLElement && isVisible(c));
|
|
119
20
|
const node = candidates.find(c => c.isContentEditable) || candidates[0];
|
|
120
21
|
if (node instanceof HTMLElement) {
|
|
@@ -127,191 +28,7 @@ function buildComposerLocatorScript() {
|
|
|
127
28
|
};
|
|
128
29
|
|
|
129
30
|
findComposer.toString = () => 'findComposer';
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export function normalizeBooleanFlag(value, fallback = false) {
|
|
134
|
-
if (typeof value === 'boolean') return value;
|
|
135
|
-
if (value == null || value === '') return fallback;
|
|
136
|
-
const normalized = String(value).trim().toLowerCase();
|
|
137
|
-
return normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on';
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function requireNonEmptyPrompt(prompt, commandName) {
|
|
141
|
-
const text = String(prompt ?? '').trim();
|
|
142
|
-
if (!text) {
|
|
143
|
-
throw new ArgumentError(
|
|
144
|
-
`${commandName} prompt cannot be empty`,
|
|
145
|
-
`Example: opencli ${commandName} "hello"`,
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
return text;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export function requirePositiveInt(value, flagLabel, hint) {
|
|
152
|
-
if (!Number.isInteger(value) || value < 1) {
|
|
153
|
-
throw new ArgumentError(`${flagLabel} must be a positive integer`, hint);
|
|
154
|
-
}
|
|
155
|
-
return value;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export function requireNonNegativeInt(value, flagLabel, hint) {
|
|
159
|
-
if (!Number.isInteger(value) || value < 0) {
|
|
160
|
-
throw new ArgumentError(`${flagLabel} must be a non-negative integer`, hint);
|
|
161
|
-
}
|
|
162
|
-
return value;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
166
|
-
// page.evaluate envelope helpers.
|
|
167
|
-
//
|
|
168
|
-
// The browser bridge wraps every `page.evaluate(...)` return value in a
|
|
169
|
-
// `{ session, data }` envelope. Adapters that read `.length` or
|
|
170
|
-
// `Array.isArray(payload)` directly on the envelope silently see "no data" —
|
|
171
|
-
// this matches the failure mode fixed for xiaohongshu/rednote (#1561) and
|
|
172
|
-
// weibo (#1568).
|
|
173
|
-
//
|
|
174
|
-
// `unwrapEvaluateResult` is a defensive ternary: it unwraps when the payload
|
|
175
|
-
// looks like an envelope, otherwise passes the value through unchanged so
|
|
176
|
-
// older bridge versions and primitive return values still work.
|
|
177
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
178
|
-
export function unwrapEvaluateResult(payload) {
|
|
179
|
-
if (payload && !Array.isArray(payload) && typeof payload === 'object' && 'session' in payload && 'data' in payload) {
|
|
180
|
-
return payload.data;
|
|
181
|
-
}
|
|
182
|
-
return payload;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function requireArrayEvaluateResult(payload, label) {
|
|
186
|
-
if (!Array.isArray(payload)) {
|
|
187
|
-
if (payload && typeof payload === 'object' && 'error' in payload) {
|
|
188
|
-
throw new CommandExecutionError(`${label}: ${String(payload.error)}`);
|
|
189
|
-
}
|
|
190
|
-
throw new CommandExecutionError(`${label} returned malformed extraction payload`);
|
|
191
|
-
}
|
|
192
|
-
return payload;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function requireObjectEvaluateResult(payload, label) {
|
|
196
|
-
if (!payload || Array.isArray(payload) || typeof payload !== 'object') {
|
|
197
|
-
throw new CommandExecutionError(`${label} returned malformed extraction payload`);
|
|
198
|
-
}
|
|
199
|
-
return payload;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export function requireBooleanEvaluateResult(payload, label) {
|
|
203
|
-
if (typeof payload !== 'boolean') {
|
|
204
|
-
throw new CommandExecutionError(`${label} returned malformed extraction payload`);
|
|
205
|
-
}
|
|
206
|
-
return payload;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function isTrustedChatGPTHost(hostname) {
|
|
210
|
-
return hostname === CHATGPT_DOMAIN || hostname.endsWith(`.${CHATGPT_DOMAIN}`);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
function projectIdFromPathname(pathname) {
|
|
214
|
-
const match = String(pathname || '').match(/^\/g\/g-p-([a-f0-9]{8,})(?:[-/]|$)/i);
|
|
215
|
-
return match ? match[1].toLowerCase() : '';
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function projectIdFromUrl(value) {
|
|
219
|
-
try {
|
|
220
|
-
const url = new URL(String(value || ''), CHATGPT_URL);
|
|
221
|
-
if (url.protocol !== 'https:' || !isTrustedChatGPTHost(url.hostname)) return '';
|
|
222
|
-
return projectIdFromPathname(url.pathname);
|
|
223
|
-
} catch {
|
|
224
|
-
return '';
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export function parseChatGPTConversationId(value) {
|
|
229
|
-
const raw = String(value ?? '').trim();
|
|
230
|
-
if (/^https?:\/\//i.test(raw)) {
|
|
231
|
-
try {
|
|
232
|
-
const parsed = new URL(raw);
|
|
233
|
-
if (parsed.protocol !== 'https:' || (parsed.hostname !== CHATGPT_DOMAIN && !parsed.hostname.endsWith(`.${CHATGPT_DOMAIN}`))) {
|
|
234
|
-
throw new Error('off-domain');
|
|
235
|
-
}
|
|
236
|
-
const match = parsed.pathname.match(/^\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})$/);
|
|
237
|
-
if (match) return match[1];
|
|
238
|
-
} catch {
|
|
239
|
-
// Fall through to the shared typed ArgumentError below.
|
|
240
|
-
}
|
|
241
|
-
throw new ArgumentError(
|
|
242
|
-
'chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL',
|
|
243
|
-
'Example: opencli chatgpt detail https://chatgpt.com/c/123e4567-e89b-12d3-a456-426614174000',
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
const pathMatch = raw.match(/^\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})(?:[?#].*)?$/);
|
|
247
|
-
if (pathMatch) return pathMatch[1];
|
|
248
|
-
if (/^[A-Za-z0-9_-]{8,}$/.test(raw)) return raw;
|
|
249
|
-
throw new ArgumentError(
|
|
250
|
-
'chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL',
|
|
251
|
-
'Example: opencli chatgpt detail 123e4567-e89b-12d3-a456-426614174000',
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export async function currentChatGPTUrl(page) {
|
|
256
|
-
const url = unwrapEvaluateResult(await page.evaluate('window.location.href').catch(() => ''));
|
|
257
|
-
return typeof url === 'string' ? url : '';
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
export async function isOnChatGPT(page) {
|
|
261
|
-
const url = await currentChatGPTUrl(page);
|
|
262
|
-
if (!url) return false;
|
|
263
|
-
try {
|
|
264
|
-
const host = new URL(url).hostname;
|
|
265
|
-
return host === CHATGPT_DOMAIN || host.endsWith(`.${CHATGPT_DOMAIN}`);
|
|
266
|
-
} catch {
|
|
267
|
-
return false;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Comma-joined CSS selector list passed to page.wait({ selector }) so the
|
|
272
|
-
// wait succeeds as soon as any composer flavour mounts (querySelectorAll
|
|
273
|
-
// matches all of them). Tracks the most stable subset of COMPOSER_SELECTORS;
|
|
274
|
-
// we only need to know "the composer is ready", not which variant rendered.
|
|
275
|
-
const COMPOSER_WAIT_SELECTOR = '#prompt-textarea, [data-testid="prompt-textarea"]';
|
|
276
|
-
const CONVERSATION_LINK_SELECTOR = 'a[href*="/c/"]';
|
|
277
|
-
const PROJECT_LINK_SELECTOR = 'a[href*="/g/g-p-"]';
|
|
278
|
-
// Selector used by detail.js to wait for at least one rendered message bubble
|
|
279
|
-
// after navigating to /c/<id>; mirrors the markup queried by getVisibleMessages.
|
|
280
|
-
export const CONVERSATION_MESSAGE_SELECTOR = '[data-message-author-role], article[data-testid*="conversation-turn"]';
|
|
281
|
-
|
|
282
|
-
export async function ensureOnChatGPT(page) {
|
|
283
|
-
if (await isOnChatGPT(page)) return false;
|
|
284
|
-
await page.goto(CHATGPT_URL, { settleMs: 2000 });
|
|
285
|
-
try {
|
|
286
|
-
await page.wait({ selector: COMPOSER_WAIT_SELECTOR, timeout: 8 });
|
|
287
|
-
} catch {
|
|
288
|
-
// Composer didn't mount; downstream ensureChatGPTLogin / ensureChatGPTComposer surfaces a typed error.
|
|
289
|
-
}
|
|
290
|
-
return true;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export async function startNewChat(page) {
|
|
294
|
-
await page.goto(`${CHATGPT_URL}/new`, { settleMs: 2000 });
|
|
295
|
-
try {
|
|
296
|
-
await page.wait({ selector: COMPOSER_WAIT_SELECTOR, timeout: 8 });
|
|
297
|
-
} catch {
|
|
298
|
-
// Composer didn't mount; downstream ensureChatGPTComposer surfaces a typed error.
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
export async function openChatGPTConversation(page, value) {
|
|
303
|
-
const id = parseChatGPTConversationId(value);
|
|
304
|
-
await page.goto(`${CHATGPT_URL}/c/${id}`, { settleMs: 2000 });
|
|
305
|
-
try {
|
|
306
|
-
await page.wait({ selector: COMPOSER_WAIT_SELECTOR, timeout: 8 });
|
|
307
|
-
} catch {
|
|
308
|
-
// Composer didn't mount; downstream ensureChatGPTLogin / ensureChatGPTComposer surfaces a typed error.
|
|
309
|
-
}
|
|
310
|
-
return id;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
export async function getPageState(page) {
|
|
314
|
-
return requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
31
|
+
`}export function normalizeBooleanFlag(Q,X=!1){if(typeof Q==="boolean")return Q;if(Q==null||Q==="")return X;const Y=String(Q).trim().toLowerCase();return Y==="true"||Y==="1"||Y==="yes"||Y==="on"}export function requireNonEmptyPrompt(Q,X){const Y=String(Q??"").trim();if(!Y)throw new k(`${X} prompt cannot be empty`,`Example: opencli ${X} "hello"`);return Y}export function requirePositiveInt(Q,X,Y){if(!Number.isInteger(Q)||Q<1)throw new k(`${X} must be a positive integer`,Y);return Q}export function requireNonNegativeInt(Q,X,Y){if(!Number.isInteger(Q)||Q<0)throw new k(`${X} must be a non-negative integer`,Y);return Q}export function unwrapEvaluateResult(Q){if(Q&&!Array.isArray(Q)&&typeof Q==="object"&&"session"in Q&&"data"in Q)return Q.data;return Q}export function requireArrayEvaluateResult(Q,X){if(!Array.isArray(Q)){if(Q&&typeof Q==="object"&&"error"in Q)throw new F(`${X}: ${String(Q.error)}`);throw new F(`${X} returned malformed extraction payload`)}return Q}export function requireObjectEvaluateResult(Q,X){if(!Q||Array.isArray(Q)||typeof Q!=="object")throw new F(`${X} returned malformed extraction payload`);return Q}export function requireBooleanEvaluateResult(Q,X){if(typeof Q!=="boolean")throw new F(`${X} returned malformed extraction payload`);return Q}function u(Q){return Q===CHATGPT_DOMAIN||Q.endsWith(`.${CHATGPT_DOMAIN}`)}function n(Q){const X=String(Q||"").match(/^\/g\/g-p-([a-f0-9]{8,})(?:[-/]|$)/i);return X?X[1].toLowerCase():""}function S(Q){try{const X=new URL(String(Q||""),CHATGPT_URL);if(X.protocol!=="https:"||!u(X.hostname))return"";return n(X.pathname)}catch{return""}}export function parseChatGPTConversationId(Q){const X=String(Q??"").trim();if(/^https?:\/\//i.test(X)){try{const Z=new URL(X);if(Z.protocol!=="https:"||Z.hostname!==CHATGPT_DOMAIN&&!Z.hostname.endsWith(`.${CHATGPT_DOMAIN}`))throw Error("off-domain");const $=Z.pathname.match(/^\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})$/);if($)return $[1]}catch{}throw new k("chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL","Example: opencli chatgpt detail https://chatgpt.com/c/123e4567-e89b-12d3-a456-426614174000")}const Y=X.match(/^\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})(?:[?#].*)?$/);if(Y)return Y[1];if(/^[A-Za-z0-9_-]{8,}$/.test(X))return X;throw new k("chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL","Example: opencli chatgpt detail 123e4567-e89b-12d3-a456-426614174000")}export async function currentChatGPTUrl(Q){const X=unwrapEvaluateResult(await Q.evaluate("window.location.href").catch(()=>""));return typeof X==="string"?X:""}export async function isOnChatGPT(Q){const X=await currentChatGPTUrl(Q);if(!X)return!1;try{const Y=new URL(X).hostname;return Y===CHATGPT_DOMAIN||Y.endsWith(`.${CHATGPT_DOMAIN}`)}catch{return!1}}const f='#prompt-textarea, [data-testid="prompt-textarea"]',R='a[href*="/c/"]',c='a[href*="/g/g-p-"]';export const CONVERSATION_MESSAGE_SELECTOR='[data-message-author-role], article[data-testid*="conversation-turn"]';export async function ensureOnChatGPT(Q){if(await isOnChatGPT(Q))return!1;await Q.goto(CHATGPT_URL,{settleMs:2000});try{await Q.wait({selector:f,timeout:8})}catch{}return!0}export async function startNewChat(Q){await Q.goto(`${CHATGPT_URL}/new`,{settleMs:2000});try{await Q.wait({selector:f,timeout:8})}catch{}}export async function openChatGPTConversation(Q,X){const Y=parseChatGPTConversationId(X);await Q.goto(`${CHATGPT_URL}/c/${Y}`,{settleMs:2000});try{await Q.wait({selector:f,timeout:8})}catch{}return Y}export async function getPageState(Q){return requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
315
32
|
const isVisible = (el) => {
|
|
316
33
|
if (!(el instanceof HTMLElement)) return false;
|
|
317
34
|
const style = window.getComputedStyle(el);
|
|
@@ -319,7 +36,7 @@ export async function getPageState(page) {
|
|
|
319
36
|
const rect = el.getBoundingClientRect();
|
|
320
37
|
return rect.width > 0 && rect.height > 0;
|
|
321
38
|
};
|
|
322
|
-
const composerSelectors = ${JSON.stringify(
|
|
39
|
+
const composerSelectors = ${JSON.stringify(x)};
|
|
323
40
|
const hasComposer = composerSelectors.some((selector) =>
|
|
324
41
|
Array.from(document.querySelectorAll(selector)).some((node) => isVisible(node))
|
|
325
42
|
);
|
|
@@ -337,52 +54,7 @@ export async function getPageState(page) {
|
|
|
337
54
|
isLoggedIn: hasComposer || !!userMenu || !hasLoginGate,
|
|
338
55
|
hasLoginGate,
|
|
339
56
|
};
|
|
340
|
-
})()`)),
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
export async function ensureChatGPTLogin(page, message = 'ChatGPT requires a logged-in browser session.') {
|
|
344
|
-
const state = await getPageState(page);
|
|
345
|
-
if (!state.isLoggedIn || state.hasLoginGate) {
|
|
346
|
-
throw new AuthRequiredError(CHATGPT_DOMAIN, message);
|
|
347
|
-
}
|
|
348
|
-
return state;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
export async function ensureChatGPTComposer(page, message = 'ChatGPT composer is not available on the current page.') {
|
|
352
|
-
const state = await ensureChatGPTLogin(page, message);
|
|
353
|
-
if (!state.hasComposer) {
|
|
354
|
-
throw new CommandExecutionError(message);
|
|
355
|
-
}
|
|
356
|
-
return state;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
function requireKnownChatGPTModel(model) {
|
|
360
|
-
const key = String(model ?? '').trim().toLowerCase();
|
|
361
|
-
const targetKey = CHATGPT_MODEL_ALIASES[key] || key;
|
|
362
|
-
const option = CHATGPT_MODEL_TARGETS[targetKey];
|
|
363
|
-
if (!option) {
|
|
364
|
-
throw new ArgumentError(
|
|
365
|
-
`Unknown ChatGPT model "${model}"`,
|
|
366
|
-
`Choose one of: ${CHATGPT_MODEL_CHOICES.join(', ')}`,
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
return { key: targetKey, alias: key !== targetKey ? key : null, ...option };
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
function requireKnownChatGPTTool(tool) {
|
|
373
|
-
const key = String(tool ?? '').trim().toLowerCase();
|
|
374
|
-
const option = CHATGPT_TOOL_OPTIONS[key];
|
|
375
|
-
if (!option) {
|
|
376
|
-
throw new ArgumentError(
|
|
377
|
-
`Unknown ChatGPT tool "${tool}"`,
|
|
378
|
-
`Choose one of: ${CHATGPT_TOOL_CHOICES.join(', ')}`,
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
|
-
return { key, ...option };
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
export async function getCurrentChatGPTModel(page) {
|
|
385
|
-
return requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
57
|
+
})()`)),"chatgpt page state")}export async function ensureChatGPTLogin(Q,X="ChatGPT requires a logged-in browser session."){const Y=await getPageState(Q);if(!Y.isLoggedIn||Y.hasLoginGate)throw new _(CHATGPT_DOMAIN,X);return Y}export async function ensureChatGPTComposer(Q,X="ChatGPT composer is not available on the current page."){const Y=await ensureChatGPTLogin(Q,X);if(!Y.hasComposer)throw new F(X);return Y}function o(Q){const X=String(Q??"").trim().toLowerCase(),Y=w[X]||X,Z=I[Y];if(!Z)throw new k(`Unknown ChatGPT model "${Q}"`,`Choose one of: ${CHATGPT_MODEL_CHOICES.join(", ")}`);return{key:Y,alias:X!==Y?X:null,...Z}}function g(Q){const X=String(Q??"").trim().toLowerCase(),Y=G[X];if(!Y)throw new k(`Unknown ChatGPT tool "${Q}"`,`Choose one of: ${CHATGPT_TOOL_CHOICES.join(", ")}`);return{key:X,...Y}}export async function getCurrentChatGPTModel(Q){return requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
386
58
|
const isVisible = (el) => {
|
|
387
59
|
if (!(el instanceof HTMLElement)) return false;
|
|
388
60
|
const style = window.getComputedStyle(el);
|
|
@@ -402,7 +74,7 @@ export async function getCurrentChatGPTModel(page) {
|
|
|
402
74
|
}
|
|
403
75
|
return normalizedText.replace(/\\s+/g, '').includes(normalizedLabel.replace(/\\s+/g, ''));
|
|
404
76
|
};
|
|
405
|
-
const labels = ${JSON.stringify(
|
|
77
|
+
const labels = ${JSON.stringify(I)};
|
|
406
78
|
const findEntryForText = (text) => {
|
|
407
79
|
const matches = [];
|
|
408
80
|
for (const [key, value] of Object.entries(labels)) {
|
|
@@ -442,23 +114,7 @@ export async function getCurrentChatGPTModel(page) {
|
|
|
442
114
|
model: entry?.key ?? null,
|
|
443
115
|
label: entry?.value?.label ?? null,
|
|
444
116
|
};
|
|
445
|
-
})()`)),
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
export async function selectChatGPTModel(page, model) {
|
|
449
|
-
const target = requireKnownChatGPTModel(model);
|
|
450
|
-
if (typeof page.nativeClick !== 'function') {
|
|
451
|
-
throw new CommandExecutionError('ChatGPT model selection requires native browser click support.');
|
|
452
|
-
}
|
|
453
|
-
await ensureOnChatGPT(page);
|
|
454
|
-
await ensureChatGPTComposer(page, 'ChatGPT model selection requires a logged-in ChatGPT session with a visible composer.');
|
|
455
|
-
|
|
456
|
-
const before = await getCurrentChatGPTModel(page);
|
|
457
|
-
if (before.model === target.key) {
|
|
458
|
-
return { Status: 'Already selected', Model: target.label };
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
const menuButton = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
117
|
+
})()`)),"chatgpt current model")}export async function selectChatGPTModel(Q,X){const Y=o(X);if(typeof Q.nativeClick!=="function")throw new F("ChatGPT model selection requires native browser click support.");await ensureOnChatGPT(Q);await ensureChatGPTComposer(Q,"ChatGPT model selection requires a logged-in ChatGPT session with a visible composer.");if((await getCurrentChatGPTModel(Q)).model===Y.key)return{Status:"Already selected",Model:Y.label};const $=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
462
118
|
const isVisible = (el) => {
|
|
463
119
|
if (!(el instanceof HTMLElement)) return false;
|
|
464
120
|
const style = window.getComputedStyle(el);
|
|
@@ -478,7 +134,7 @@ export async function selectChatGPTModel(page, model) {
|
|
|
478
134
|
}
|
|
479
135
|
return normalizedText.replace(/\\s+/g, '').includes(normalizedLabel.replace(/\\s+/g, ''));
|
|
480
136
|
};
|
|
481
|
-
const labels = ${JSON.stringify(Object.values(
|
|
137
|
+
const labels = ${JSON.stringify(Object.values(I).flatMap((z)=>z.labels))};
|
|
482
138
|
const menuButtonSelectors = [
|
|
483
139
|
'button[data-testid="model-switcher-dropdown-button"]',
|
|
484
140
|
'button[aria-label*="model" i]',
|
|
@@ -501,16 +157,7 @@ export async function selectChatGPTModel(page, model) {
|
|
|
501
157
|
x: Math.round(rect.left + rect.width / 2),
|
|
502
158
|
y: Math.round(rect.top + rect.height / 2),
|
|
503
159
|
};
|
|
504
|
-
})()`)),
|
|
505
|
-
if (!menuButton.found) {
|
|
506
|
-
throw new CommandExecutionError('Could not find the ChatGPT model selector in the composer.');
|
|
507
|
-
}
|
|
508
|
-
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
|
|
509
|
-
await page.wait(0.5);
|
|
510
|
-
|
|
511
|
-
let optionCenter = null;
|
|
512
|
-
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
513
|
-
optionCenter = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
160
|
+
})()`)),"chatgpt model menu button");if(!$.found)throw new F("Could not find the ChatGPT model selector in the composer.");await Q.nativeClick(Number($.x),Number($.y));await Q.wait(0.5);let W=null;for(let z=0;z<10;z+=1){W=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
514
161
|
const isVisible = (el) => {
|
|
515
162
|
if (!(el instanceof HTMLElement)) return false;
|
|
516
163
|
const style = window.getComputedStyle(el);
|
|
@@ -530,7 +177,7 @@ export async function selectChatGPTModel(page, model) {
|
|
|
530
177
|
}
|
|
531
178
|
return normalizedText.replace(/\\s+/g, '').includes(normalizedLabel.replace(/\\s+/g, ''));
|
|
532
179
|
};
|
|
533
|
-
const target = ${JSON.stringify(
|
|
180
|
+
const target = ${JSON.stringify(Y)};
|
|
534
181
|
const clickableSelector = '[role="menuitemradio"], [role="menuitem"], [role="option"], button, [data-testid^="model-switcher"]';
|
|
535
182
|
const intelligenceContent = document.querySelector('[data-testid="composer-intelligence-picker-content"]');
|
|
536
183
|
const intelligenceOptions = intelligenceContent
|
|
@@ -576,21 +223,7 @@ export async function selectChatGPTModel(page, model) {
|
|
|
576
223
|
x: Math.round(rect.left + rect.width / 2),
|
|
577
224
|
y: Math.round(rect.top + rect.height / 2),
|
|
578
225
|
};
|
|
579
|
-
})()`)),
|
|
580
|
-
if (optionCenter.found) break;
|
|
581
|
-
await page.wait(0.5);
|
|
582
|
-
}
|
|
583
|
-
if (!optionCenter?.found) {
|
|
584
|
-
throw new CommandExecutionError(`Could not click the ChatGPT ${target.label} model option.`);
|
|
585
|
-
}
|
|
586
|
-
await page.nativeClick(Number(optionCenter.x), Number(optionCenter.y));
|
|
587
|
-
|
|
588
|
-
await page.wait(0.5);
|
|
589
|
-
const after = await getCurrentChatGPTModel(page);
|
|
590
|
-
if (after.model !== target.key) {
|
|
591
|
-
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
|
|
592
|
-
await page.wait(0.5);
|
|
593
|
-
const checked = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
226
|
+
})()`)),"chatgpt model option click");if(W.found)break;await Q.wait(0.5)}if(!W?.found)throw new F(`Could not click the ChatGPT ${Y.label} model option.`);await Q.nativeClick(Number(W.x),Number(W.y));await Q.wait(0.5);if((await getCurrentChatGPTModel(Q)).model!==Y.key){await Q.nativeClick(Number($.x),Number($.y));await Q.wait(0.5);const z=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
594
227
|
const isVisible = (el) => {
|
|
595
228
|
if (!(el instanceof HTMLElement)) return false;
|
|
596
229
|
const style = window.getComputedStyle(el);
|
|
@@ -598,7 +231,7 @@ export async function selectChatGPTModel(page, model) {
|
|
|
598
231
|
const rect = el.getBoundingClientRect();
|
|
599
232
|
return rect.width > 0 && rect.height > 0;
|
|
600
233
|
};
|
|
601
|
-
const target = ${JSON.stringify(
|
|
234
|
+
const target = ${JSON.stringify(Y)};
|
|
602
235
|
const intelligenceContent = document.querySelector('[data-testid="composer-intelligence-picker-content"]');
|
|
603
236
|
const options = intelligenceContent
|
|
604
237
|
? Array.from(intelligenceContent.querySelectorAll('[role="menuitemradio"]')).filter(isVisible)
|
|
@@ -608,19 +241,7 @@ export async function selectChatGPTModel(page, model) {
|
|
|
608
241
|
recognized: options.length === 5 && Number.isInteger(target.intelligenceOrder),
|
|
609
242
|
checkedIndex,
|
|
610
243
|
};
|
|
611
|
-
})()`)),
|
|
612
|
-
if (checked.recognized && checked.checkedIndex === target.intelligenceOrder) {
|
|
613
|
-
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
|
|
614
|
-
return { Status: 'Success', Model: target.label };
|
|
615
|
-
}
|
|
616
|
-
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
|
|
617
|
-
throw new CommandExecutionError(`ChatGPT model did not switch to ${target.label}.`);
|
|
618
|
-
}
|
|
619
|
-
return { Status: 'Success', Model: target.label };
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
export async function getCurrentChatGPTTool(page) {
|
|
623
|
-
return requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
244
|
+
})()`)),"chatgpt model checked intelligence option");if(z.recognized&&z.checkedIndex===Y.intelligenceOrder){await Q.nativeClick(Number($.x),Number($.y));return{Status:"Success",Model:Y.label}}await Q.nativeClick(Number($.x),Number($.y));throw new F(`ChatGPT model did not switch to ${Y.label}.`)}return{Status:"Success",Model:Y.label}}export async function getCurrentChatGPTTool(Q){return requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
624
245
|
const isVisible = (el) => {
|
|
625
246
|
if (!(el instanceof HTMLElement)) return false;
|
|
626
247
|
const style = window.getComputedStyle(el);
|
|
@@ -629,7 +250,7 @@ export async function getCurrentChatGPTTool(page) {
|
|
|
629
250
|
return rect.width > 0 && rect.height > 0;
|
|
630
251
|
};
|
|
631
252
|
const normalize = (value) => String(value || '').replace(/\\s+/g, ' ').trim();
|
|
632
|
-
const labels = ${JSON.stringify(
|
|
253
|
+
const labels = ${JSON.stringify(G)};
|
|
633
254
|
const form = Array.from(document.querySelectorAll('form')).find((node) => node instanceof HTMLElement && isVisible(node));
|
|
634
255
|
const root = form || document.body;
|
|
635
256
|
const nodes = Array.from(root.querySelectorAll('button, [role="button"], [role="menuitemradio"], span, div'));
|
|
@@ -644,23 +265,7 @@ export async function getCurrentChatGPTTool(page) {
|
|
|
644
265
|
tool: entry?.[0] ?? null,
|
|
645
266
|
label: entry?.[1]?.label ?? null,
|
|
646
267
|
};
|
|
647
|
-
})()`)),
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
export async function selectChatGPTTool(page, tool) {
|
|
651
|
-
const target = requireKnownChatGPTTool(tool);
|
|
652
|
-
if (typeof page.nativeClick !== 'function') {
|
|
653
|
-
throw new CommandExecutionError('ChatGPT tool selection requires native browser click support.');
|
|
654
|
-
}
|
|
655
|
-
await ensureOnChatGPT(page);
|
|
656
|
-
await ensureChatGPTComposer(page, 'ChatGPT tool selection requires a logged-in ChatGPT session with a visible composer.');
|
|
657
|
-
|
|
658
|
-
const before = await getCurrentChatGPTTool(page);
|
|
659
|
-
if (before.tool === target.key) {
|
|
660
|
-
return { Status: 'Already selected', Tool: target.label };
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
const menuButton = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
268
|
+
})()`)),"chatgpt current tool")}export async function selectChatGPTTool(Q,X){const Y=g(X);if(typeof Q.nativeClick!=="function")throw new F("ChatGPT tool selection requires native browser click support.");await ensureOnChatGPT(Q);await ensureChatGPTComposer(Q,"ChatGPT tool selection requires a logged-in ChatGPT session with a visible composer.");if((await getCurrentChatGPTTool(Q)).tool===Y.key)return{Status:"Already selected",Tool:Y.label};const $=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
664
269
|
const isVisible = (el) => {
|
|
665
270
|
if (!(el instanceof HTMLElement)) return false;
|
|
666
271
|
const style = window.getComputedStyle(el);
|
|
@@ -677,16 +282,7 @@ export async function selectChatGPTTool(page, tool) {
|
|
|
677
282
|
x: Math.round(rect.left + rect.width / 2),
|
|
678
283
|
y: Math.round(rect.top + rect.height / 2),
|
|
679
284
|
};
|
|
680
|
-
})()`)),
|
|
681
|
-
if (!menuButton.found) {
|
|
682
|
-
throw new CommandExecutionError('Could not find the ChatGPT tools menu button in the composer.');
|
|
683
|
-
}
|
|
684
|
-
await page.nativeClick(Number(menuButton.x), Number(menuButton.y));
|
|
685
|
-
await page.wait(0.5);
|
|
686
|
-
|
|
687
|
-
let optionCenter = null;
|
|
688
|
-
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
689
|
-
optionCenter = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
285
|
+
})()`)),"chatgpt tools menu button");if(!$.found)throw new F("Could not find the ChatGPT tools menu button in the composer.");await Q.nativeClick(Number($.x),Number($.y));await Q.wait(0.5);let W=null;for(let z=0;z<10;z+=1){W=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
690
286
|
const isVisible = (el) => {
|
|
691
287
|
if (!(el instanceof HTMLElement)) return false;
|
|
692
288
|
const style = window.getComputedStyle(el);
|
|
@@ -695,7 +291,7 @@ export async function selectChatGPTTool(page, tool) {
|
|
|
695
291
|
return rect.width > 0 && rect.height > 0;
|
|
696
292
|
};
|
|
697
293
|
const normalize = (value) => String(value || '').replace(/\\s+/g, ' ').trim();
|
|
698
|
-
const labels = ${JSON.stringify(
|
|
294
|
+
const labels = ${JSON.stringify(Y.labels)};
|
|
699
295
|
const options = Array.from(document.querySelectorAll('[role="menuitemradio"]'));
|
|
700
296
|
const option = options.find((node) => node instanceof HTMLElement && isVisible(node) && labels.includes(normalize(node.textContent)));
|
|
701
297
|
if (!(option instanceof HTMLElement)) return { found: false };
|
|
@@ -708,27 +304,7 @@ export async function selectChatGPTTool(page, tool) {
|
|
|
708
304
|
x: Math.round(rect.left + rect.width / 2),
|
|
709
305
|
y: Math.round(rect.top + rect.height / 2),
|
|
710
306
|
};
|
|
711
|
-
})()`)),
|
|
712
|
-
if (optionCenter.found) break;
|
|
713
|
-
await page.wait(0.5);
|
|
714
|
-
}
|
|
715
|
-
if (!optionCenter?.found) {
|
|
716
|
-
throw new CommandExecutionError(`Could not find the ChatGPT ${target.label} tool option.`);
|
|
717
|
-
}
|
|
718
|
-
if (!optionCenter.checked) {
|
|
719
|
-
await page.nativeClick(Number(optionCenter.x), Number(optionCenter.y));
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
await page.wait(0.5);
|
|
723
|
-
const after = await getCurrentChatGPTTool(page);
|
|
724
|
-
if (after.tool !== target.key) {
|
|
725
|
-
throw new CommandExecutionError(`ChatGPT tool did not switch to ${target.label}.`);
|
|
726
|
-
}
|
|
727
|
-
return { Status: optionCenter.checked ? 'Already selected' : 'Success', Tool: target.label };
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
export async function clearChatGPTDraft(page) {
|
|
731
|
-
await page.evaluate(`
|
|
307
|
+
})()`)),"chatgpt tool option click");if(W.found)break;await Q.wait(0.5)}if(!W?.found)throw new F(`Could not find the ChatGPT ${Y.label} tool option.`);if(!W.checked)await Q.nativeClick(Number(W.x),Number(W.y));await Q.wait(0.5);if((await getCurrentChatGPTTool(Q)).tool!==Y.key)throw new F(`ChatGPT tool did not switch to ${Y.label}.`);return{Status:W.checked?"Already selected":"Success",Tool:Y.label}}export async function clearChatGPTDraft(Q){await Q.evaluate(`
|
|
732
308
|
(() => {
|
|
733
309
|
const removeLabels = [/^remove file/i, /^移除文件/];
|
|
734
310
|
for (let pass = 0; pass < 10; pass += 1) {
|
|
@@ -740,7 +316,7 @@ export async function clearChatGPTDraft(page) {
|
|
|
740
316
|
button.click();
|
|
741
317
|
}
|
|
742
318
|
|
|
743
|
-
const selectors = ${JSON.stringify(
|
|
319
|
+
const selectors = ${JSON.stringify(x)};
|
|
744
320
|
for (const selector of selectors) {
|
|
745
321
|
for (const node of document.querySelectorAll(selector)) {
|
|
746
322
|
if (!(node instanceof HTMLElement)) continue;
|
|
@@ -757,51 +333,15 @@ export async function clearChatGPTDraft(page) {
|
|
|
757
333
|
}
|
|
758
334
|
}
|
|
759
335
|
})()
|
|
760
|
-
`);
|
|
761
|
-
await page.wait(0.5);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
export function parseChatGPTProjectId(value) {
|
|
765
|
-
const raw = String(value ?? '').trim();
|
|
766
|
-
if (/^https?:\/\//i.test(raw) || raw.startsWith('/')) {
|
|
767
|
-
const id = projectIdFromUrl(raw);
|
|
768
|
-
if (id) return id;
|
|
769
|
-
throw new ArgumentError(
|
|
770
|
-
'chatgpt project commands require a chatgpt.com project id or /g/g-p-<id> URL',
|
|
771
|
-
'Example: opencli chatgpt project-file-add report.pdf --id 12345678',
|
|
772
|
-
);
|
|
773
|
-
}
|
|
774
|
-
// Accept project slug pattern: g-p-{hex_id}-{slug} or just hex id
|
|
775
|
-
const slugMatch = raw.match(/^g-p-([a-f0-9]{8,})/i);
|
|
776
|
-
if (slugMatch) return slugMatch[1].toLowerCase();
|
|
777
|
-
if (/^[a-f0-9]{8,}$/i.test(raw)) return raw.toLowerCase();
|
|
778
|
-
throw new ArgumentError(
|
|
779
|
-
'chatgpt project commands require a project id or /g/g-p-<id> URL',
|
|
780
|
-
'Example: opencli chatgpt project-file-add report.pdf --id 12345678',
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
/**
|
|
785
|
-
* Send a message to the ChatGPT composer and submit it.
|
|
786
|
-
* Returns true if the message was sent successfully.
|
|
787
|
-
*/
|
|
788
|
-
export async function sendChatGPTMessage(page, text) {
|
|
789
|
-
// Close sidebar if open (it can cover the chat composer)
|
|
790
|
-
await page.evaluate(`
|
|
336
|
+
`);await Q.wait(0.5)}export function parseChatGPTProjectId(Q){const X=String(Q??"").trim();if(/^https?:\/\//i.test(X)||X.startsWith("/")){const Z=S(X);if(Z)return Z;throw new k("chatgpt project commands require a chatgpt.com project id or /g/g-p-<id> URL","Example: opencli chatgpt project-file-add report.pdf --id 12345678")}const Y=X.match(/^g-p-([a-f0-9]{8,})/i);if(Y)return Y[1].toLowerCase();if(/^[a-f0-9]{8,}$/i.test(X))return X.toLowerCase();throw new k("chatgpt project commands require a project id or /g/g-p-<id> URL","Example: opencli chatgpt project-file-add report.pdf --id 12345678")}export async function sendChatGPTMessage(Q,X){await Q.evaluate(`
|
|
791
337
|
(() => {
|
|
792
|
-
const labels = ${JSON.stringify(
|
|
338
|
+
const labels = ${JSON.stringify(A)};
|
|
793
339
|
const closeBtn = Array.from(document.querySelectorAll('button')).find(b => labels.includes(b.getAttribute('aria-label') || ''));
|
|
794
340
|
if (closeBtn) closeBtn.click();
|
|
795
341
|
})()
|
|
796
|
-
`);
|
|
797
|
-
// The previous 0.5 s + 1.5 s pre-composer settles are dropped: the next
|
|
798
|
-
// page.evaluate roundtrip flushes the close-sidebar React update and
|
|
799
|
-
// findComposer() retries inside a single CDP call, so no fixed sleep is
|
|
800
|
-
// needed before reading the composer.
|
|
801
|
-
|
|
802
|
-
const typeResult = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
342
|
+
`);const Y=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
803
343
|
(() => {
|
|
804
|
-
${
|
|
344
|
+
${v()}
|
|
805
345
|
const composer = findComposer();
|
|
806
346
|
if (!composer) return { ready: false };
|
|
807
347
|
composer.focus();
|
|
@@ -823,39 +363,16 @@ export async function sendChatGPTMessage(page, text) {
|
|
|
823
363
|
y: Math.round(rect.top + Math.max(8, Math.min(rect.height / 2, rect.height - 8))),
|
|
824
364
|
};
|
|
825
365
|
})()
|
|
826
|
-
`)),
|
|
827
|
-
|
|
828
|
-
if (!typeResult.ready) return false;
|
|
829
|
-
|
|
830
|
-
// Use page.type() which is Playwright's native method
|
|
831
|
-
try {
|
|
832
|
-
if (page.nativeType) {
|
|
833
|
-
if (typeof page.nativeClick === 'function') {
|
|
834
|
-
await page.nativeClick(Number(typeResult.x), Number(typeResult.y));
|
|
835
|
-
await page.wait(0.2);
|
|
836
|
-
}
|
|
837
|
-
await page.nativeType(text);
|
|
838
|
-
} else {
|
|
839
|
-
throw new Error('nativeType unavailable');
|
|
840
|
-
}
|
|
841
|
-
} catch (e) {
|
|
842
|
-
// Fallback: use execCommand
|
|
843
|
-
await page.evaluate(`
|
|
366
|
+
`)),"chatgpt composer readiness");if(!Y.ready)return!1;try{if(Q.nativeType){if(typeof Q.nativeClick==="function"){await Q.nativeClick(Number(Y.x),Number(Y.y));await Q.wait(0.2)}await Q.nativeType(X)}else throw Error("nativeType unavailable")}catch($){await Q.evaluate(`
|
|
844
367
|
(() => {
|
|
845
368
|
var composer = null;
|
|
846
|
-
var sels = ${JSON.stringify(
|
|
369
|
+
var sels = ${JSON.stringify(x)};
|
|
847
370
|
for (var si = 0; si < sels.length; si++) { composer = document.querySelector(sels[si]); if (composer) break; }
|
|
848
371
|
if (!composer) return;
|
|
849
372
|
composer.focus();
|
|
850
|
-
document.execCommand('insertText', false, ${JSON.stringify(
|
|
373
|
+
document.execCommand('insertText', false, ${JSON.stringify(X)});
|
|
851
374
|
})()
|
|
852
|
-
`);
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
let sent = null;
|
|
856
|
-
for (let attempt = 0; attempt < 20; attempt += 1) {
|
|
857
|
-
await page.wait(0.5);
|
|
858
|
-
sent = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
375
|
+
`)}let Z=null;for(let $=0;$<20;$+=1){await Q.wait(0.5);Z=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
859
376
|
(() => {
|
|
860
377
|
const isVisible = (el) => {
|
|
861
378
|
if (!(el instanceof HTMLElement)) return false;
|
|
@@ -870,10 +387,10 @@ export async function sendChatGPTMessage(page, text) {
|
|
|
870
387
|
&& button.getAttribute('aria-disabled') !== 'true';
|
|
871
388
|
const form = Array.from(document.querySelectorAll('form')).find((node) => node instanceof HTMLElement && isVisible(node));
|
|
872
389
|
const root = form || document.body;
|
|
873
|
-
const primary = root.querySelector(${JSON.stringify(
|
|
874
|
-
|| ${JSON.stringify(
|
|
390
|
+
const primary = root.querySelector(${JSON.stringify(U)})
|
|
391
|
+
|| ${JSON.stringify(L)}.map(selector => root.querySelector(selector)).find(Boolean);
|
|
875
392
|
const btns = Array.from(root.querySelectorAll('button'));
|
|
876
|
-
const labels = ${JSON.stringify(
|
|
393
|
+
const labels = ${JSON.stringify(y)};
|
|
877
394
|
const looksLikeSend = (button) => {
|
|
878
395
|
const label = button.getAttribute('aria-label') || '';
|
|
879
396
|
const text = (button.innerText || button.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
@@ -884,15 +401,7 @@ export async function sendChatGPTMessage(page, text) {
|
|
|
884
401
|
: btns.find(b => looksLikeSend(b) && isUsable(b));
|
|
885
402
|
return { sendBtnFound: !!sendBtn };
|
|
886
403
|
})()
|
|
887
|
-
`)),
|
|
888
|
-
if (sent?.sendBtnFound) break;
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
if (!sent?.sendBtnFound) {
|
|
892
|
-
return false;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
await page.evaluate(`
|
|
404
|
+
`)),"chatgpt send button readiness");if(Z?.sendBtnFound)break}if(!Z?.sendBtnFound)return!1;await Q.evaluate(`
|
|
896
405
|
(() => {
|
|
897
406
|
const isVisible = (el) => {
|
|
898
407
|
if (!(el instanceof HTMLElement)) return false;
|
|
@@ -907,9 +416,9 @@ export async function sendChatGPTMessage(page, text) {
|
|
|
907
416
|
&& button.getAttribute('aria-disabled') !== 'true';
|
|
908
417
|
const form = Array.from(document.querySelectorAll('form')).find((node) => node instanceof HTMLElement && isVisible(node));
|
|
909
418
|
const root = form || document.body;
|
|
910
|
-
const primary = root.querySelector(${JSON.stringify(
|
|
911
|
-
|| ${JSON.stringify(
|
|
912
|
-
const labels = ${JSON.stringify(
|
|
419
|
+
const primary = root.querySelector(${JSON.stringify(U)})
|
|
420
|
+
|| ${JSON.stringify(L)}.map(selector => root.querySelector(selector)).find(Boolean);
|
|
421
|
+
const labels = ${JSON.stringify(y)};
|
|
913
422
|
const looksLikeSend = (button) => {
|
|
914
423
|
const label = button.getAttribute('aria-label') || '';
|
|
915
424
|
const text = (button.innerText || button.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
@@ -920,12 +429,7 @@ export async function sendChatGPTMessage(page, text) {
|
|
|
920
429
|
: Array.from(root.querySelectorAll('button')).find(b => looksLikeSend(b) && isUsable(b));
|
|
921
430
|
if (sendBtn) sendBtn.click();
|
|
922
431
|
})()
|
|
923
|
-
`);
|
|
924
|
-
return true;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
export async function getVisibleMessages(page) {
|
|
928
|
-
const result = requireArrayEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
432
|
+
`);return!0}export async function getVisibleMessages(Q){return requireArrayEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
929
433
|
const isVisible = (el) => {
|
|
930
434
|
if (!(el instanceof HTMLElement)) return false;
|
|
931
435
|
const style = window.getComputedStyle(el);
|
|
@@ -971,200 +475,7 @@ export async function getVisibleMessages(page) {
|
|
|
971
475
|
rows.push({ role, text, html });
|
|
972
476
|
}
|
|
973
477
|
return rows;
|
|
974
|
-
})()`)),
|
|
975
|
-
return result.map((item, index) => ({
|
|
976
|
-
Index: index + 1,
|
|
977
|
-
Role: item?.role === 'Assistant' ? 'Assistant' : 'User',
|
|
978
|
-
Text: String(item?.text || '').trim(),
|
|
979
|
-
Html: String(item?.html || ''),
|
|
980
|
-
})).filter((item) => item.Text);
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
function formatChatGPTDetailMessages(messages, { wantMarkdown, generating, stableSeconds }) {
|
|
984
|
-
return messages.map((message) => ({
|
|
985
|
-
Index: message.Index,
|
|
986
|
-
Role: message.Role,
|
|
987
|
-
Text: wantMarkdown && message.Role === 'Assistant' && message.Html
|
|
988
|
-
? (messageHtmlToMarkdown(message.Html) || message.Text)
|
|
989
|
-
: message.Text,
|
|
990
|
-
Generating: generating,
|
|
991
|
-
StableSeconds: stableSeconds,
|
|
992
|
-
}));
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
export async function getChatGPTDetailRows(page, { wantMarkdown = false, stableSeconds = 0 } = {}) {
|
|
996
|
-
const generating = await isGenerating(page);
|
|
997
|
-
const messages = await getVisibleMessages(page);
|
|
998
|
-
return {
|
|
999
|
-
messages,
|
|
1000
|
-
rows: formatChatGPTDetailMessages(messages, { wantMarkdown, generating, stableSeconds }),
|
|
1001
|
-
generating,
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
export async function waitForChatGPTDetailRows(page, { wantMarkdown = false, timeoutSeconds = 120, stableSeconds = 6 } = {}) {
|
|
1006
|
-
const startTime = Date.now();
|
|
1007
|
-
let lastKey = '';
|
|
1008
|
-
let stableStartedAt = 0;
|
|
1009
|
-
|
|
1010
|
-
while (Date.now() - startTime < timeoutSeconds * 1000) {
|
|
1011
|
-
const generating = await isGenerating(page);
|
|
1012
|
-
const messages = await getVisibleMessages(page);
|
|
1013
|
-
const key = JSON.stringify(messages.map((message) => [message.Role, message.Text]));
|
|
1014
|
-
if (!generating && messages.length && messages[messages.length - 1]?.Role === 'Assistant') {
|
|
1015
|
-
if (key === lastKey) {
|
|
1016
|
-
if (!stableStartedAt) stableStartedAt = Date.now();
|
|
1017
|
-
const elapsedSeconds = Math.floor((Date.now() - stableStartedAt) / 1000);
|
|
1018
|
-
if (elapsedSeconds >= stableSeconds) {
|
|
1019
|
-
return {
|
|
1020
|
-
messages,
|
|
1021
|
-
rows: formatChatGPTDetailMessages(messages, {
|
|
1022
|
-
wantMarkdown,
|
|
1023
|
-
generating: false,
|
|
1024
|
-
stableSeconds: elapsedSeconds,
|
|
1025
|
-
}),
|
|
1026
|
-
generating: false,
|
|
1027
|
-
};
|
|
1028
|
-
}
|
|
1029
|
-
} else {
|
|
1030
|
-
lastKey = key;
|
|
1031
|
-
stableStartedAt = Date.now();
|
|
1032
|
-
}
|
|
1033
|
-
} else {
|
|
1034
|
-
lastKey = key;
|
|
1035
|
-
stableStartedAt = 0;
|
|
1036
|
-
}
|
|
1037
|
-
await page.wait(3);
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
throw new TimeoutError(
|
|
1041
|
-
'chatgpt detail',
|
|
1042
|
-
timeoutSeconds,
|
|
1043
|
-
'Conversation did not finish or stabilize before timeout. Re-run with a higher --timeout if it is still generating.',
|
|
1044
|
-
);
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
export function messageHtmlToMarkdown(html) {
|
|
1048
|
-
try {
|
|
1049
|
-
return htmlToMarkdown(html).trim();
|
|
1050
|
-
} catch {
|
|
1051
|
-
return String(html || '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
export async function getBubbleCount(page) {
|
|
1056
|
-
const messages = await getVisibleMessages(page);
|
|
1057
|
-
return messages.length;
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
function cleanPromptText(str) {
|
|
1061
|
-
return String(str || '')
|
|
1062
|
-
.replace(/\s+/g, ' ')
|
|
1063
|
-
.trim();
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
function responsePairKey(user, assistant) {
|
|
1067
|
-
return JSON.stringify([
|
|
1068
|
-
cleanPromptText(user?.Text),
|
|
1069
|
-
String(assistant?.Text || '').trim(),
|
|
1070
|
-
]);
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
export function getChatGPTResponsePairKeys(messages, prompt) {
|
|
1074
|
-
const promptKey = cleanPromptText(prompt);
|
|
1075
|
-
if (!promptKey) return [];
|
|
1076
|
-
const keys = [];
|
|
1077
|
-
for (let index = 0; index < messages.length; index += 1) {
|
|
1078
|
-
const user = messages[index];
|
|
1079
|
-
if (user?.Role !== 'User' || cleanPromptText(user.Text) !== promptKey) continue;
|
|
1080
|
-
const assistant = messages.slice(index + 1).find((message) => message?.Role === 'Assistant');
|
|
1081
|
-
if (!assistant || !String(assistant.Text || '').trim()) continue;
|
|
1082
|
-
keys.push(responsePairKey(user, assistant));
|
|
1083
|
-
}
|
|
1084
|
-
return keys;
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
export function getChatGPTResponsePairCounts(messages, prompt) {
|
|
1088
|
-
const counts = new Map();
|
|
1089
|
-
for (const key of getChatGPTResponsePairKeys(messages, prompt)) {
|
|
1090
|
-
counts.set(key, (counts.get(key) || 0) + 1);
|
|
1091
|
-
}
|
|
1092
|
-
return counts;
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
function normalizeBaselinePairCounts(options) {
|
|
1096
|
-
if (options.baselinePairCounts instanceof Map) return options.baselinePairCounts;
|
|
1097
|
-
return new Map(Array.from(options.baselinePairKeys || []).map((key) => [key, 1]));
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
function findLatestNewAssistantResponse(messages, prompt, baselinePairCounts) {
|
|
1101
|
-
const promptKey = cleanPromptText(prompt);
|
|
1102
|
-
if (!promptKey) return '';
|
|
1103
|
-
const currentPairCounts = getChatGPTResponsePairCounts(messages, prompt);
|
|
1104
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
1105
|
-
const user = messages[index];
|
|
1106
|
-
if (user?.Role !== 'User' || cleanPromptText(user.Text) !== promptKey) continue;
|
|
1107
|
-
const assistantIndex = messages.findIndex((message, candidateIndex) => (
|
|
1108
|
-
candidateIndex > index
|
|
1109
|
-
&& message?.Role === 'Assistant'
|
|
1110
|
-
&& String(message.Text || '').trim()
|
|
1111
|
-
));
|
|
1112
|
-
if (assistantIndex < 0) continue;
|
|
1113
|
-
const assistant = messages[assistantIndex];
|
|
1114
|
-
const key = responsePairKey(user, assistant);
|
|
1115
|
-
if ((currentPairCounts.get(key) || 0) <= (baselinePairCounts.get(key) || 0)) continue;
|
|
1116
|
-
return String(assistant.Text || '').trim();
|
|
1117
|
-
}
|
|
1118
|
-
return '';
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
export async function waitForChatGPTResponse(page, baselineCount, prompt, timeoutSeconds, options = {}) {
|
|
1122
|
-
const startTime = Date.now();
|
|
1123
|
-
let lastText = '';
|
|
1124
|
-
let stableCount = 0;
|
|
1125
|
-
const baselinePairCounts = normalizeBaselinePairCounts(options);
|
|
1126
|
-
|
|
1127
|
-
while (Date.now() - startTime < timeoutSeconds * 1000) {
|
|
1128
|
-
await page.wait(3);
|
|
1129
|
-
if (options.conversationUrl) {
|
|
1130
|
-
const currentUrl = await currentChatGPTUrl(page);
|
|
1131
|
-
if (currentUrl && !isSameChatGPTConversation(currentUrl, options.conversationUrl)) {
|
|
1132
|
-
throw new CommandExecutionError(
|
|
1133
|
-
`ChatGPT navigated away from the target conversation (${options.conversationUrl}); current URL is ${currentUrl}`,
|
|
1134
|
-
);
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
if (await isGenerating(page)) {
|
|
1138
|
-
stableCount = 0;
|
|
1139
|
-
continue;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
const messages = await getVisibleMessages(page);
|
|
1143
|
-
const candidate = findLatestNewAssistantResponse(messages, prompt, baselinePairCounts);
|
|
1144
|
-
if (!candidate || candidate === String(prompt || '').trim()) continue;
|
|
1145
|
-
|
|
1146
|
-
if (candidate === lastText) {
|
|
1147
|
-
stableCount += 1;
|
|
1148
|
-
if (stableCount >= 2) return candidate;
|
|
1149
|
-
} else {
|
|
1150
|
-
lastText = candidate;
|
|
1151
|
-
stableCount = 0;
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
throw new TimeoutError(
|
|
1156
|
-
'chatgpt ask',
|
|
1157
|
-
timeoutSeconds,
|
|
1158
|
-
'No ChatGPT response appeared before timeout. Re-run with a higher --timeout if it is still generating.',
|
|
1159
|
-
);
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
export async function getConversationList(page) {
|
|
1163
|
-
// ensureOnChatGPT already waits for the composer selector after navigation,
|
|
1164
|
-
// so the previous standalone 2 s settle is redundant.
|
|
1165
|
-
await ensureOnChatGPT(page);
|
|
1166
|
-
|
|
1167
|
-
const openSidebar = requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
478
|
+
})()`)),"chatgpt visible messages").map((Y,Z)=>({Index:Z+1,Role:Y?.role==="Assistant"?"Assistant":"User",Text:String(Y?.text||"").trim(),Html:String(Y?.html||"")})).filter((Y)=>Y.Text)}function h(Q,{wantMarkdown:X,generating:Y,stableSeconds:Z}){return Q.map(($)=>({Index:$.Index,Role:$.Role,Text:X&&$.Role==="Assistant"&&$.Html?messageHtmlToMarkdown($.Html)||$.Text:$.Text,Generating:Y,StableSeconds:Z}))}export async function getChatGPTDetailRows(Q,{wantMarkdown:X=!1,stableSeconds:Y=0}={}){const Z=await isGenerating(Q),$=await getVisibleMessages(Q);return{messages:$,rows:h($,{wantMarkdown:X,generating:Z,stableSeconds:Y}),generating:Z}}export async function waitForChatGPTDetailRows(Q,{wantMarkdown:X=!1,timeoutSeconds:Y=120,stableSeconds:Z=6}={}){const $=Date.now();let W="",V=0;while(Date.now()-$<Y*1000){const z=await isGenerating(Q),q=await getVisibleMessages(Q),j=JSON.stringify(q.map((J)=>[J.Role,J.Text]));if(!z&&q.length&&q[q.length-1]?.Role==="Assistant")if(j===W){if(!V)V=Date.now();const J=Math.floor((Date.now()-V)/1000);if(J>=Z)return{messages:q,rows:h(q,{wantMarkdown:X,generating:!1,stableSeconds:J}),generating:!1}}else{W=j;V=Date.now()}else{W=j;V=0}await Q.wait(3)}throw new O("chatgpt detail",Y,"Conversation did not finish or stabilize before timeout. Re-run with a higher --timeout if it is still generating.")}export function messageHtmlToMarkdown(Q){try{return i(Q).trim()}catch{return String(Q||"").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}}export async function getBubbleCount(Q){return(await getVisibleMessages(Q)).length}function M(Q){return String(Q||"").replace(/\s+/g," ").trim()}function E(Q,X){return JSON.stringify([M(Q?.Text),String(X?.Text||"").trim()])}export function getChatGPTResponsePairKeys(Q,X){const Y=M(X);if(!Y)return[];const Z=[];for(let $=0;$<Q.length;$+=1){const W=Q[$];if(W?.Role!=="User"||M(W.Text)!==Y)continue;const V=Q.slice($+1).find((z)=>z?.Role==="Assistant");if(!V||!String(V.Text||"").trim())continue;Z.push(E(W,V))}return Z}export function getChatGPTResponsePairCounts(Q,X){const Y=new Map;for(const Z of getChatGPTResponsePairKeys(Q,X))Y.set(Z,(Y.get(Z)||0)+1);return Y}function l(Q){if(Q.baselinePairCounts instanceof Map)return Q.baselinePairCounts;return new Map(Array.from(Q.baselinePairKeys||[]).map((X)=>[X,1]))}function r(Q,X,Y){const Z=M(X);if(!Z)return"";const $=getChatGPTResponsePairCounts(Q,X);for(let W=Q.length-1;W>=0;W-=1){const V=Q[W];if(V?.Role!=="User"||M(V.Text)!==Z)continue;const z=Q.findIndex((J,K)=>K>W&&J?.Role==="Assistant"&&String(J.Text||"").trim());if(z<0)continue;const q=Q[z],j=E(V,q);if(($.get(j)||0)<=(Y.get(j)||0))continue;return String(q.Text||"").trim()}return""}export async function waitForChatGPTResponse(Q,X,Y,Z,$={}){const W=Date.now();let V="",z=0;const q=l($);while(Date.now()-W<Z*1000){await Q.wait(3);if($.conversationUrl){const K=await currentChatGPTUrl(Q);if(K&&!N(K,$.conversationUrl))throw new F(`ChatGPT navigated away from the target conversation (${$.conversationUrl}); current URL is ${K}`)}if(await isGenerating(Q)){z=0;continue}const j=await getVisibleMessages(Q),J=r(j,Y,q);if(!J||J===String(Y||"").trim())continue;if(J===V){z+=1;if(z>=2)return J}else{V=J;z=0}}throw new O("chatgpt ask",Z,"No ChatGPT response appeared before timeout. Re-run with a higher --timeout if it is still generating.")}export async function getConversationList(Q){await ensureOnChatGPT(Q);if(requireBooleanEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
1168
479
|
const button = Array.from(document.querySelectorAll('button'))
|
|
1169
480
|
.find((node) => /open sidebar/i.test(node.getAttribute('aria-label') || ''));
|
|
1170
481
|
if (button instanceof HTMLElement) {
|
|
@@ -1172,31 +483,7 @@ export async function getConversationList(page) {
|
|
|
1172
483
|
return true;
|
|
1173
484
|
}
|
|
1174
485
|
return false;
|
|
1175
|
-
})()`)),
|
|
1176
|
-
if (openSidebar) {
|
|
1177
|
-
try {
|
|
1178
|
-
await page.wait({ selector: CONVERSATION_LINK_SELECTOR, timeout: 3 });
|
|
1179
|
-
} catch {
|
|
1180
|
-
// Sidebar slide-in didn't surface conversation links; extractConversationLinks below tolerates empty and falls back to home goto.
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
let items = await extractConversationLinks(page);
|
|
1185
|
-
if (!items.length) {
|
|
1186
|
-
await page.goto(CHATGPT_URL, { settleMs: 2000 });
|
|
1187
|
-
try {
|
|
1188
|
-
await page.wait({ selector: CONVERSATION_LINK_SELECTOR, timeout: 8 });
|
|
1189
|
-
} catch {
|
|
1190
|
-
// No conversation links visible after fallback goto; extractConversationLinks returns empty.
|
|
1191
|
-
}
|
|
1192
|
-
items = await extractConversationLinks(page);
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
return items;
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
async function extractConversationLinks(page) {
|
|
1199
|
-
const items = requireArrayEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
486
|
+
})()`)),"chatgpt sidebar open state"))try{await Q.wait({selector:R,timeout:3})}catch{}let Y=await C(Q);if(!Y.length){await Q.goto(CHATGPT_URL,{settleMs:2000});try{await Q.wait({selector:R,timeout:8})}catch{}Y=await C(Q)}return Y}async function C(Q){return requireArrayEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
1200
487
|
const isVisible = (el) => {
|
|
1201
488
|
if (!(el instanceof HTMLElement)) return false;
|
|
1202
489
|
const style = window.getComputedStyle(el);
|
|
@@ -1221,58 +508,9 @@ async function extractConversationLinks(page) {
|
|
|
1221
508
|
});
|
|
1222
509
|
}
|
|
1223
510
|
return rows;
|
|
1224
|
-
})()`)),
|
|
1225
|
-
return items.map((item, index) => ({
|
|
1226
|
-
Index: index + 1,
|
|
1227
|
-
Id: String(item?.Id || ''),
|
|
1228
|
-
Title: String(item?.Title || '(untitled)').trim() || '(untitled)',
|
|
1229
|
-
Url: String(item?.Url || ''),
|
|
1230
|
-
})).filter((item) => item.Id);
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
function imageMimeFromPath(filePath) {
|
|
1234
|
-
const lower = String(filePath || '').toLowerCase();
|
|
1235
|
-
if (lower.endsWith('.png')) return 'image/png';
|
|
1236
|
-
if (lower.endsWith('.webp')) return 'image/webp';
|
|
1237
|
-
if (lower.endsWith('.gif')) return 'image/gif';
|
|
1238
|
-
if (lower.endsWith('.heic')) return 'image/heic';
|
|
1239
|
-
if (lower.endsWith('.heif')) return 'image/heif';
|
|
1240
|
-
return 'image/jpeg';
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
export async function prepareChatGPTImagePaths(imagePaths) {
|
|
1244
|
-
const fs = await import('node:fs');
|
|
1245
|
-
const path = await import('node:path');
|
|
1246
|
-
const absPaths = imagePaths.map(filePath => path.default.resolve(filePath));
|
|
1247
|
-
const allowedExts = new Set(['.jpg', '.jpeg', '.png', '.webp', '.gif', '.heic', '.heif']);
|
|
1248
|
-
|
|
1249
|
-
for (const absPath of absPaths) {
|
|
1250
|
-
if (!fs.default.existsSync(absPath)) {
|
|
1251
|
-
return { ok: false, reason: `Image not found: ${absPath}` };
|
|
1252
|
-
}
|
|
1253
|
-
const stat = fs.default.statSync(absPath);
|
|
1254
|
-
if (!stat.isFile()) {
|
|
1255
|
-
return { ok: false, reason: `Not a file: ${absPath}` };
|
|
1256
|
-
}
|
|
1257
|
-
if (stat.size > 25 * 1024 * 1024) {
|
|
1258
|
-
return { ok: false, reason: `Image too large (${(stat.size / 1024 / 1024).toFixed(1)} MB). Max: 25 MB` };
|
|
1259
|
-
}
|
|
1260
|
-
const ext = path.default.extname(absPath).toLowerCase();
|
|
1261
|
-
if (!allowedExts.has(ext)) {
|
|
1262
|
-
return { ok: false, reason: `Unsupported image type: ${absPath}` };
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
return { ok: true, paths: absPaths };
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
async function waitForChatGPTUploadPreview(page, fileNames) {
|
|
1270
|
-
const namesJson = JSON.stringify(fileNames);
|
|
1271
|
-
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
1272
|
-
await page.wait(1);
|
|
1273
|
-
const ready = requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
511
|
+
})()`)),"chatgpt conversation link extraction").map((Y,Z)=>({Index:Z+1,Id:String(Y?.Id||""),Title:String(Y?.Title||"(untitled)").trim()||"(untitled)",Url:String(Y?.Url||"")})).filter((Y)=>Y.Id)}function P(Q){const X=String(Q||"").toLowerCase();if(X.endsWith(".png"))return"image/png";if(X.endsWith(".webp"))return"image/webp";if(X.endsWith(".gif"))return"image/gif";if(X.endsWith(".heic"))return"image/heic";if(X.endsWith(".heif"))return"image/heif";return"image/jpeg"}export async function prepareChatGPTImagePaths(Q){const X=await import("node:fs"),Y=await import("node:path"),Z=Q.map((W)=>Y.default.resolve(W)),$=new Set([".jpg",".jpeg",".png",".webp",".gif",".heic",".heif"]);for(const W of Z){if(!X.default.existsSync(W))return{ok:!1,reason:`Image not found: ${W}`};const V=X.default.statSync(W);if(!V.isFile())return{ok:!1,reason:`Not a file: ${W}`};if(V.size>26214400)return{ok:!1,reason:`Image too large (${(V.size/1024/1024).toFixed(1)} MB). Max: 25 MB`};const z=Y.default.extname(W).toLowerCase();if(!$.has(z))return{ok:!1,reason:`Unsupported image type: ${W}`}}return{ok:!0,paths:Z}}async function p(Q,X){const Y=JSON.stringify(X);for(let Z=0;Z<10;Z+=1){await Q.wait(1);if(requireBooleanEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
1274
512
|
(() => {
|
|
1275
|
-
const names = ${
|
|
513
|
+
const names = ${Y};
|
|
1276
514
|
const text = document.body ? (document.body.innerText || '') : '';
|
|
1277
515
|
const matchedNames = names.filter(name => text.includes(name)).length;
|
|
1278
516
|
if (matchedNames >= names.length) return true;
|
|
@@ -1297,43 +535,9 @@ async function waitForChatGPTUploadPreview(page, fileNames) {
|
|
|
1297
535
|
const previewNodes = Array.from(scope.querySelectorAll('img[src], canvas, video, [style*="background-image"]')).filter(isVisibleMedia);
|
|
1298
536
|
return previewNodes.length >= names.length;
|
|
1299
537
|
})()
|
|
1300
|
-
`)),
|
|
1301
|
-
if (ready) return true;
|
|
1302
|
-
}
|
|
1303
|
-
return false;
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
export async function uploadChatGPTImages(page, imagePaths) {
|
|
1307
|
-
const fs = await import('node:fs');
|
|
1308
|
-
const path = await import('node:path');
|
|
1309
|
-
const prepared = await prepareChatGPTImagePaths(imagePaths);
|
|
1310
|
-
if (!prepared.ok) return prepared;
|
|
1311
|
-
const absPaths = prepared.paths;
|
|
1312
|
-
|
|
1313
|
-
const fileNames = absPaths.map(filePath => path.default.basename(filePath));
|
|
1314
|
-
|
|
1315
|
-
let uploaded = false;
|
|
1316
|
-
if (page.setFileInput) {
|
|
1317
|
-
try {
|
|
1318
|
-
await page.setFileInput(absPaths, 'input[type="file"]');
|
|
1319
|
-
uploaded = true;
|
|
1320
|
-
} catch (err) {
|
|
1321
|
-
const msg = String(err?.message || err);
|
|
1322
|
-
if (!msg.includes('Unknown action') && !msg.includes('not supported') && !msg.includes('Not allowed') && !msg.includes('No element found')) {
|
|
1323
|
-
throw err;
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
if (!uploaded) {
|
|
1329
|
-
const files = absPaths.map(absPath => ({
|
|
1330
|
-
name: path.default.basename(absPath),
|
|
1331
|
-
mime: imageMimeFromPath(absPath),
|
|
1332
|
-
base64: fs.default.readFileSync(absPath).toString('base64'),
|
|
1333
|
-
}));
|
|
1334
|
-
const fallbackResult = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
538
|
+
`)),"chatgpt upload preview detection"))return!0}return!1}export async function uploadChatGPTImages(Q,X){const Y=await import("node:fs"),Z=await import("node:path"),$=await prepareChatGPTImagePaths(X);if(!$.ok)return $;const W=$.paths,V=W.map((j)=>Z.default.basename(j));let z=!1;if(Q.setFileInput)try{await Q.setFileInput(W,'input[type="file"]');z=!0}catch(j){const J=String(j?.message||j);if(!J.includes("Unknown action")&&!J.includes("not supported")&&!J.includes("Not allowed")&&!J.includes("No element found"))throw j}if(!z){const j=W.map((K)=>({name:Z.default.basename(K),mime:P(K),base64:Y.default.readFileSync(K).toString("base64")})),J=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
1335
539
|
(() => {
|
|
1336
|
-
const files = ${JSON.stringify(
|
|
540
|
+
const files = ${JSON.stringify(j)};
|
|
1337
541
|
const input = document.querySelector('input[type="file"]');
|
|
1338
542
|
if (!(input instanceof HTMLInputElement)) {
|
|
1339
543
|
return { ok: false, reason: 'file input not found' };
|
|
@@ -1367,21 +571,7 @@ export async function uploadChatGPTImages(page, imagePaths) {
|
|
|
1367
571
|
}
|
|
1368
572
|
return { ok: true };
|
|
1369
573
|
})()
|
|
1370
|
-
`)),
|
|
1371
|
-
if (fallbackResult && !fallbackResult.ok) return fallbackResult;
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
const ready = await waitForChatGPTUploadPreview(page, fileNames);
|
|
1375
|
-
if (!ready) return { ok: false, reason: 'image upload preview did not appear' };
|
|
1376
|
-
|
|
1377
|
-
return { ok: true, files: absPaths };
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
/**
|
|
1381
|
-
* Check if ChatGPT is still generating a response.
|
|
1382
|
-
*/
|
|
1383
|
-
export async function isGenerating(page) {
|
|
1384
|
-
return requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
574
|
+
`)),"chatgpt image upload fallback");if(J&&!J.ok)return J}if(!await p(Q,V))return{ok:!1,reason:"image upload preview did not appear"};return{ok:!0,files:W}}export async function isGenerating(Q){return requireBooleanEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
1385
575
|
(() => {
|
|
1386
576
|
const text = (document.body?.innerText || '').replace(/\\s+/g, ' ');
|
|
1387
577
|
if (/正在思考|停止生成|Thinking/.test(text)) return true;
|
|
@@ -1393,14 +583,7 @@ export async function isGenerating(page) {
|
|
|
1393
583
|
|| label.includes('正在思考');
|
|
1394
584
|
});
|
|
1395
585
|
})()
|
|
1396
|
-
`)),
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
/**
|
|
1400
|
-
* Get visible image URLs from the ChatGPT page (excluding profile/avatar images).
|
|
1401
|
-
*/
|
|
1402
|
-
export async function getChatGPTVisibleImageUrls(page) {
|
|
1403
|
-
return requireArrayEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
586
|
+
`)),"chatgpt generation state")}export async function getChatGPTVisibleImageUrls(Q){return requireArrayEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
1404
587
|
(() => {
|
|
1405
588
|
const isVisible = (el) => {
|
|
1406
589
|
if (!(el instanceof HTMLElement)) return false;
|
|
@@ -1444,7 +627,7 @@ export async function getChatGPTVisibleImageUrls(page) {
|
|
|
1444
627
|
if (/chatgpt|assistant|助手/.test(heading)) return false;
|
|
1445
628
|
const openButtonLabel = (img.closest('button[aria-label^="Open image:"]')?.getAttribute('aria-label') || '').toLowerCase();
|
|
1446
629
|
const previewText = [alt, openButtonLabel].join(' ');
|
|
1447
|
-
return
|
|
630
|
+
return /.(png|jpe?g|webp|gif|heic|heif)(?:\b|$)/i.test(previewText)
|
|
1448
631
|
|| /ref-|reference|参考|upload|uploaded|attachment/.test(previewText);
|
|
1449
632
|
};
|
|
1450
633
|
|
|
@@ -1518,71 +701,9 @@ export async function getChatGPTVisibleImageUrls(page) {
|
|
|
1518
701
|
}
|
|
1519
702
|
return urls;
|
|
1520
703
|
})()
|
|
1521
|
-
`)),
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
/**
|
|
1525
|
-
* Wait for new images to appear after sending a prompt.
|
|
1526
|
-
*/
|
|
1527
|
-
export async function waitForChatGPTImages(page, beforeUrls, timeoutSeconds, convUrl) {
|
|
1528
|
-
const beforeSet = new Set(beforeUrls);
|
|
1529
|
-
const pollIntervalSeconds = 3;
|
|
1530
|
-
const maxPolls = Math.max(1, Math.ceil(timeoutSeconds / pollIntervalSeconds));
|
|
1531
|
-
let lastUrls = [];
|
|
1532
|
-
let stableCount = 0;
|
|
1533
|
-
|
|
1534
|
-
for (let i = 0; i < maxPolls; i++) {
|
|
1535
|
-
await page.wait(i === 0 ? 3 : pollIntervalSeconds);
|
|
1536
|
-
|
|
1537
|
-
let currentUrl = '';
|
|
1538
|
-
if (convUrl && convUrl.includes('/c/')) {
|
|
1539
|
-
currentUrl = unwrapEvaluateResult(await page.evaluate('window.location.href').catch(() => ''));
|
|
1540
|
-
if (currentUrl && !isSameChatGPTConversation(currentUrl, convUrl)) {
|
|
1541
|
-
await page.goto(convUrl);
|
|
1542
|
-
await page.wait(3);
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
const generating = await isGenerating(page);
|
|
1547
|
-
if (generating) continue;
|
|
1548
|
-
|
|
1549
|
-
if (convUrl && convUrl.includes('/c/') && i > 0 && i % 5 === 0) {
|
|
1550
|
-
const onConversation = !currentUrl || isSameChatGPTConversation(currentUrl, convUrl);
|
|
1551
|
-
if (onConversation) {
|
|
1552
|
-
await page.goto(convUrl);
|
|
1553
|
-
await page.wait(3);
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
const urls = (await getChatGPTVisibleImageUrls(page)).filter(url => !beforeSet.has(url));
|
|
1558
|
-
if (urls.length === 0) continue;
|
|
1559
|
-
|
|
1560
|
-
const key = urls.join('\n');
|
|
1561
|
-
const prevKey = lastUrls.join('\n');
|
|
1562
|
-
if (key === prevKey) {
|
|
1563
|
-
stableCount += 1;
|
|
1564
|
-
} else {
|
|
1565
|
-
lastUrls = urls;
|
|
1566
|
-
stableCount = 1;
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
if (stableCount >= 2 || i === maxPolls - 1) {
|
|
1570
|
-
return lastUrls;
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
return lastUrls;
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
/**
|
|
1577
|
-
* Get the list of ChatGPT Projects from the sidebar.
|
|
1578
|
-
* Navigates to chatgpt.com if not already there, opens the sidebar,
|
|
1579
|
-
* and extracts project links (matching /g/g-p-*).
|
|
1580
|
-
*/
|
|
1581
|
-
export async function getProjectList(page) {
|
|
1582
|
-
await ensureOnChatGPT(page);
|
|
1583
|
-
|
|
1584
|
-
// Ensure sidebar is open
|
|
1585
|
-
const openSidebar = requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
704
|
+
`)),"chatgpt visible image url extraction")}export async function waitForChatGPTImages(Q,X,Y,Z){const $=new Set(X),W=3,V=Math.max(1,Math.ceil(Y/W));let z=[],q=0;for(let j=0;j<V;j++){await Q.wait(j===0?3:W);let J="";if(Z&&Z.includes("/c/")){J=unwrapEvaluateResult(await Q.evaluate("window.location.href").catch(()=>""));if(J&&!N(J,Z)){await Q.goto(Z);await Q.wait(3)}}if(await isGenerating(Q))continue;if(Z&&Z.includes("/c/")&&j>0&&j%5===0){if(!J||N(J,Z)){await Q.goto(Z);await Q.wait(3)}}const B=(await getChatGPTVisibleImageUrls(Q)).filter((b)=>!$.has(b));if(B.length===0)continue;const H=B.join(`
|
|
705
|
+
`),D=z.join(`
|
|
706
|
+
`);if(H===D)q+=1;else{z=B;q=1}if(q>=2||j===V-1)return z}return z}export async function getProjectList(Q){await ensureOnChatGPT(Q);if(requireBooleanEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
1586
707
|
const button = Array.from(document.querySelectorAll('button'))
|
|
1587
708
|
.find((node) => /open sidebar/i.test(node.getAttribute('aria-label') || ''));
|
|
1588
709
|
if (button instanceof HTMLElement) {
|
|
@@ -1590,13 +711,7 @@ export async function getProjectList(page) {
|
|
|
1590
711
|
return true;
|
|
1591
712
|
}
|
|
1592
713
|
return false;
|
|
1593
|
-
})()`)),
|
|
1594
|
-
if (openSidebar) {
|
|
1595
|
-
await page.wait(0.5);
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
// Click "Show more" to reveal all projects
|
|
1599
|
-
await page.evaluate(`(() => {
|
|
714
|
+
})()`)),"chatgpt sidebar open state"))await Q.wait(0.5);await Q.evaluate(`(() => {
|
|
1600
715
|
var btn = Array.from(document.querySelectorAll('button')).find(function(b) {
|
|
1601
716
|
var text = (b.innerText || '').trim();
|
|
1602
717
|
return text === 'Show more' || text === '显示更多' || text === '查看更多';
|
|
@@ -1604,15 +719,7 @@ export async function getProjectList(page) {
|
|
|
1604
719
|
if (btn instanceof HTMLElement) {
|
|
1605
720
|
btn.click();
|
|
1606
721
|
}
|
|
1607
|
-
})()`);
|
|
1608
|
-
await page.wait(0.5);
|
|
1609
|
-
|
|
1610
|
-
let items = await extractProjectLinks(page);
|
|
1611
|
-
if (!items.length) {
|
|
1612
|
-
await page.goto(CHATGPT_URL, { settleMs: 2000 });
|
|
1613
|
-
await page.wait(1);
|
|
1614
|
-
// Try clicking Show more again on fresh page
|
|
1615
|
-
await page.evaluate(`(() => {
|
|
722
|
+
})()`);await Q.wait(0.5);let Y=await T(Q);if(!Y.length){await Q.goto(CHATGPT_URL,{settleMs:2000});await Q.wait(1);await Q.evaluate(`(() => {
|
|
1616
723
|
var btn = Array.from(document.querySelectorAll('button')).find(function(b) {
|
|
1617
724
|
var text = (b.innerText || '').trim();
|
|
1618
725
|
return text === 'Show more' || text === '显示更多' || text === '查看更多';
|
|
@@ -1620,17 +727,8 @@ export async function getProjectList(page) {
|
|
|
1620
727
|
if (btn instanceof HTMLElement) {
|
|
1621
728
|
btn.click();
|
|
1622
729
|
}
|
|
1623
|
-
})()`);
|
|
1624
|
-
|
|
1625
|
-
items = await extractProjectLinks(page);
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
return items;
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
async function extractProjectLinks(page) {
|
|
1632
|
-
const items = requireArrayEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
1633
|
-
const projectLinkSelector = ${JSON.stringify(PROJECT_LINK_SELECTOR)};
|
|
730
|
+
})()`);await Q.wait(0.5);Y=await T(Q)}return Y}async function T(Q){return requireArrayEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`(() => {
|
|
731
|
+
const projectLinkSelector = ${JSON.stringify(c)};
|
|
1634
732
|
const isVisible = (el) => {
|
|
1635
733
|
if (!(el instanceof HTMLElement)) return false;
|
|
1636
734
|
const style = window.getComputedStyle(el);
|
|
@@ -1739,67 +837,9 @@ async function extractProjectLinks(page) {
|
|
|
1739
837
|
}
|
|
1740
838
|
|
|
1741
839
|
return rows;
|
|
1742
|
-
})()`)),
|
|
1743
|
-
return items.map(function(item, index) {
|
|
1744
|
-
return {
|
|
1745
|
-
Index: index + 1,
|
|
1746
|
-
Id: String(item?.Id || ''),
|
|
1747
|
-
Title: String(item?.Title || '(untitled project)').trim() || '(untitled project)',
|
|
1748
|
-
Url: String(item?.Url || ''),
|
|
1749
|
-
};
|
|
1750
|
-
}).filter(function(item) { return item.Id; });
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
/**
|
|
1754
|
-
* Navigate to a ChatGPT project page.
|
|
1755
|
-
*/
|
|
1756
|
-
const PROJECT_ADD_FILES_LABELS = [
|
|
1757
|
-
'Add files',
|
|
1758
|
-
'Add sources',
|
|
1759
|
-
'添加文件',
|
|
1760
|
-
'Project files',
|
|
1761
|
-
'项目文件',
|
|
1762
|
-
];
|
|
1763
|
-
|
|
1764
|
-
const PROJECT_ADD_FILES_DIALOG_SELECTORS = [
|
|
1765
|
-
'[role="tabpanel"][data-state="active"] [data-project-home-sources-surface="true"] input[type="file"]:not([accept])',
|
|
1766
|
-
'[data-project-home-sources-surface="true"] input[type="file"]:not([accept])',
|
|
1767
|
-
'[role="dialog"] input[type="file"]',
|
|
1768
|
-
'[data-testid*="project-files"] input[type="file"]',
|
|
1769
|
-
'[data-testid*="project"] input[type="file"]',
|
|
1770
|
-
];
|
|
1771
|
-
|
|
1772
|
-
/**
|
|
1773
|
-
* Navigate to a ChatGPT project page.
|
|
1774
|
-
*/
|
|
1775
|
-
export async function navigateToProject(page, projectId) {
|
|
1776
|
-
const id = parseChatGPTProjectId(projectId);
|
|
1777
|
-
await page.goto(`${CHATGPT_URL}/g/g-p-${id}`, { settleMs: 2000 });
|
|
1778
|
-
try {
|
|
1779
|
-
await page.wait({ selector: COMPOSER_WAIT_SELECTOR, timeout: 10 });
|
|
1780
|
-
} catch {
|
|
1781
|
-
// Composer may not mount if project requires login; downstream ensureChatGPTLogin handles it.
|
|
1782
|
-
}
|
|
1783
|
-
const state = await getPageState(page);
|
|
1784
|
-
if (projectIdFromUrl(state.url) === id) return id;
|
|
1785
|
-
if (state.hasLoginGate || !state.isLoggedIn) {
|
|
1786
|
-
throw new AuthRequiredError(CHATGPT_DOMAIN, 'ChatGPT project requires a logged-in ChatGPT session.');
|
|
1787
|
-
}
|
|
1788
|
-
throw new CommandExecutionError(
|
|
1789
|
-
`ChatGPT did not open the requested project ${id}.`,
|
|
1790
|
-
`Current URL: ${state.url || '(unknown)'}`,
|
|
1791
|
-
);
|
|
1792
|
-
}
|
|
1793
|
-
|
|
1794
|
-
/**
|
|
1795
|
-
* Open the Project knowledge files dialog by clicking the "Add files" button
|
|
1796
|
-
* in the project header area (NOT the chat composer's plus button).
|
|
1797
|
-
* Returns true if the dialog appeared.
|
|
1798
|
-
*/
|
|
1799
|
-
export async function openProjectKnowledgeDialog(page) {
|
|
1800
|
-
const rawOpenResult = unwrapEvaluateResult(await page.evaluate(`
|
|
840
|
+
})()`)),"chatgpt project link extraction").map(function(Y,Z){return{Index:Z+1,Id:String(Y?.Id||""),Title:String(Y?.Title||"(untitled project)").trim()||"(untitled project)",Url:String(Y?.Url||"")}}).filter(function(Y){return Y.Id})}const s=["Add files","Add sources","添加文件","Project files","项目文件"],d=['[role="tabpanel"][data-state="active"] [data-project-home-sources-surface="true"] input[type="file"]:not([accept])','[data-project-home-sources-surface="true"] input[type="file"]:not([accept])','[role="dialog"] input[type="file"]','[data-testid*="project-files"] input[type="file"]','[data-testid*="project"] input[type="file"]'];export async function navigateToProject(Q,X){const Y=parseChatGPTProjectId(X);await Q.goto(`${CHATGPT_URL}/g/g-p-${Y}`,{settleMs:2000});try{await Q.wait({selector:f,timeout:10})}catch{}const Z=await getPageState(Q);if(S(Z.url)===Y)return Y;if(Z.hasLoginGate||!Z.isLoggedIn)throw new _(CHATGPT_DOMAIN,"ChatGPT project requires a logged-in ChatGPT session.");throw new F(`ChatGPT did not open the requested project ${Y}.`,`Current URL: ${Z.url||"(unknown)"}`)}export async function openProjectKnowledgeDialog(Q){const X=unwrapEvaluateResult(await Q.evaluate(`
|
|
1801
841
|
(() => {
|
|
1802
|
-
const labels = ${JSON.stringify(
|
|
842
|
+
const labels = ${JSON.stringify(s)};
|
|
1803
843
|
const isVisible = (el) => {
|
|
1804
844
|
if (!(el instanceof HTMLElement)) return false;
|
|
1805
845
|
const style = window.getComputedStyle(el);
|
|
@@ -1879,85 +919,12 @@ export async function openProjectKnowledgeDialog(page) {
|
|
|
1879
919
|
|
|
1880
920
|
return { ok: false };
|
|
1881
921
|
})()
|
|
1882
|
-
`));
|
|
1883
|
-
const openResult = typeof rawOpenResult === 'boolean'
|
|
1884
|
-
? { ok: rawOpenResult }
|
|
1885
|
-
: requireObjectEvaluateResult(rawOpenResult, 'chatgpt project knowledge dialog open');
|
|
1886
|
-
|
|
1887
|
-
if (openResult.ok) {
|
|
1888
|
-
if (openResult.nativeClick && typeof page.nativeClick === 'function') {
|
|
1889
|
-
try { await page.nativeClick(openResult.nativeClick.x, openResult.nativeClick.y); } catch {}
|
|
1890
|
-
}
|
|
1891
|
-
if (openResult.nativeClick && typeof page.click === 'function') {
|
|
1892
|
-
try { await page.click('[role="tab"][id$="-sources"]'); } catch {}
|
|
1893
|
-
}
|
|
1894
|
-
// Wait for the dialog or Sources tab content to appear
|
|
1895
|
-
await page.wait(1);
|
|
1896
|
-
try {
|
|
1897
|
-
await page.wait({ selector: '[role="dialog"], [data-project-home-sources-surface="true"] input[type="file"]', timeout: 5 });
|
|
1898
|
-
} catch {
|
|
1899
|
-
// Dialog/source input may use a different shape; upload selectors surface the precise failure.
|
|
1900
|
-
}
|
|
1901
|
-
return true;
|
|
1902
|
-
}
|
|
1903
|
-
return false;
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
/**
|
|
1907
|
-
* Upload files to a ChatGPT Project's knowledge base.
|
|
1908
|
-
* This navigates to the project page, opens the knowledge files dialog,
|
|
1909
|
-
* and uploads files through the dialog's file input.
|
|
1910
|
-
*/
|
|
1911
|
-
export async function uploadChatGPTProjectFiles(page, projectId, filePaths) {
|
|
1912
|
-
const id = parseChatGPTProjectId(projectId);
|
|
1913
|
-
const fs = await import('node:fs');
|
|
1914
|
-
const path = await import('node:path');
|
|
1915
|
-
|
|
1916
|
-
const prepared = await prepareChatGPTFilePaths(filePaths);
|
|
1917
|
-
if (!prepared.ok) return { ...prepared, inputError: true };
|
|
1918
|
-
const absPaths = prepared.paths;
|
|
1919
|
-
|
|
1920
|
-
// Navigate to project and open knowledge dialog
|
|
1921
|
-
await navigateToProject(page, id);
|
|
1922
|
-
await ensureChatGPTLogin(page, 'ChatGPT project file upload requires a logged-in ChatGPT session.');
|
|
1923
|
-
|
|
1924
|
-
const dialogOpened = await openProjectKnowledgeDialog(page);
|
|
1925
|
-
if (!dialogOpened) {
|
|
1926
|
-
return { ok: false, reason: 'could not find or click the project "Add files" button' };
|
|
1927
|
-
}
|
|
1928
|
-
|
|
1929
|
-
// Try uploading via dialog file input (multiple selector patterns)
|
|
1930
|
-
const fileNames = absPaths.map(fp => path.default.basename(fp));
|
|
1931
|
-
|
|
1932
|
-
let uploaded = false;
|
|
1933
|
-
if (page.setFileInput) {
|
|
1934
|
-
for (const selector of PROJECT_ADD_FILES_DIALOG_SELECTORS) {
|
|
1935
|
-
try {
|
|
1936
|
-
await page.setFileInput(absPaths, selector);
|
|
1937
|
-
uploaded = true;
|
|
1938
|
-
break;
|
|
1939
|
-
} catch (err) {
|
|
1940
|
-
const msg = String(err?.message || err);
|
|
1941
|
-
if (!msg.includes('Unknown action') && !msg.includes('not supported') && !msg.includes('Not allowed') && !msg.includes('No element found')) {
|
|
1942
|
-
throw err;
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
|
|
1948
|
-
if (!uploaded) {
|
|
1949
|
-
// Fallback: try all dialog file inputs via evaluate
|
|
1950
|
-
const files = absPaths.map(absPath => ({
|
|
1951
|
-
name: path.default.basename(absPath),
|
|
1952
|
-
mime: mimeFromFilePath(absPath),
|
|
1953
|
-
base64: fs.default.readFileSync(absPath).toString('base64'),
|
|
1954
|
-
}));
|
|
1955
|
-
const fallbackResult = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
922
|
+
`)),Y=typeof X==="boolean"?{ok:X}:requireObjectEvaluateResult(X,"chatgpt project knowledge dialog open");if(Y.ok){if(Y.nativeClick&&typeof Q.nativeClick==="function")try{await Q.nativeClick(Y.nativeClick.x,Y.nativeClick.y)}catch{}if(Y.nativeClick&&typeof Q.click==="function")try{await Q.click('[role="tab"][id$="-sources"]')}catch{}await Q.wait(1);try{await Q.wait({selector:'[role="dialog"], [data-project-home-sources-surface="true"] input[type="file"]',timeout:5})}catch{}return!0}return!1}export async function uploadChatGPTProjectFiles(Q,X,Y){const Z=parseChatGPTProjectId(X),$=await import("node:fs"),W=await import("node:path"),V=await prepareChatGPTFilePaths(Y);if(!V.ok)return{...V,inputError:!0};const z=V.paths;await navigateToProject(Q,Z);await ensureChatGPTLogin(Q,"ChatGPT project file upload requires a logged-in ChatGPT session.");if(!await openProjectKnowledgeDialog(Q))return{ok:!1,reason:'could not find or click the project "Add files" button'};const j=z.map((B)=>W.default.basename(B));let J=!1;if(Q.setFileInput)for(const B of d)try{await Q.setFileInput(z,B);J=!0;break}catch(H){const D=String(H?.message||H);if(!D.includes("Unknown action")&&!D.includes("not supported")&&!D.includes("Not allowed")&&!D.includes("No element found"))throw H}if(!J){const B=z.map((D)=>({name:W.default.basename(D),mime:m(D),base64:$.default.readFileSync(D).toString("base64")})),H=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
1956
923
|
(() => {
|
|
1957
|
-
const files = ${JSON.stringify(
|
|
924
|
+
const files = ${JSON.stringify(B)};
|
|
1958
925
|
|
|
1959
926
|
// Look for file input inside a dialog or the project area
|
|
1960
|
-
const selectors = ${JSON.stringify(
|
|
927
|
+
const selectors = ${JSON.stringify(d)};
|
|
1961
928
|
let input = null;
|
|
1962
929
|
for (const sel of selectors) {
|
|
1963
930
|
input = document.querySelector(sel);
|
|
@@ -2006,25 +973,9 @@ export async function uploadChatGPTProjectFiles(page, projectId, filePaths) {
|
|
|
2006
973
|
}
|
|
2007
974
|
return { ok: true };
|
|
2008
975
|
})()
|
|
2009
|
-
`)),
|
|
2010
|
-
if (fallbackResult && !fallbackResult.ok) return fallbackResult;
|
|
2011
|
-
}
|
|
2012
|
-
|
|
2013
|
-
const confirmation = await waitForChatGPTProjectUploadConfirmation(page, fileNames);
|
|
2014
|
-
if (!confirmation.ok) return confirmation;
|
|
2015
|
-
|
|
2016
|
-
return { ok: true, files: absPaths };
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
async function waitForChatGPTProjectUploadConfirmation(page, fileNames) {
|
|
2020
|
-
const expectedFileNames = fileNames.map(name => String(name || '').trim()).filter(Boolean);
|
|
2021
|
-
if (!expectedFileNames.length) return { ok: true };
|
|
2022
|
-
|
|
2023
|
-
let lastReason = 'uploaded file did not appear in project knowledge';
|
|
2024
|
-
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
2025
|
-
const result = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
976
|
+
`)),"chatgpt project file upload fallback");if(H&&!H.ok)return H}const K=await t(Q,j);if(!K.ok)return K;return{ok:!0,files:z}}async function t(Q,X){const Y=X.map(($)=>String($||"").trim()).filter(Boolean);if(!Y.length)return{ok:!0};let Z="uploaded file did not appear in project knowledge";for(let $=0;$<10;$+=1){const W=requireObjectEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
2026
977
|
(() => {
|
|
2027
|
-
const expectedFileNames = ${JSON.stringify(
|
|
978
|
+
const expectedFileNames = ${JSON.stringify(Y)};
|
|
2028
979
|
const normalize = (value) => String(value || '').replace(/\\s+/g, ' ').trim();
|
|
2029
980
|
const root = document.querySelector('[role="dialog"]')
|
|
2030
981
|
|| document.querySelector('[data-project-home-sources-surface="true"]')
|
|
@@ -2044,91 +995,7 @@ async function waitForChatGPTProjectUploadConfirmation(page, fileNames) {
|
|
|
2044
995
|
if (!missing.length) return { ok: true };
|
|
2045
996
|
return { ok: false, pending: true, reason: 'uploaded file did not appear in project knowledge: ' + missing.join(', ') };
|
|
2046
997
|
})()
|
|
2047
|
-
`)),
|
|
2048
|
-
|
|
2049
|
-
if (result.ok === true) return { ok: true };
|
|
2050
|
-
lastReason = String(result.reason || lastReason);
|
|
2051
|
-
if (!result.pending) return { ok: false, reason: lastReason };
|
|
2052
|
-
await page.wait(0.5);
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
|
-
return { ok: false, reason: lastReason };
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
|
-
/**
|
|
2059
|
-
* Validate local file paths for project file upload.
|
|
2060
|
-
* Accepts all file types with a 512 MB per-file limit (matching ChatGPT's project limit).
|
|
2061
|
-
*/
|
|
2062
|
-
export async function prepareChatGPTFilePaths(filePaths) {
|
|
2063
|
-
const fs = await import('node:fs');
|
|
2064
|
-
const path = await import('node:path');
|
|
2065
|
-
const absPaths = filePaths.map(filePath => path.default.resolve(filePath));
|
|
2066
|
-
|
|
2067
|
-
for (const absPath of absPaths) {
|
|
2068
|
-
if (!fs.default.existsSync(absPath)) {
|
|
2069
|
-
return { ok: false, reason: `File not found: ${absPath}` };
|
|
2070
|
-
}
|
|
2071
|
-
const stat = fs.default.statSync(absPath);
|
|
2072
|
-
if (!stat.isFile()) {
|
|
2073
|
-
return { ok: false, reason: `Not a file: ${absPath}` };
|
|
2074
|
-
}
|
|
2075
|
-
if (stat.size > 512 * 1024 * 1024) {
|
|
2076
|
-
return { ok: false, reason: `File too large (${(stat.size / 1024 / 1024).toFixed(1)} MB). Max: 512 MB` };
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
return { ok: true, paths: absPaths };
|
|
2081
|
-
}
|
|
2082
|
-
|
|
2083
|
-
function mimeFromFilePath(filePath) {
|
|
2084
|
-
const lower = String(filePath || '').toLowerCase();
|
|
2085
|
-
if (lower.endsWith('.pdf')) return 'application/pdf';
|
|
2086
|
-
if (lower.endsWith('.doc')) return 'application/msword';
|
|
2087
|
-
if (lower.endsWith('.docx')) return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
|
2088
|
-
if (lower.endsWith('.xls')) return 'application/vnd.ms-excel';
|
|
2089
|
-
if (lower.endsWith('.xlsx')) return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
|
2090
|
-
if (lower.endsWith('.ppt')) return 'application/vnd.ms-powerpoint';
|
|
2091
|
-
if (lower.endsWith('.pptx')) return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
|
|
2092
|
-
if (lower.endsWith('.csv')) return 'text/csv';
|
|
2093
|
-
if (lower.endsWith('.txt')) return 'text/plain';
|
|
2094
|
-
if (lower.endsWith('.json')) return 'application/json';
|
|
2095
|
-
if (lower.endsWith('.xml')) return 'application/xml';
|
|
2096
|
-
if (lower.endsWith('.html') || lower.endsWith('.htm')) return 'text/html';
|
|
2097
|
-
if (lower.endsWith('.md')) return 'text/markdown';
|
|
2098
|
-
if (lower.endsWith('.py')) return 'text/x-python';
|
|
2099
|
-
if (lower.endsWith('.js')) return 'text/javascript';
|
|
2100
|
-
if (lower.endsWith('.ts')) return 'application/typescript';
|
|
2101
|
-
if (lower.endsWith('.jsx')) return 'text/jsx';
|
|
2102
|
-
if (lower.endsWith('.tsx')) return 'text/tsx';
|
|
2103
|
-
if (lower.endsWith('.png')) return 'image/png';
|
|
2104
|
-
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg';
|
|
2105
|
-
if (lower.endsWith('.gif')) return 'image/gif';
|
|
2106
|
-
if (lower.endsWith('.webp')) return 'image/webp';
|
|
2107
|
-
if (lower.endsWith('.svg')) return 'image/svg+xml';
|
|
2108
|
-
return 'application/octet-stream';
|
|
2109
|
-
}
|
|
2110
|
-
|
|
2111
|
-
export const __test__ = {
|
|
2112
|
-
COMPOSER_SELECTORS,
|
|
2113
|
-
SEND_BUTTON_SELECTOR,
|
|
2114
|
-
SEND_BUTTON_FALLBACK_SELECTORS,
|
|
2115
|
-
SEND_BUTTON_LABELS,
|
|
2116
|
-
CLOSE_SIDEBAR_LABELS,
|
|
2117
|
-
buildComposerLocatorScript,
|
|
2118
|
-
isSameChatGPTConversation,
|
|
2119
|
-
parseChatGPTConversationId,
|
|
2120
|
-
parseChatGPTProjectId,
|
|
2121
|
-
imageMimeFromPath,
|
|
2122
|
-
mimeFromFilePath,
|
|
2123
|
-
PROJECT_LINK_SELECTOR,
|
|
2124
|
-
};
|
|
2125
|
-
|
|
2126
|
-
/**
|
|
2127
|
-
* Export images by URL: fetch from ChatGPT backend API and convert to base64 data URLs.
|
|
2128
|
-
*/
|
|
2129
|
-
export async function getChatGPTImageAssets(page, urls) {
|
|
2130
|
-
const urlsJson = JSON.stringify(urls);
|
|
2131
|
-
return requireArrayEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
998
|
+
`)),"chatgpt project upload confirmation");if(W.ok===!0)return{ok:!0};Z=String(W.reason||Z);if(!W.pending)return{ok:!1,reason:Z};await Q.wait(0.5)}return{ok:!1,reason:Z}}export async function prepareChatGPTFilePaths(Q){const X=await import("node:fs"),Y=await import("node:path"),Z=Q.map(($)=>Y.default.resolve($));for(const $ of Z){if(!X.default.existsSync($))return{ok:!1,reason:`File not found: ${$}`};const W=X.default.statSync($);if(!W.isFile())return{ok:!1,reason:`Not a file: ${$}`};if(W.size>536870912)return{ok:!1,reason:`File too large (${(W.size/1024/1024).toFixed(1)} MB). Max: 512 MB`}}return{ok:!0,paths:Z}}function m(Q){const X=String(Q||"").toLowerCase();if(X.endsWith(".pdf"))return"application/pdf";if(X.endsWith(".doc"))return"application/msword";if(X.endsWith(".docx"))return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";if(X.endsWith(".xls"))return"application/vnd.ms-excel";if(X.endsWith(".xlsx"))return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";if(X.endsWith(".ppt"))return"application/vnd.ms-powerpoint";if(X.endsWith(".pptx"))return"application/vnd.openxmlformats-officedocument.presentationml.presentation";if(X.endsWith(".csv"))return"text/csv";if(X.endsWith(".txt"))return"text/plain";if(X.endsWith(".json"))return"application/json";if(X.endsWith(".xml"))return"application/xml";if(X.endsWith(".html")||X.endsWith(".htm"))return"text/html";if(X.endsWith(".md"))return"text/markdown";if(X.endsWith(".py"))return"text/x-python";if(X.endsWith(".js"))return"text/javascript";if(X.endsWith(".ts"))return"application/typescript";if(X.endsWith(".jsx"))return"text/jsx";if(X.endsWith(".tsx"))return"text/tsx";if(X.endsWith(".png"))return"image/png";if(X.endsWith(".jpg")||X.endsWith(".jpeg"))return"image/jpeg";if(X.endsWith(".gif"))return"image/gif";if(X.endsWith(".webp"))return"image/webp";if(X.endsWith(".svg"))return"image/svg+xml";return"application/octet-stream"}export const __test__={COMPOSER_SELECTORS:x,SEND_BUTTON_SELECTOR:U,SEND_BUTTON_FALLBACK_SELECTORS:L,SEND_BUTTON_LABELS:y,CLOSE_SIDEBAR_LABELS:A,buildComposerLocatorScript:v,isSameChatGPTConversation:N,parseChatGPTConversationId,parseChatGPTProjectId,imageMimeFromPath:P,mimeFromFilePath:m,PROJECT_LINK_SELECTOR:c};export async function getChatGPTImageAssets(Q,X){const Y=JSON.stringify(X);return requireArrayEvaluateResult(unwrapEvaluateResult(await Q.evaluate(`
|
|
2132
999
|
(async (targetUrls) => {
|
|
2133
1000
|
const blobToDataUrl = (blob) => new Promise((resolve, reject) => {
|
|
2134
1001
|
const reader = new FileReader();
|
|
@@ -2221,6 +1088,5 @@ export async function getChatGPTImageAssets(page, urls) {
|
|
|
2221
1088
|
}
|
|
2222
1089
|
|
|
2223
1090
|
return results;
|
|
2224
|
-
})(${
|
|
2225
|
-
`)),
|
|
2226
|
-
}
|
|
1091
|
+
})(${Y})
|
|
1092
|
+
`)),"chatgpt image asset export")}
|