publishport-opencli 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli-manifest.json +35 -0
- package/clis/12306/me.js +2 -2
- package/clis/12306/orders.js +3 -3
- package/clis/12306/passengers.js +3 -3
- package/clis/12306/price.js +1 -1
- package/clis/12306/stations.js +1 -1
- package/clis/12306/train.js +1 -1
- package/clis/12306/trains.js +1 -1
- package/clis/12306/utils.js +1 -1
- package/clis/1688/download.js +1 -1
- package/clis/1688/item.js +4 -4
- package/clis/1688/search.js +4 -4
- package/clis/1688/store.js +4 -4
- package/clis/1point3acres/forum.js +1 -1
- package/clis/1point3acres/forums.js +1 -1
- package/clis/1point3acres/notifications.js +1 -1
- package/clis/1point3acres/search.js +1 -1
- package/clis/1point3acres/thread.js +2 -2
- package/clis/1point3acres/user.js +1 -1
- package/clis/1point3acres/utils.js +2 -2
- package/clis/36kr/article.js +2 -2
- package/clis/36kr/hot.js +2 -2
- package/clis/36kr/news.js +1 -1
- package/clis/36kr/search.js +2 -2
- package/clis/51job/company.js +2 -2
- package/clis/51job/detail.js +2 -2
- package/clis/51job/hot.js +1 -1
- package/clis/51job/search.js +1 -1
- package/clis/51job/utils.js +7 -7
- package/clis/_atlassian/shared.js +9 -9
- package/clis/_shared/article/auth.js +4 -4
- package/clis/_shared/article/douban-md2draft.js +4 -4
- package/clis/_shared/article/format.js +1 -1
- package/clis/_shared/article/images.js +7 -7
- package/clis/_shared/article/login.js +1 -1
- package/clis/_shared/article/publish.js +11 -11
- package/clis/_shared/common.js +1 -1
- package/clis/_shared/content-guard.js +1 -1
- package/clis/_shared/desktop-commands.js +1 -1
- package/clis/_shared/file-inject.js +12 -12
- package/clis/_shared/self-hosted-sites.js +2 -2
- package/clis/_shared/site-auth.js +1 -1
- package/clis/_shared/token-auth.js +2 -2
- package/clis/_shared/video-publish.js +9 -9
- package/clis/amazon/offer.js +3 -3
- package/clis/amazon/product.js +5 -5
- package/clis/amazon/shared.js +6 -6
- package/clis/antigravity/_actions.js +13 -13
- package/clis/antigravity/audit-extras.js +10 -10
- package/clis/antigravity/delete.js +1 -1
- package/clis/antigravity/model.js +6 -6
- package/clis/antigravity/new.js +2 -2
- package/clis/antigravity/read.js +2 -2
- package/clis/antigravity/rename.js +1 -1
- package/clis/antigravity/send.js +3 -3
- package/clis/antigravity/serve.js +17 -17
- package/clis/antigravity/storage.js +6 -6
- package/clis/antigravity/watch.js +2 -2
- package/clis/apple-podcasts/episodes.js +1 -1
- package/clis/apple-podcasts/top.js +1 -1
- package/clis/apple-podcasts/utils.js +1 -1
- package/clis/archive/item.js +1 -1
- package/clis/archive/search.js +1 -1
- package/clis/archive/snapshots.js +1 -1
- package/clis/archive/wayback.js +1 -1
- package/clis/arxiv/author.js +1 -1
- package/clis/arxiv/utils.js +1 -1
- package/clis/autohome/brand.js +1 -1
- package/clis/autohome/score.js +1 -1
- package/clis/autohome/utils.js +1 -1
- package/clis/baijiahao/article.js +1 -1
- package/clis/baijiahao/lists.js +1 -1
- package/clis/baijiahao/login.js +1 -1
- package/clis/baijiahao/publish.js +9 -9
- package/clis/baijiahao/stats.js +1 -1
- package/clis/baijiahao/whoami.js +1 -1
- package/clis/band/bands.js +2 -2
- package/clis/band/mentions.js +2 -2
- package/clis/band/post.js +4 -4
- package/clis/band/posts.js +3 -3
- package/clis/barchart/flow.js +3 -3
- package/clis/barchart/greeks.js +2 -2
- package/clis/barchart/quote.js +3 -3
- package/clis/bbc/news.js +1 -1
- package/clis/bbc/topic.js +1 -1
- package/clis/bbc/utils.js +1 -1
- package/clis/bilibili/article.js +1 -1
- package/clis/bilibili/categories.js +1 -1
- package/clis/bilibili/coin.js +1 -1
- package/clis/bilibili/comment-del.js +1 -1
- package/clis/bilibili/comment-like.js +1 -1
- package/clis/bilibili/comment.js +1 -1
- package/clis/bilibili/comments.js +1 -1
- package/clis/bilibili/dm-list.js +1 -1
- package/clis/bilibili/dm-read.js +1 -1
- package/clis/bilibili/dm-send.js +1 -1
- package/clis/bilibili/download.js +2 -2
- package/clis/bilibili/drafts.js +1 -1
- package/clis/bilibili/dynamic-post.js +3 -3
- package/clis/bilibili/favorite-add.js +1 -1
- package/clis/bilibili/favorite.js +1 -1
- package/clis/bilibili/feed.js +2 -2
- package/clis/bilibili/follow.js +1 -1
- package/clis/bilibili/following.js +1 -1
- package/clis/bilibili/like.js +1 -1
- package/clis/bilibili/partitions.js +1 -1
- package/clis/bilibili/stats.js +1 -1
- package/clis/bilibili/subtitle.js +3 -3
- package/clis/bilibili/summary.js +1 -1
- package/clis/bilibili/topics.js +1 -1
- package/clis/bilibili/unfollow.js +1 -1
- package/clis/bilibili/upload.js +1 -1
- package/clis/bilibili/utils.js +10 -10
- package/clis/bilibili/video-drafts.js +1 -1
- package/clis/bilibili/video.js +1 -1
- package/clis/bloomberg/businessweek.js +4 -4
- package/clis/bloomberg/news.js +2 -2
- package/clis/bloomberg/utils.js +13 -13
- package/clis/bluesky/post.js +1 -1
- package/clis/bluesky/shared.js +11 -11
- package/clis/bluesky/whoami.js +1 -1
- package/clis/booking/search.js +2 -2
- package/clis/boss/accept.js +1 -1
- package/clis/boss/applied.js +1 -1
- package/clis/boss/auth.js +1 -1
- package/clis/boss/batchgreet.js +1 -1
- package/clis/boss/bossinfo.js +1 -1
- package/clis/boss/chatlist.js +1 -1
- package/clis/boss/chatmsg.js +1 -1
- package/clis/boss/cities.js +1 -1
- package/clis/boss/detail.js +1 -1
- package/clis/boss/exchange.js +1 -1
- package/clis/boss/greet.js +1 -1
- package/clis/boss/interviews.js +1 -1
- package/clis/boss/invite.js +1 -1
- package/clis/boss/joblist.js +1 -1
- package/clis/boss/mark.js +1 -1
- package/clis/boss/me.js +2 -2
- package/clis/boss/recommend.js +1 -1
- package/clis/boss/resumedelete.js +1 -1
- package/clis/boss/resumelist.js +1 -1
- package/clis/boss/resumeupload.js +11 -11
- package/clis/boss/search.js +1 -1
- package/clis/boss/send.js +1 -1
- package/clis/boss/sendresume.js +1 -1
- package/clis/boss/stats.js +1 -1
- package/clis/boss/unread.js +1 -1
- package/clis/boss/utils.js +13 -13
- package/clis/chaoxing/assignments.js +1 -1
- package/clis/chaoxing/exams.js +1 -1
- package/clis/chaoxing/utils.js +9 -9
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/auth.js +2 -2
- package/clis/chatgpt/detail.js +1 -1
- package/clis/chatgpt/image.js +1 -1
- package/clis/chatgpt/read.js +1 -1
- package/clis/chatgpt/send.js +1 -1
- package/clis/chatgpt/utils.js +59 -59
- package/clis/chatgpt-app/ask.js +1 -1
- package/clis/chatgpt-app/send.js +1 -1
- package/clis/chatwise/model.js +6 -6
- package/clis/chess/analyze.js +1 -1
- package/clis/chess/game.js +1 -1
- package/clis/chess/games.js +1 -1
- package/clis/chess/stats.js +1 -1
- package/clis/chess/utils.js +1 -1
- package/clis/claude/ask.js +2 -2
- package/clis/claude/detail.js +1 -1
- package/clis/claude/new.js +1 -1
- package/clis/claude/read.js +1 -1
- package/clis/claude/send.js +1 -1
- package/clis/claude/utils.js +23 -23
- package/clis/cnblogs/article.js +1 -1
- package/clis/cnblogs/login.js +1 -1
- package/clis/cnblogs/stats.js +7 -7
- package/clis/cnblogs/whoami.js +1 -1
- package/clis/codex/_actions.js +3 -3
- package/clis/codex/archive.js +1 -1
- package/clis/codex/ask.js +6 -6
- package/clis/codex/model.js +8 -8
- package/clis/codex/pin.js +1 -1
- package/clis/codex/rename.js +4 -4
- package/clis/codex/send.js +3 -3
- package/clis/codex/sidebar.js +1 -1
- package/clis/coingecko/categories.js +1 -1
- package/clis/coingecko/coin.js +1 -1
- package/clis/coingecko/derivatives.js +1 -1
- package/clis/coingecko/exchanges.js +1 -1
- package/clis/coingecko/global.js +1 -1
- package/clis/coingecko/trending.js +1 -1
- package/clis/confluence/search.js +1 -1
- package/clis/coupang/product.js +3 -3
- package/clis/coupang/utils.js +1 -1
- package/clis/crates/crate.js +1 -1
- package/clis/crates/search.js +1 -1
- package/clis/crates/utils.js +1 -1
- package/clis/csdn/article.js +13 -13
- package/clis/csdn/columns.js +1 -1
- package/clis/csdn/login.js +1 -1
- package/clis/csdn/stats.js +4 -4
- package/clis/csdn/whoami.js +1 -1
- package/clis/cto51/article.js +1 -1
- package/clis/cto51/whoami.js +1 -1
- package/clis/ctrip/flight.js +2 -2
- package/clis/ctrip/hotel-search.js +3 -3
- package/clis/ctrip/hotel-suggest.js +1 -1
- package/clis/ctrip/search.js +1 -1
- package/clis/ctrip/utils.js +6 -6
- package/clis/cursor/ask.js +5 -5
- package/clis/cursor/composer.js +2 -2
- package/clis/cursor/model.js +4 -4
- package/clis/cursor/send.js +2 -2
- package/clis/dblp/author.js +1 -1
- package/clis/dblp/paper.js +1 -1
- package/clis/dblp/search.js +1 -1
- package/clis/dblp/utils.js +1 -1
- package/clis/dblp/venue.js +1 -1
- package/clis/deepseek/ask.js +1 -1
- package/clis/deepseek/auth.js +2 -2
- package/clis/deepseek/detail.js +1 -1
- package/clis/deepseek/new.js +1 -1
- package/clis/deepseek/read.js +1 -1
- package/clis/deepseek/send.js +7 -7
- package/clis/deepseek/utils.js +25 -25
- package/clis/defillama/protocol.js +1 -1
- package/clis/defillama/protocols.js +1 -1
- package/clis/defillama/utils.js +1 -1
- package/clis/devto/auth.js +2 -2
- package/clis/devto/latest.js +1 -1
- package/clis/devto/publish.js +5 -5
- package/clis/devto/read.js +2 -2
- package/clis/devto/stats.js +3 -3
- package/clis/dianping/auth.js +2 -2
- package/clis/dianping/cityResolver.js +2 -2
- package/clis/dianping/search.js +1 -1
- package/clis/dianping/shop.js +1 -1
- package/clis/dianping/utils.js +1 -1
- package/clis/discord-app/delete.js +3 -3
- package/clis/discord-app/read.js +1 -1
- package/clis/discord-app/thread-read.js +1 -1
- package/clis/discord-web/auth.js +2 -2
- package/clis/discord-web/send.js +5 -5
- package/clis/dockerhub/image.js +1 -1
- package/clis/dockerhub/search.js +1 -1
- package/clis/dockerhub/utils.js +1 -1
- package/clis/dongchedi/koubei.js +1 -1
- package/clis/dongchedi/models.js +1 -1
- package/clis/dongchedi/score.js +1 -1
- package/clis/dongchedi/search.js +1 -1
- package/clis/dongchedi/series.js +1 -1
- package/clis/dongchedi/specs.js +1 -1
- package/clis/dongchedi/utils.js +1 -1
- package/clis/douban/article.js +3 -3
- package/clis/douban/auth.js +2 -2
- package/clis/douban/download.js +1 -1
- package/clis/douban/utils.js +23 -23
- package/clis/doubao/auth.js +3 -3
- package/clis/doubao/utils.js +39 -39
- package/clis/doubao-app/ask.js +1 -1
- package/clis/doubao-app/utils.js +4 -4
- package/clis/douyin/_shared/browser-fetch.js +7 -7
- package/clis/douyin/_shared/draft-cache.js +1 -1
- package/clis/douyin/_shared/imagex-upload.js +1 -1
- package/clis/douyin/_shared/sts2.js +1 -1
- package/clis/douyin/_shared/text-extra.js +1 -1
- package/clis/douyin/_shared/tos-upload.js +4 -4
- package/clis/douyin/_shared/transcode.js +1 -1
- package/clis/douyin/_shared/vod-upload.js +4 -4
- package/clis/douyin/draft.js +18 -18
- package/clis/douyin/drafts.js +1 -1
- package/clis/douyin/publish-image.js +12 -12
- package/clis/douyin/publish.js +9 -9
- package/clis/douyin/search.js +3 -3
- package/clis/douyin/videos.js +1 -1
- package/clis/eastmoney/_secid.js +1 -1
- package/clis/eastmoney/announcement.js +1 -1
- package/clis/eastmoney/article.js +1 -1
- package/clis/eastmoney/convertible.js +1 -1
- package/clis/eastmoney/etf.js +1 -1
- package/clis/eastmoney/holders.js +1 -1
- package/clis/eastmoney/index-board.js +1 -1
- package/clis/eastmoney/kline.js +1 -1
- package/clis/eastmoney/kuaixun.js +1 -1
- package/clis/eastmoney/longhu.js +1 -1
- package/clis/eastmoney/money-flow.js +1 -1
- package/clis/eastmoney/northbound.js +1 -1
- package/clis/eastmoney/quote.js +1 -1
- package/clis/eastmoney/rank.js +1 -1
- package/clis/eastmoney/sectors.js +1 -1
- package/clis/endoflife/product.js +1 -1
- package/clis/endoflife/utils.js +1 -1
- package/clis/facebook/comment.js +8 -8
- package/clis/facebook/feed.js +4 -4
- package/clis/facebook/like.js +5 -5
- package/clis/facebook/notifications.js +3 -3
- package/clis/facebook/post.js +11 -11
- package/clis/facebook/search.js +3 -3
- package/clis/flathub/app.js +1 -1
- package/clis/flathub/search.js +1 -1
- package/clis/flathub/utils.js +1 -1
- package/clis/flomo/memos.js +1 -1
- package/clis/gemini/deep-research-result.js +4 -4
- package/clis/gemini/deep-research.js +1 -1
- package/clis/gemini/detail.js +1 -1
- package/clis/gemini/history.js +1 -1
- package/clis/gemini/image.js +2 -2
- package/clis/gemini/status.js +1 -1
- package/clis/gemini/utils.js +43 -43
- package/clis/geogebra/hexagon.js +1 -1
- package/clis/geogebra/info.js +3 -3
- package/clis/geogebra/triangle.js +1 -1
- package/clis/geogebra/utils.js +11 -11
- package/clis/ghost/login.js +1 -1
- package/clis/ghost/shared.js +2 -2
- package/clis/gitee/auth.js +2 -2
- package/clis/github-trending/repos.js +1 -1
- package/clis/google/news.js +1 -1
- package/clis/google/search.js +2 -2
- package/clis/google/suggest.js +1 -1
- package/clis/google/trends.js +1 -1
- package/clis/google/utils.js +1 -1
- package/clis/goproxy/module.js +1 -1
- package/clis/goproxy/utils.js +1 -1
- package/clis/goproxy/versions.js +1 -1
- package/clis/gov-policy/recent.js +2 -2
- package/clis/gov-policy/search.js +2 -2
- package/clis/grok/ask.js +1 -1
- package/clis/grok/detail.js +1 -1
- package/clis/grok/image.js +8 -8
- package/clis/grok/pin.js +1 -1
- package/clis/grok/send.js +1 -1
- package/clis/grok/status.js +1 -1
- package/clis/grok/utils.js +21 -21
- package/clis/guazi/browse.js +1 -1
- package/clis/guazi/car.js +1 -1
- package/clis/guazi/utils.js +1 -1
- package/clis/hackernews/auth.js +2 -2
- package/clis/hackernews/comment.js +8 -8
- package/clis/hackernews/read.js +7 -7
- package/clis/hackernews/submit.js +7 -7
- package/clis/hashnode/auth.js +3 -3
- package/clis/hashnode/publish.js +14 -14
- package/clis/hf/auth.js +2 -2
- package/clis/hf/models.js +1 -1
- package/clis/hf/paper.js +1 -1
- package/clis/hf/spaces.js +1 -1
- package/clis/hf/top.js +1 -1
- package/clis/homebrew/cask.js +1 -1
- package/clis/homebrew/formula.js +1 -1
- package/clis/homebrew/popular.js +1 -1
- package/clis/homebrew/utils.js +1 -1
- package/clis/huodongxing/events.js +1 -1
- package/clis/hupu/detail.js +4 -4
- package/clis/hupu/hot.js +3 -3
- package/clis/hupu/reply.js +1 -1
- package/clis/hupu/search.js +1 -1
- package/clis/hupu/unlike.js +1 -1
- package/clis/hupu/utils.js +10 -10
- package/clis/imdb/person.js +2 -2
- package/clis/imdb/reviews.js +3 -3
- package/clis/imdb/search.js +2 -2
- package/clis/imdb/title.js +1 -1
- package/clis/imdb/top.js +1 -1
- package/clis/imdb/trending.js +1 -1
- package/clis/imdb/utils.js +13 -13
- package/clis/imooc/article.js +6 -6
- package/clis/imooc/login.js +1 -1
- package/clis/imooc/whoami.js +1 -1
- package/clis/indeed/job.js +2 -2
- package/clis/indeed/search.js +2 -2
- package/clis/indeed/utils.js +1 -1
- package/clis/infoq/article.js +2 -2
- package/clis/infoq/login.js +1 -1
- package/clis/infoq/whoami.js +1 -1
- package/clis/instagram/_shared/private-publish.js +4 -4
- package/clis/instagram/_shared/protocol-capture.js +9 -9
- package/clis/instagram/detail.js +3 -3
- package/clis/instagram/post.js +25 -25
- package/clis/instagram/reel.js +18 -18
- package/clis/instagram/story.js +4 -4
- package/clis/instagram/user.js +2 -2
- package/clis/jd/item.js +65 -65
- package/clis/jianshu/article.js +1 -1
- package/clis/jianshu/login.js +1 -1
- package/clis/jianshu/notebooks.js +1 -1
- package/clis/jianshu/whoami.js +1 -1
- package/clis/jianyu/search.js +6 -6
- package/clis/jianyu/shared/procurement-contract.js +1 -1
- package/clis/jike/api.js +6 -6
- package/clis/jike/auth.js +3 -3
- package/clis/jike/comment.js +1 -1
- package/clis/jike/create.js +6 -6
- package/clis/jike/feed.js +3 -3
- package/clis/jike/like.js +1 -1
- package/clis/jike/notifications.js +3 -3
- package/clis/jike/repost.js +13 -13
- package/clis/jike/search.js +3 -3
- package/clis/jimeng/auth.js +2 -2
- package/clis/jimeng/generate.js +10 -10
- package/clis/jira/shared.js +1 -1
- package/clis/juejin/article.js +4 -4
- package/clis/juejin/categories.js +1 -1
- package/clis/juejin/hot.js +1 -1
- package/clis/juejin/login.js +1 -1
- package/clis/juejin/recommend.js +1 -1
- package/clis/juejin/stats.js +3 -3
- package/clis/juejin/tags.js +1 -1
- package/clis/juejin/utils.js +1 -1
- package/clis/juejin/whoami.js +1 -1
- package/clis/ke/utils.js +4 -4
- package/clis/kimi/_utils.js +7 -7
- package/clis/kimi/audit-extras.js +14 -14
- package/clis/kimi/auth.js +3 -3
- package/clis/kimi/chat.js +15 -15
- package/clis/kimi/storage.js +5 -5
- package/clis/kimi/ui.js +13 -13
- package/clis/kimi/usage.js +3 -3
- package/clis/kuaishou/auth.js +1 -1
- package/clis/kuaishou/publish.js +6 -6
- package/clis/lesswrong/_helpers.js +5 -5
- package/clis/lesswrong/comments.js +5 -5
- package/clis/lichess/top.js +1 -1
- package/clis/lichess/user.js +1 -1
- package/clis/lichess/utils.js +1 -1
- package/clis/linkedin/comment.js +1 -1
- package/clis/linkedin/connect.js +11 -11
- package/clis/linkedin/create.js +5 -5
- package/clis/linkedin/follow.js +1 -1
- package/clis/linkedin/inbox.js +1 -1
- package/clis/linkedin/job-detail.js +3 -3
- package/clis/linkedin/like.js +1 -1
- package/clis/linkedin/notifications.js +1 -1
- package/clis/linkedin/people-search.js +1 -1
- package/clis/linkedin/post-comments.js +1 -1
- package/clis/linkedin/post-detail.js +1 -1
- package/clis/linkedin/profile-analytics.js +1 -1
- package/clis/linkedin/profile-api.js +13 -13
- package/clis/linkedin/profile-experience.js +1 -1
- package/clis/linkedin/profile-projects.js +1 -1
- package/clis/linkedin/profile-read.js +3 -3
- package/clis/linkedin/reply.js +1 -1
- package/clis/linkedin/repost.js +1 -1
- package/clis/linkedin/safe-send.js +8 -8
- package/clis/linkedin/salesnav-inbox.js +5 -5
- package/clis/linkedin/salesnav-message.js +3 -3
- package/clis/linkedin/salesnav-search.js +4 -4
- package/clis/linkedin/salesnav-thread.js +1 -1
- package/clis/linkedin/search-api.js +3 -3
- package/clis/linkedin/search.js +8 -8
- package/clis/linkedin/social-api.js +31 -31
- package/clis/linkedin/timeline.js +3 -3
- package/clis/linkedin-learning/search.js +2 -2
- package/clis/linkedin-learning/trending.js +2 -2
- package/clis/linux-do/feed.js +4 -4
- package/clis/linux-do/topic-content.js +8 -8
- package/clis/lobsters/domain.js +1 -1
- package/clis/lobsters/read.js +7 -7
- package/clis/maimai/auth.js +2 -2
- package/clis/maimai/search-talents.js +4 -4
- package/clis/manus/_utils.js +1 -1
- package/clis/mastodon/login.js +1 -1
- package/clis/mastodon/post.js +1 -1
- package/clis/mastodon/shared.js +12 -12
- package/clis/mastodon/whoami.js +1 -1
- package/clis/maven/artifact.js +1 -1
- package/clis/maven/search.js +1 -1
- package/clis/maven/utils.js +1 -1
- package/clis/mdn/search.js +1 -1
- package/clis/medium/article.js +5 -5
- package/clis/medium/login.js +1 -1
- package/clis/medium/stats.js +3 -3
- package/clis/medium/tag.js +1 -1
- package/clis/medium/whoami.js +1 -1
- package/clis/mubu/notes.js +1 -1
- package/clis/mubu/utils.js +15 -15
- package/clis/note/auth.js +2 -2
- package/clis/note/note-utils.js +2 -2
- package/clis/note/publish.js +8 -8
- package/clis/notebooklm/add-source.js +8 -8
- package/clis/notebooklm/create.js +1 -1
- package/clis/notebooklm/generate-slides.js +1 -1
- package/clis/notebooklm/notes-get.js +1 -1
- package/clis/notebooklm/rpc.js +8 -8
- package/clis/notebooklm/source-fulltext.js +1 -1
- package/clis/notebooklm/utils.js +10 -10
- package/clis/nowcoder/auth.js +2 -2
- package/clis/nowcoder/comment.js +1 -1
- package/clis/nowcoder/comments.js +1 -1
- package/clis/nowcoder/dm-list.js +1 -1
- package/clis/nowcoder/dm-read.js +1 -1
- package/clis/nowcoder/dm-send.js +1 -1
- package/clis/nowcoder/drafts.js +1 -1
- package/clis/nowcoder/inbox.js +1 -1
- package/clis/nowcoder/like.js +1 -1
- package/clis/nowcoder/my.js +1 -1
- package/clis/nowcoder/post.js +1 -1
- package/clis/nowcoder/utils.js +13 -13
- package/clis/npm/downloads.js +1 -1
- package/clis/npm/package.js +1 -1
- package/clis/npm/search.js +1 -1
- package/clis/npm/utils.js +1 -1
- package/clis/nuget/package.js +1 -1
- package/clis/nuget/search.js +1 -1
- package/clis/nuget/utils.js +1 -1
- package/clis/nvd/cve.js +1 -1
- package/clis/oeis/search.js +1 -1
- package/clis/oeis/sequence.js +1 -1
- package/clis/oeis/utils.js +1 -1
- package/clis/ones/common.js +6 -6
- package/clis/ones/enrich-tasks.js +1 -1
- package/clis/ones/my-tasks.js +1 -1
- package/clis/ones/resolve-labels.js +1 -1
- package/clis/ones/task-helpers.js +1 -1
- package/clis/ones/task.js +1 -1
- package/clis/ones/worklog.js +7 -7
- package/clis/openalex/search.js +1 -1
- package/clis/openalex/utils.js +1 -1
- package/clis/openalex/work.js +1 -1
- package/clis/openfda/drug-label.js +1 -1
- package/clis/openfda/food-recall.js +1 -1
- package/clis/openfda/utils.js +1 -1
- package/clis/openreview/author.js +1 -1
- package/clis/openreview/paper.js +1 -1
- package/clis/openreview/reviews.js +3 -3
- package/clis/openreview/search.js +1 -1
- package/clis/openreview/utils.js +1 -1
- package/clis/openreview/venue.js +1 -1
- package/clis/oschina/article.js +1 -1
- package/clis/oschina/catalogs.js +1 -1
- package/clis/oschina/login.js +1 -1
- package/clis/oschina/stats.js +6 -6
- package/clis/oschina/whoami.js +1 -1
- package/clis/osv/query.js +1 -1
- package/clis/osv/utils.js +1 -1
- package/clis/osv/vulnerability.js +1 -1
- package/clis/packagist/package.js +1 -1
- package/clis/packagist/search.js +1 -1
- package/clis/packagist/utils.js +1 -1
- package/clis/pinterest/api.js +1 -1
- package/clis/pinterest/auth.js +1 -1
- package/clis/pinterest/boards.js +1 -1
- package/clis/pinterest/client.js +6 -6
- package/clis/pinterest/publish.js +5 -5
- package/clis/pixiv/auth.js +2 -2
- package/clis/pixiv/download.js +1 -1
- package/clis/pixiv/illusts.js +1 -1
- package/clis/pixiv/search.js +1 -1
- package/clis/pixiv/utils.js +3 -3
- package/clis/powerchina/auth.js +2 -2
- package/clis/powerchina/search.js +1 -1
- package/clis/producthunt/browse.js +2 -2
- package/clis/producthunt/hot.js +2 -2
- package/clis/producthunt/posts.js +1 -1
- package/clis/producthunt/today.js +1 -1
- package/clis/producthunt/utils.js +1 -1
- package/clis/pypi/downloads.js +1 -1
- package/clis/pypi/package.js +1 -1
- package/clis/pypi/utils.js +1 -1
- package/clis/qiita/auth.js +1 -1
- package/clis/qiita/gql.js +6 -6
- package/clis/qiita/publish.js +4 -4
- package/clis/qiita/stats.js +4 -4
- package/clis/qoder/_utils.js +16 -16
- package/clis/qoder/composer.js +1 -1
- package/clis/qoder/quest.js +1 -1
- package/clis/qoder/ui.js +14 -14
- package/clis/quark/auth.js +2 -2
- package/clis/quark/utils.js +2 -2
- package/clis/quora/answer-comments.js +3 -3
- package/clis/quora/create-answer.js +4 -4
- package/clis/quora/create-question.js +3 -3
- package/clis/quora/shared.js +17 -17
- package/clis/quora/whoami.js +1 -1
- package/clis/qwen/ask.js +1 -1
- package/clis/qwen/auth.js +3 -3
- package/clis/qwen/detail.js +1 -1
- package/clis/qwen/image.js +5 -5
- package/clis/qwen/status.js +1 -1
- package/clis/qwen/utils.js +16 -16
- package/clis/reddit/home.js +3 -3
- package/clis/reddit/read.js +10 -10
- package/clis/reddit/reply.js +4 -4
- package/clis/reddit/submit.js +11 -11
- package/clis/reddit/subreddit-info.js +3 -3
- package/clis/reddit/subscribed.js +4 -4
- package/clis/reddit/whoami.js +2 -2
- package/clis/rednote/comments.js +1 -1
- package/clis/rednote/download.js +1 -1
- package/clis/rednote/feed.js +1 -1
- package/clis/rednote/note.js +1 -1
- package/clis/rednote/notifications.js +2 -2
- package/clis/rednote/search.js +2 -2
- package/clis/rest-countries/country.js +1 -1
- package/clis/rest-countries/region.js +1 -1
- package/clis/rest-countries/utils.js +1 -1
- package/clis/reuters/article-detail.js +1 -1
- package/clis/reuters/auth.js +3 -3
- package/clis/reuters/search.js +1 -1
- package/clis/reuters/utils.js +4 -4
- package/clis/rfc/rfc.js +1 -1
- package/clis/rfc/utils.js +1 -1
- package/clis/rubygems/gem.js +1 -1
- package/clis/rubygems/search.js +1 -1
- package/clis/rubygems/utils.js +1 -1
- package/clis/segmentfault/article.js +3 -3
- package/clis/segmentfault/channels.js +1 -1
- package/clis/segmentfault/login.js +1 -1
- package/clis/segmentfault/stats.js +4 -4
- package/clis/segmentfault/tags.js +1 -1
- package/clis/segmentfault/whoami.js +1 -1
- package/clis/semanticscholar/citations.js +1 -1
- package/clis/semanticscholar/paper.js +1 -1
- package/clis/semanticscholar/recommendations.js +1 -1
- package/clis/semanticscholar/search.js +1 -1
- package/clis/semanticscholar/utils.js +1 -1
- package/clis/sinafinance/news.js +1 -1
- package/clis/sinafinance/stock-rank.js +1 -1
- package/clis/sinafinance/stock.js +1 -1
- package/clis/slock/attachment-download.js +1 -1
- package/clis/slock/attachment-upload.js +7 -7
- package/clis/slock/attachment-url.js +1 -1
- package/clis/slock/auth-verify.js +1 -1
- package/clis/slock/bookmark-add.js +1 -1
- package/clis/slock/bookmark-remove.js +1 -1
- package/clis/slock/channel-action.js +1 -1
- package/clis/slock/channel-create.js +1 -1
- package/clis/slock/channel-files.js +1 -1
- package/clis/slock/channel-list.js +1 -1
- package/clis/slock/channel-mark.js +1 -1
- package/clis/slock/channel-members.js +1 -1
- package/clis/slock/channel-unarchive.js +1 -1
- package/clis/slock/dm-list.js +1 -1
- package/clis/slock/errors.js +1 -1
- package/clis/slock/in-page.js +28 -28
- package/clis/slock/inbox-done.js +5 -5
- package/clis/slock/inbox.js +1 -1
- package/clis/slock/message-read.js +22 -22
- package/clis/slock/message-search.js +10 -10
- package/clis/slock/message-send.js +25 -25
- package/clis/slock/reaction-add.js +1 -1
- package/clis/slock/reaction-remove.js +1 -1
- package/clis/slock/resolve.js +1 -1
- package/clis/slock/server-list.js +2 -2
- package/clis/slock/task-claim.js +4 -4
- package/clis/slock/task-convert.js +13 -13
- package/clis/slock/task-create.js +1 -1
- package/clis/slock/task-delete.js +5 -5
- package/clis/slock/task-get.js +5 -5
- package/clis/slock/task-list-server.js +4 -4
- package/clis/slock/task-list.js +5 -5
- package/clis/slock/task-status.js +3 -3
- package/clis/slock/task-unclaim.js +3 -3
- package/clis/slock/thread-follow.js +1 -1
- package/clis/slock/thread-state.js +1 -1
- package/clis/slock/unread-summary.js +5 -5
- package/clis/slock/whoami.js +1 -1
- package/clis/smzdm/search.js +3 -3
- package/clis/sohu/article.js +1 -1
- package/clis/sohu/attributes.js +1 -1
- package/clis/sohu/categories.js +1 -1
- package/clis/sohu/channels.js +1 -1
- package/clis/sohu/columns.js +1 -1
- package/clis/sohu/login.js +1 -1
- package/clis/sohu/stats.js +3 -3
- package/clis/sohu/topics.js +1 -1
- package/clis/sohu/whoami.js +1 -1
- package/clis/spotify/spotify.js +1 -1
- package/clis/stackoverflow/read.js +6 -6
- package/clis/stackoverflow/related.js +1 -1
- package/clis/stackoverflow/tag.js +1 -1
- package/clis/stackoverflow/user.js +1 -1
- package/clis/stackoverflow/utils.js +1 -1
- package/clis/steam/app.js +1 -1
- package/clis/steam/search.js +1 -1
- package/clis/steam/utils.js +1 -1
- package/clis/substack/auth.js +2 -2
- package/clis/substack/post-utils.js +2 -2
- package/clis/substack/publish.js +5 -5
- package/clis/suno/auth.js +2 -2
- package/clis/suno/download.js +5 -5
- package/clis/suno/generate.js +3 -3
- package/clis/suno/list.js +1 -1
- package/clis/suno/status.js +1 -1
- package/clis/suno/utils.js +29 -29
- package/clis/telegram/send.js +7 -7
- package/clis/telegram/shared.js +2 -2
- package/clis/telegram/whoami.js +1 -1
- package/clis/test-utils.js +1 -1
- package/clis/threads/post.js +23 -23
- package/clis/threads/shared.js +3 -3
- package/clis/threads/whoami.js +1 -1
- package/clis/tieba/hot.js +3 -3
- package/clis/tieba/posts.js +1 -1
- package/clis/tieba/read.js +2 -2
- package/clis/tieba/search.js +3 -3
- package/clis/tieba/utils.js +1 -1
- package/clis/tiktok/comment.js +2 -2
- package/clis/tiktok/creator-videos.js +3 -3
- package/clis/tiktok/explore.js +3 -3
- package/clis/tiktok/follow.js +8 -8
- package/clis/tiktok/following.js +4 -4
- package/clis/tiktok/friends.js +7 -7
- package/clis/tiktok/live.js +3 -3
- package/clis/tiktok/notifications.js +6 -6
- package/clis/tiktok/publish.js +16 -16
- package/clis/tiktok/unfollow.js +4 -4
- package/clis/tiktok/user.js +2 -2
- package/clis/tiktok/utils.js +1 -1
- package/clis/toutiao/article.js +1 -1
- package/clis/toutiao/articles.js +2 -2
- package/clis/toutiao/auth.js +2 -2
- package/clis/toutiao/hot.js +1 -1
- package/clis/toutiao/recommend.js +1 -1
- package/clis/toutiao/utils.js +2 -2
- package/clis/trae-solo/_actions.js +4 -4
- package/clis/trae-solo/_fs.js +5 -5
- package/clis/trae-solo/_state.js +2 -2
- package/clis/trae-solo/automation.js +4 -4
- package/clis/trae-solo/mode.js +4 -4
- package/clis/trae-solo/model.js +4 -4
- package/clis/trae-solo/renderer-storage.js +4 -4
- package/clis/trae-solo/settings.js +1 -1
- package/clis/trae-solo/skill-fs.js +1 -1
- package/clis/trae-solo/skill.js +12 -12
- package/clis/trae-solo/state-fs.js +2 -2
- package/clis/trae-solo/task-fs.js +5 -5
- package/clis/trae-solo/workspaces-fs.js +1 -1
- package/clis/tumblr/auth.js +2 -2
- package/clis/tumblr/publish.js +3 -3
- package/clis/tvmaze/search.js +1 -1
- package/clis/tvmaze/show.js +1 -1
- package/clis/tvmaze/utils.js +1 -1
- package/clis/twitter/accept.js +7 -7
- package/clis/twitter/article.js +7 -7
- package/clis/twitter/bookmark-folder.js +3 -3
- package/clis/twitter/bookmark-folders.js +3 -3
- package/clis/twitter/bookmarks.js +4 -4
- package/clis/twitter/delete.js +5 -5
- package/clis/twitter/device-follow.js +3 -3
- package/clis/twitter/dm-list.js +1 -1
- package/clis/twitter/dm-read.js +1 -1
- package/clis/twitter/dm-send.js +5 -5
- package/clis/twitter/dm-shared.js +3 -3
- package/clis/twitter/download.js +6 -6
- package/clis/twitter/followers.js +5 -5
- package/clis/twitter/following.js +2 -2
- package/clis/twitter/like.js +3 -3
- package/clis/twitter/likes.js +8 -8
- package/clis/twitter/list-add-core.js +9 -9
- package/clis/twitter/list-create.js +5 -5
- package/clis/twitter/list-remove-core.js +9 -9
- package/clis/twitter/list-tweets.js +7 -7
- package/clis/twitter/lists.js +6 -6
- package/clis/twitter/notifications.js +2 -2
- package/clis/twitter/post.js +24 -24
- package/clis/twitter/profile.js +7 -7
- package/clis/twitter/quote.js +7 -7
- package/clis/twitter/reply-dm.js +7 -7
- package/clis/twitter/reply.js +12 -12
- package/clis/twitter/retweet.js +3 -3
- package/clis/twitter/scheduled-delete.js +3 -3
- package/clis/twitter/scheduled-list.js +2 -2
- package/clis/twitter/scheduled-utils.js +3 -3
- package/clis/twitter/search.js +5 -5
- package/clis/twitter/shared.js +6 -6
- package/clis/twitter/thread.js +4 -4
- package/clis/twitter/timeline.js +3 -3
- package/clis/twitter/trending.js +2 -2
- package/clis/twitter/tweets.js +11 -11
- package/clis/twitter/unlike.js +3 -3
- package/clis/twitter/unretweet.js +3 -3
- package/clis/twitter/utils.js +6 -6
- package/clis/upwork/detail.js +2 -2
- package/clis/upwork/feed.js +2 -2
- package/clis/upwork/search.js +2 -2
- package/clis/upwork/utils.js +1 -1
- package/clis/v2ex/auth.js +2 -2
- package/clis/v2ex/daily.js +3 -3
- package/clis/v2ex/me.js +2 -2
- package/clis/v2ex/notifications.js +2 -2
- package/clis/vk/post.js +1 -1
- package/clis/vk/shared.js +2 -2
- package/clis/vk/whoami.js +1 -1
- package/clis/web/read.js +8 -8
- package/clis/wechat-channels/auth.js +2 -2
- package/clis/wechat-channels/publish.js +30 -30
- package/clis/weibo/article.js +1 -1
- package/clis/weibo/auth.js +3 -3
- package/clis/weibo/comments.js +1 -1
- package/clis/weibo/delete.js +2 -2
- package/clis/weibo/feed.js +3 -3
- package/clis/weibo/hot.js +1 -1
- package/clis/weibo/publish.js +10 -10
- package/clis/weibo/search.js +2 -2
- package/clis/weibo/user-posts.js +3 -3
- package/clis/weibo/user.js +2 -2
- package/clis/weibo/utils.js +3 -3
- package/clis/weixin/article.js +1 -1
- package/clis/weixin/create-draft.js +26 -26
- package/clis/weixin/download.js +2 -2
- package/clis/weixin/login.js +1 -1
- package/clis/weixin/search.js +2 -2
- package/clis/weixin/stats.js +3 -3
- package/clis/weixin/whoami.js +1 -1
- package/clis/weread/ai-outline.js +2 -2
- package/clis/weread/book-search.js +2 -2
- package/clis/weread/book.js +2 -2
- package/clis/weread/notebooks.js +1 -1
- package/clis/weread/search.js +1 -1
- package/clis/weread/shelf.js +1 -1
- package/clis/weread/utils.js +6 -6
- package/clis/weread-official/book.js +1 -1
- package/clis/weread-official/discover.js +1 -1
- package/clis/weread-official/list-apis.js +1 -1
- package/clis/weread-official/notes.js +1 -1
- package/clis/weread-official/readdata.js +1 -1
- package/clis/weread-official/review.js +1 -1
- package/clis/weread-official/search.js +1 -1
- package/clis/weread-official/shelf.js +1 -1
- package/clis/weread-official/utils.js +1 -1
- package/clis/wikidata/entity.js +1 -1
- package/clis/wikidata/search.js +1 -1
- package/clis/wikidata/utils.js +1 -1
- package/clis/wikipedia/page.js +1 -1
- package/clis/wikipedia/trending.js +1 -1
- package/clis/wikipedia/utils.js +1 -1
- package/clis/wordpress/login.js +1 -1
- package/clis/wordpress/publish.js +1 -1
- package/clis/wordpress/shared.js +3 -3
- package/clis/wordpress/whoami.js +1 -1
- package/clis/woshipm/article.js +1 -1
- package/clis/woshipm/login.js +1 -1
- package/clis/woshipm/stats.js +4 -4
- package/clis/woshipm/whoami.js +1 -1
- package/clis/wttr/current.js +1 -1
- package/clis/wttr/forecast.js +1 -1
- package/clis/wttr/utils.js +1 -1
- package/clis/xianyu/collect.js +1 -1
- package/clis/xianyu/inbox.js +1 -1
- package/clis/xianyu/item-stats.js +2 -2
- package/clis/xianyu/location.js +1 -1
- package/clis/xianyu/manage.js +1 -1
- package/clis/xianyu/messages.js +1 -1
- package/clis/xianyu/mtop.js +5 -5
- package/clis/xianyu/order.js +1 -1
- package/clis/xianyu/promote-stats.js +2 -2
- package/clis/xianyu/publish.js +17 -17
- package/clis/xianyu/rate.js +1 -1
- package/clis/xianyu/reply.js +1 -1
- package/clis/xianyu/search.js +8 -8
- package/clis/xianyu/seller-data.js +1 -1
- package/clis/xianyu/seller-list.js +1 -1
- package/clis/xianyu/user.js +1 -1
- package/clis/xiaoe/catalog.js +2 -2
- package/clis/xiaoe/content.js +2 -2
- package/clis/xiaoe/courses.js +2 -2
- package/clis/xiaohongshu/ask.js +6 -6
- package/clis/xiaohongshu/comments.js +6 -6
- package/clis/xiaohongshu/creator-note-detail.js +7 -7
- package/clis/xiaohongshu/creator-notes-summary.js +1 -1
- package/clis/xiaohongshu/creator-notes.js +13 -13
- package/clis/xiaohongshu/creator-profile.js +2 -2
- package/clis/xiaohongshu/creator-stats.js +2 -2
- package/clis/xiaohongshu/delete-note.js +7 -7
- package/clis/xiaohongshu/download.js +4 -4
- package/clis/xiaohongshu/feed.js +2 -2
- package/clis/xiaohongshu/follow.js +3 -3
- package/clis/xiaohongshu/human.js +3 -3
- package/clis/xiaohongshu/note-helpers.js +1 -1
- package/clis/xiaohongshu/note.js +2 -2
- package/clis/xiaohongshu/notifications.js +1 -1
- package/clis/xiaohongshu/publish-video.js +8 -8
- package/clis/xiaohongshu/publish.js +59 -59
- package/clis/xiaohongshu/search.js +8 -8
- package/clis/xiaohongshu/unfollow.js +4 -4
- package/clis/xiaohongshu/user-helpers.js +1 -1
- package/clis/xiaohongshu/user.js +2 -2
- package/clis/xiaoyuzhou/auth.js +3 -3
- package/clis/xiaoyuzhou/download.js +1 -1
- package/clis/xiaoyuzhou/utils.js +1 -1
- package/clis/xueqiu/article.js +4 -4
- package/clis/xueqiu/comments.js +4 -4
- package/clis/xueqiu/danjuan-utils.js +4 -4
- package/clis/xueqiu/earnings-date.js +1 -1
- package/clis/xueqiu/events.js +3 -3
- package/clis/xueqiu/hashtags.js +3 -3
- package/clis/xueqiu/stocks.js +3 -3
- package/clis/xueqiu/users.js +3 -3
- package/clis/xueqiu/utils.js +3 -3
- package/clis/yahoo-finance/quote.js +1 -1
- package/clis/yollomi/background.js +1 -1
- package/clis/yollomi/edit.js +1 -1
- package/clis/yollomi/face-swap.js +1 -1
- package/clis/yollomi/generate.js +1 -1
- package/clis/yollomi/object-remover.js +1 -1
- package/clis/yollomi/remove-bg.js +1 -1
- package/clis/yollomi/restore.js +1 -1
- package/clis/yollomi/try-on.js +1 -1
- package/clis/yollomi/upload.js +4 -4
- package/clis/yollomi/upscale.js +1 -1
- package/clis/yollomi/utils.js +4 -4
- package/clis/yollomi/video.js +1 -1
- package/clis/youtube/channel.js +4 -4
- package/clis/youtube/feed.js +2 -2
- package/clis/youtube/like.js +5 -5
- package/clis/youtube/playlist.js +7 -7
- package/clis/youtube/publish.js +11 -11
- package/clis/youtube/search.js +3 -3
- package/clis/youtube/subscribe.js +7 -7
- package/clis/youtube/subscriptions.js +1 -1
- package/clis/youtube/transcript-group.js +2 -2
- package/clis/youtube/transcript.js +13 -13
- package/clis/youtube/unlike.js +5 -5
- package/clis/youtube/unsubscribe.js +7 -7
- package/clis/youtube/utils.js +3 -3
- package/clis/youtube/video.js +4 -4
- package/clis/youtube/watch-later.js +2 -2
- package/clis/yuanbao/ask.js +18 -18
- package/clis/yuanbao/detail.js +1 -1
- package/clis/yuanbao/read.js +1 -1
- package/clis/yuanbao/shared.js +9 -9
- package/clis/yuanbao/status.js +1 -1
- package/clis/yuque/article.js +1 -1
- package/clis/yuque/whoami.js +1 -1
- package/clis/zhihu/answer-comments.js +2 -2
- package/clis/zhihu/answer-detail.js +3 -3
- package/clis/zhihu/answer.js +1 -1
- package/clis/zhihu/article-transform.js +1 -1
- package/clis/zhihu/article.js +1 -1
- package/clis/zhihu/auth.js +2 -2
- package/clis/zhihu/collection.js +3 -3
- package/clis/zhihu/collections.js +3 -3
- package/clis/zhihu/download.js +2 -2
- package/clis/zhihu/image-profile.js +6 -6
- package/clis/zhihu/paginate.js +3 -3
- package/clis/zhihu/pin.js +4 -4
- package/clis/zhihu/question.js +3 -3
- package/clis/zhihu/recommend.js +3 -3
- package/clis/zhihu/search.js +3 -3
- package/clis/zhihu/stats.js +3 -3
- package/clis/zhihu/user-arg.js +1 -1
- package/clis/zhihu/write-shared.js +7 -7
- package/clis/zlibrary/utils.js +6 -6
- package/clis/zsxq/auth.js +3 -3
- package/clis/zsxq/search.js +1 -1
- package/clis/zsxq/topic.js +1 -1
- package/clis/zsxq/utils.js +5 -5
- package/dist/src/adapter-source.js +1 -1
- package/dist/src/browser/analyze.js +1 -1
- package/dist/src/browser/article-extract.js +2 -2
- package/dist/src/browser/ax-snapshot.js +2 -2
- package/dist/src/browser/base-page.js +25 -25
- package/dist/src/browser/bridge.js +1 -1
- package/dist/src/browser/cdp.js +1 -1
- package/dist/src/browser/daemon-client.js +1 -1
- package/dist/src/browser/daemon-lifecycle.js +7 -7
- package/dist/src/browser/dom-helpers.js +35 -35
- package/dist/src/browser/dom-snapshot.js +19 -19
- package/dist/src/browser/errors.js +3 -3
- package/dist/src/browser/extract.js +5 -5
- package/dist/src/browser/find.js +13 -13
- package/dist/src/browser/fingerprint.js +2 -2
- package/dist/src/browser/html-tree.js +6 -6
- package/dist/src/browser/managed-chrome.js +1 -1
- package/dist/src/browser/network-cache.js +1 -1
- package/dist/src/browser/network-key.js +1 -1
- package/dist/src/browser/page.js +7 -7
- package/dist/src/browser/profile.js +2 -2
- package/dist/src/browser/proxy-test.js +8 -8
- package/dist/src/browser/shape-filter.js +1 -1
- package/dist/src/browser/shape.js +1 -1
- package/dist/src/browser/stealth.js +3 -3
- package/dist/src/browser/tabs.js +2 -2
- package/dist/src/browser/target-errors.js +1 -1
- package/dist/src/browser/target-resolver.js +23 -23
- package/dist/src/browser/trace.js +2 -2
- package/dist/src/browser/utils.js +1 -1
- package/dist/src/browser/verify-fixture.js +2 -2
- package/dist/src/browser-session-lock.js +1 -1
- package/dist/src/build-manifest.js +11 -11
- package/dist/src/capabilityRouting.js +1 -1
- package/dist/src/cli-argv-preprocess.js +1 -1
- package/dist/src/cli.js +32 -32
- package/dist/src/commanderAdapter.js +3 -3
- package/dist/src/commands/auth.js +3 -3
- package/dist/src/commands/daemon.js +1 -1
- package/dist/src/completion-fast.js +1 -1
- package/dist/src/completion.js +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/convention-audit.js +2 -2
- package/dist/src/daemon-utils.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/discovery.js +2 -2
- package/dist/src/doctor.js +9 -9
- package/dist/src/download/article-download.js +15 -15
- package/dist/src/download/index.js +4 -4
- package/dist/src/download/media-download.js +1 -1
- package/dist/src/download/progress.js +3 -3
- package/dist/src/electron-apps.js +1 -1
- package/dist/src/errors.js +2 -2
- package/dist/src/execution.js +2 -2
- package/dist/src/external.js +1 -1
- package/dist/src/help.js +8 -8
- package/dist/src/hooks.js +1 -1
- package/dist/src/interceptor.js +21 -21
- package/dist/src/launcher.js +7 -7
- package/dist/src/logger.js +8 -8
- package/dist/src/main.js +7 -7
- package/dist/src/observation/artifact.js +5 -5
- package/dist/src/observation/retention.js +1 -1
- package/dist/src/output.js +2 -2
- package/dist/src/package-paths.js +1 -1
- package/dist/src/pipeline/executor.js +1 -1
- package/dist/src/pipeline/registry.js +1 -1
- package/dist/src/pipeline/steps/browser.js +1 -1
- package/dist/src/pipeline/steps/download.js +1 -1
- package/dist/src/pipeline/steps/fetch.js +6 -6
- package/dist/src/pipeline/steps/intercept.js +1 -1
- package/dist/src/pipeline/steps/tap.js +17 -17
- package/dist/src/pipeline/steps/transform.js +1 -1
- package/dist/src/pipeline/template.js +1 -1
- package/dist/src/plugin-manifest.js +1 -1
- package/dist/src/plugin-scaffold.js +19 -19
- package/dist/src/plugin.js +12 -12
- package/dist/src/rate-limit.js +1 -1
- package/dist/src/registry.js +1 -1
- package/dist/src/runtime-detect.js +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/scripts/framework.js +1 -1
- package/dist/src/scripts/interact.js +1 -1
- package/dist/src/scripts/store.js +1 -1
- package/dist/src/serialization.js +2 -2
- package/dist/src/session-lease.js +1 -1
- package/dist/src/snapshotFormatter.js +2 -2
- package/dist/src/tui.js +12 -12
- package/dist/src/user-runtime.js +1 -1
- package/dist/src/utils.d.ts +12 -0
- package/dist/src/utils.js +4 -4
- package/dist/src/validate.js +2 -2
- package/dist/src/verify.js +2 -2
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as q,Strategy as J}from"@jackwener/opencli/registry";import{ArgumentError as l,AuthRequiredError as b,CommandExecutionError as u}from"@jackwener/opencli/errors";const w="www.linkedin.com",B="https://www.linkedin.com/sales/",D="(entityUrn,objectUrn,firstName,lastName,fullName,headline,degree,inmailRestriction,memberBadges,defaultPosition)",k="https://www.linkedin.com/sales-api/salesApiCredits?q=findCreditGrant&creditGrantType=LSS_INMAIL",F="https://www.linkedin.com/sales-api/salesApiMessageActions?action=createMessage";function c(e){return String(e??"").replace(/[\u00a0\u202f]/g," ").replace(/\s+/g," ").trim()}function R(e,t,n=t){const r=c(e[t]);if(!r)throw new l(`${n} is required`);return r}function f(e){if(e&&typeof e==="object"&&"data"in e&&"session"in e)return e.data;return e}function G(e){const t=String(e||"").toLowerCase();return t==="linkedin.com"||t.endsWith(".linkedin.com")}function g(e){const t=c(e),n=t.match(/^urn:li:fs_salesProfile:\(([^,()]+),([^,()]+),([^,()]+)\)$/);if(!n)return null;if(!m(n[1],n[2],n[3]))return null;return{profileId:n[1],authType:n[2],authToken:n[3],entityUrn:t}}function m(e,t,n){return[e,t,n].every((r)=>{const i=c(r).toLowerCase();return i&&i!=="undefined"&&i!=="null"&&i!=="not_available"})}function N({profileId:e,authType:t,authToken:n}){return`https://www.linkedin.com/sales/lead/${encodeURIComponent(e)},${encodeURIComponent(t)},${encodeURIComponent(n)}`}function v(e){const t=c(e),n=g(t);if(n)return n;try{const r=new URL(t);if(r.protocol!=="https:"||r.username||r.password||r.port||!G(r.hostname))return null;const i=r.pathname.match(/^\/sales\/lead\/([^,/]+),([^,/]+),([^/]+)\/?$/i);if(i){const a=decodeURIComponent(i[1]),s=decodeURIComponent(i[2]),d=decodeURIComponent(i[3]);if(!m(a,s,d))return null;return{profileId:a,authType:s,authToken:d,entityUrn:`urn:li:fs_salesProfile:(${a},${s},${d})`}}const o=r.pathname.match(/^\/in\/([^/]+)\/?$/i);if(o)return{profileId:decodeURIComponent(o[1]),authType:"",authToken:"",entityUrn:""}}catch{return null}return null}function H(e){return encodeURIComponent(e).replace(/\(/g,"%28").replace(/\)/g,"%29")}function U(e){if(!e?.profileId||!e?.authType||!e?.authToken)return"";return`https://www.linkedin.com/sales-api/salesApiProfiles/${`(profileId:${e.profileId},authType:${e.authType},authToken:${e.authToken})`}?decoration=${H(D)}`}function z(){const e=new Uint8Array(8);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(e);else for(let t=0;t<e.length;t+=1)e[t]=Math.floor(Math.random()*256);return Array.from(e,(t)=>t.toString(16).padStart(2,"0")).join("")}function T({recipientUrn:e,subject:t,body:n,trackingId:r=z(),copyToCrm:i=!1}){const o=c(e);if(!g(o))throw new l("--recipient must resolve to a Sales Navigator lead urn");const a=c(t),s=String(n??"").trim();if(!a)throw new l("--subject is required");if(!s)throw new l("--body is required");if(a.length>200)throw new l("--subject must be 200 characters or fewer");if(s.length>1900)throw new l("--body must be 1900 characters or fewer");return{createMessageRequest:{recipients:[o],subject:a,body:s,copyToCrm:Boolean(i),trackingId:r}}}function _(e){const n=(Array.isArray(e?.elements)?e.elements:[]).find((o)=>o?.type==="LSS_INMAIL"&&Number.isInteger(o.value));if(n)return n.value;const r=[],i=(o)=>{if(o===null||o===void 0)return;if(typeof o==="number"&&Number.isFinite(o))r.push(o);if(Array.isArray(o))o.forEach(i);else if(typeof o==="object"){for(const[a,s]of Object.entries(o))if(/remaining|available|balance|value/i.test(a)&&typeof s==="number")r.unshift(s);else if(!/^count$|^start$|^id$/i.test(a))i(s)}};i(e);return r.find((o)=>Number.isInteger(o)&&o>=0)??null}function p(e,t,n={}){return String.raw`(async () => {
|
|
2
2
|
const headers = {
|
|
3
3
|
'csrf-token': ${JSON.stringify(t)},
|
|
4
4
|
'x-restli-protocol-version': '2.0.0',
|
|
@@ -21,7 +21,7 @@ import{cli as E,Strategy as q}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
21
21
|
} catch (e) {
|
|
22
22
|
return ['error', 0, null, '', 'fetch failed: ' + ((e && e.message) || String(e))];
|
|
23
23
|
}
|
|
24
|
-
})()`}function h(e,t,{requireJson:n=!0}={}){if(Array.isArray(e)){const[r,i,o,a,s]=e;e={authRequired:r==="auth",error:r==="error"?s||`HTTP ${i}`:"",status:i,json:o,text:a}}if(e?.authRequired)throw new b(w,`${t} auth failed.`);if(e?.error)throw new u(`${t} failed`,e.error);if(!e||typeof e!=="object"||Array.isArray(e))throw new u(`${t} returned malformed response`);if(n&&(!e.json||typeof e.json!=="object"||Array.isArray(e.json)))throw new u(`${t} returned malformed response`,"missing_json");return e}function A(e,t){const n=c(e),r=c(t).split(" ")[0];return n.includes("You sent a Sales Navigator message")&&(!r||n.includes(r))}async function
|
|
24
|
+
})()`}function h(e,t,{requireJson:n=!0}={}){if(Array.isArray(e)){const[r,i,o,a,s]=e;e={authRequired:r==="auth",error:r==="error"?s||`HTTP ${i}`:"",status:i,json:o,text:a}}if(e?.authRequired)throw new b(w,`${t} auth failed.`);if(e?.error)throw new u(`${t} failed`,e.error);if(!e||typeof e!=="object"||Array.isArray(e))throw new u(`${t} returned malformed response`);if(n&&(!e.json||typeof e.json!=="object"||Array.isArray(e.json)))throw new u(`${t} returned malformed response`,"missing_json");return e}function A(e,t){const n=c(e),r=c(t).split(" ")[0];return n.includes("You sent a Sales Navigator message")&&(!r||n.includes(r))}async function V(e){const n=(await e.getCookies({url:"https://www.linkedin.com"})).find((r)=>r.name==="JSESSIONID")?.value;if(!n)throw new b(w,"LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn.");return n.replace(/^\"|\"$/g,"")}async function W(e,t,n){if(!t)throw new l("--recipient must be a Sales Navigator lead URL, Sales Navigator profile URL, LinkedIn /in/ URL, or urn:li:fs_salesProfile:(...)");if(t.entityUrn&&t.authType&&t.authToken)return t;await e.goto(`https://www.linkedin.com/sales/lead/${encodeURIComponent(t.profileId)}`);await e.wait(6);const r=f(await e.evaluate(String.raw`(() => {
|
|
25
25
|
const href = location.href;
|
|
26
26
|
const text = document.body ? document.body.innerText : '';
|
|
27
27
|
const resourceUrns = Array.from(performance.getEntriesByType('resource'))
|
|
@@ -30,4 +30,4 @@ import{cli as E,Strategy as q}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
30
30
|
.slice(-20);
|
|
31
31
|
return { href, text: text.slice(0, 1000), resourceUrns };
|
|
32
32
|
})()`)),i=String(r?.href||"").match(/\/sales\/lead\/([^,/]+),([^,/]+),([^/?#]+)/i);if(i&&m(i[1],i[2],i[3]))return{profileId:decodeURIComponent(i[1]),authType:decodeURIComponent(i[2]),authToken:decodeURIComponent(i[3]),entityUrn:`urn:li:fs_salesProfile:(${decodeURIComponent(i[1])},${decodeURIComponent(i[2])},${decodeURIComponent(i[3])})`};for(const o of r?.resourceUrns||[]){const a=String(o).match(/profileId:([^,)]+),authType:([^,)]+),authToken:([^,)]+)\)/);if(a&&a[1]===t.profileId)return{profileId:a[1],authType:a[2],authToken:a[3],entityUrn:`urn:li:fs_salesProfile:(${a[1]},${a[2]},${a[3]})`}}throw new u("Could not resolve Sales Navigator auth token for recipient",`Observed URL: ${r?.href||"url_not_available"}
|
|
33
|
-
Body: ${c(r?.text||"").slice(0,500)}`)}function
|
|
33
|
+
Body: ${c(r?.text||"").slice(0,500)}`)}function j(e){const t=e?.data||e||{},n=t.defaultPosition||(Array.isArray(t.positions)?t.positions.find((r)=>r.current)||t.positions[0]:{})||{};return{recipient:c(t.fullName||[t.firstName,t.lastName].filter(Boolean).join(" ")),title:c(n.title||t.headline||""),company:c(n.companyName||n.company?.name||""),degree:c(t.degree||""),inmail_restriction:c(t.inmailRestriction||""),open_link:Boolean(t.memberBadges?.openLink)}}function C(e){const t=j(e);if(!t.recipient)throw new u("Sales Navigator profile lookup returned malformed profile data","missing_recipient_name");return t}q({site:"linkedin",name:"salesnav-message",access:"write",description:"Send or dry-run a LinkedIn Sales Navigator InMail to a lead using the Sales Navigator messaging API",domain:w,strategy:J.UI,browser:!0,args:[{name:"recipient",type:"string",required:!0,positional:!0,help:"Sales Navigator lead URL, LinkedIn /in/ URL from salesnav-search, or urn:li:fs_salesProfile:(...)"},{name:"subject",type:"string",required:!0,help:"InMail subject"},{name:"body",fromFile:!0,type:"string",required:!0,help:"InMail body"},{name:"send",type:"bool",default:!1,help:"Actually send the InMail. Default is dry-run validation only."},{name:"copy-to-crm",type:"bool",default:!1,help:"Set Sales Navigator copyToCrm on the message request"}],columns:["status","recipient","title","company","credits_remaining","credits_before","credits_after","sent_in_salesnav","message_chars","subject_chars","recipient_urn","degree","inmail_restriction","open_link"],func:async(e,t)=>{if(!e)throw new u("Browser session required for linkedin salesnav-message");const n=R(t,"recipient","--recipient"),r=R(t,"subject","--subject"),i=String(t.body??"").trim();if(!i)throw new l("--body is required");await e.goto(B);await e.wait(4);const o=await V(e),a=await W(e,v(n),o);let s={recipient:"",title:"",company:"",degree:"",inmail_restriction:"",open_link:!1};const d=U(a);if(d){const E=h(f(await e.evaluate(p(d,o))),"LinkedIn Sales Navigator profile API");s=C(E.json)}if(s.inmail_restriction&&s.inmail_restriction!=="NO_RESTRICTION")throw new u("Sales Navigator InMail blocked by recipient restriction",s.inmail_restriction);const L=h(f(await e.evaluate(p(k,o))),"LinkedIn Sales Navigator credits API"),y=_(L?.json),P=T({recipientUrn:a.entityUrn,subject:r,body:i,copyToCrm:t["copy-to-crm"]});if(!t.send)return[{status:"validated_dry_run",recipient:s.recipient,title:s.title,company:s.company,credits_remaining:y,credits_before:y,credits_after:"",sent_in_salesnav:!1,message_chars:i.length,subject_chars:r.length,recipient_urn:a.entityUrn,degree:s.degree,inmail_restriction:s.inmail_restriction,open_link:s.open_link}];const M=h(f(await e.evaluate(p(F,o,{method:"POST",accept:"application/vnd.linkedin.normalized+json+2.1",body:P}))),"LinkedIn Sales Navigator message API",{requireJson:!1});await e.wait(3);const x=h(f(await e.evaluate(p(k,o))),"LinkedIn Sales Navigator credits API after send"),I=_(x?.json);await e.goto(N(a));await e.wait(6);const O=f(await e.evaluate('document.body ? document.body.innerText : ""')),S=A(O,s.recipient);if(!S)throw new u("Sales Navigator post-send verification failed","Sent activity was not found on the Sales Navigator lead page.");return[{status:"sent",recipient:s.recipient,title:s.title,company:s.company,credits_remaining:I,credits_before:y,credits_after:I,sent_in_salesnav:S,message_chars:i.length,subject_chars:r.length,recipient_urn:a.entityUrn,degree:s.degree,inmail_restriction:s.inmail_restriction,open_link:s.open_link}]}});export const __test__={normalizeWhitespace:c,parseSalesProfileUrn:g,isResolvedSalesProfileParts:m,parseRecipient:v,salesLeadUrlFromParts:N,profileApiUrl:U,buildCreateMessagePayload:T,extractRemainingCredits:_,profileSummary:j,requireProfileSummary:C,salesPageShowsSentMessage:A};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as P,Strategy as v}from"@jackwener/opencli/registry";import{ArgumentError as S,AuthRequiredError as y,CommandExecutionError as i,EmptyResultError as R}from"@jackwener/opencli/errors";const f="www.linkedin.com",q="https://www.linkedin.com/sales/",b="https://www.linkedin.com/sales-api/salesApiLeadSearch",C="com.linkedin.sales.deco.desktop.searchv2.LeadSearchResult-14",k=25;function o(e){return String(e??"").replace(/[ ]/g," ").replace(/\s+/g," ").trim()}function U(e,r,t=r){const s=o(e[r]);if(!s)throw new S(`${t} is required`);return s}function I(e){if(e===void 0||e===null||e==="")return 25;const r=Number(e);if(!Number.isInteger(r)||r<1||r>500)throw new S("--limit must be an integer between 1 and 500");return r}function j(e){if(e&&typeof e==="object"&&"data"in e&&"session"in e)return e.data;return e}function N(e,r){const t="(spellCorrectionEnabled:true,recentSearchParam:(doLogHistory:true),keywords:"+encodeURIComponent(e)+")";return b+"?q=searchQuery&query="+t+"&start="+r+"&count="+k+"&decorationId="+C}function O(e,r){return String.raw`(async () => {
|
|
2
2
|
const headers = {
|
|
3
|
-
'csrf-token': ${JSON.stringify(
|
|
3
|
+
'csrf-token': ${JSON.stringify(r)},
|
|
4
4
|
'x-restli-protocol-version': '2.0.0',
|
|
5
5
|
accept: 'application/json',
|
|
6
6
|
};
|
|
7
7
|
try {
|
|
8
|
-
const res = await fetch(${JSON.stringify(
|
|
8
|
+
const res = await fetch(${JSON.stringify(e)}, { credentials: 'include', headers });
|
|
9
9
|
if (res.status === 401 || res.status === 403) return { authRequired: true, status: res.status };
|
|
10
10
|
if (!res.ok) return { error: 'HTTP ' + res.status };
|
|
11
11
|
return { json: await res.json() };
|
|
12
12
|
} catch (e) {
|
|
13
13
|
return { error: 'fetch failed: ' + ((e && e.message) || String(e)) };
|
|
14
14
|
}
|
|
15
|
-
})()`}function
|
|
15
|
+
})()`}function m(e){const r=String(e||"").match(/fs_salesProfile:\(([^,)]+)/);return r&&r[1]?"https://www.linkedin.com/in/"+r[1]:""}function A(e){const r=String(e||"").match(/^urn:li:fs_salesProfile:\(([^,()]+),([^,()]+),([^,()]+)\)$/);if(!r)return"";return`https://www.linkedin.com/sales/lead/${encodeURIComponent(r[1])},${encodeURIComponent(r[2])},${encodeURIComponent(r[3])}`}function E(e){if(!e||typeof e!=="object"||!Array.isArray(e.elements))throw new i("Sales Navigator lead search API returned malformed payload");const r=[];for(const t of e.elements){if(!t||typeof t!=="object")throw new i("Sales Navigator lead search API returned malformed lead row");const s=Array.isArray(t.currentPositions)?t.currentPositions:[],w=Array.isArray(t.pastPositions)?t.pastPositions:[],c=s[0]||w[0]||{},l=o(t.fullName||[t.firstName,t.lastName].filter(Boolean).join(" "));if(!l)throw new i("Sales Navigator lead row missing name");const n=o(t.entityUrn||"");if(!m(n))throw new i("Sales Navigator lead row missing profile identity");r.push({name:l,title:o(c.title||""),company:o(c.companyName||""),location:o(t.geoRegion||""),degree:o(t.degree||""),profile_url:m(n),lead_url:A(n),recipient_urn:n})}return r}function _(e){if(e?.authRequired)throw new y(f,"LinkedIn Sales Navigator API auth failed (HTTP "+(e.status||"")+"). Confirm the account has Sales Navigator access.");if(e?.error)throw new i("Sales Navigator lead search API returned an unexpected response",e.error);if(!e||!e.json)throw new i("Sales Navigator lead search API returned an unexpected response","no_json");return e.json}P({site:"linkedin",name:"salesnav-search",access:"read",description:"Search LinkedIn Sales Navigator for people leads by keyword",domain:f,strategy:v.UI,browser:!0,args:[{name:"keywords",type:"string",required:!0,positional:!0,help:'People search keywords, e.g. "quality manager food manufacturing"'},{name:"limit",type:"number",default:25,help:"Maximum leads to return (1-500, fetched 25 per request)"}],columns:["rank","name","title","company","location","degree","profile_url","lead_url","recipient_urn"],func:async(e,r)=>{if(!e)throw new i("Browser session required for linkedin salesnav-search");const t=U(r,"keywords","--keywords"),s=I(r.limit);await e.goto(q);await e.wait(6);const c=(await e.getCookies({url:"https://www.linkedin.com"})).find((a)=>a.name==="JSESSIONID")?.value;if(!c)throw new y(f,"LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn.");const l=c.replace(/^\"|\"$/g,""),n=[],h=new Set;for(let a=0;n.length<s&&a<2000;a+=k){const u=j(await e.evaluate(O(N(t,a),l))),L=_(u),p=E(L);if(p.length===0)break;for(const d of p){const g=d.profile_url||d.name.toLowerCase();if(h.has(g))continue;h.add(g);n.push(d)}await e.wait(1)}if(n.length===0)throw new R("linkedin salesnav-search","No Sales Navigator leads were found.");return n.slice(0,s).map((a,u)=>({rank:u+1,...a}))}});export const __test__={normalizeWhitespace:o,parseLimit:I,leadSearchUrl:N,profileUrlFromEntityUrn:m,leadUrlFromEntityUrn:A,parseLeads:E,requireLeadSearchResult:_};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as R,Strategy as
|
|
1
|
+
import{cli as R,Strategy as x}from"@jackwener/opencli/registry";import{ArgumentError as f,CommandExecutionError as l,EmptyResultError as w}from"@jackwener/opencli/errors";import{THREAD_DECORATION as C,THREADS_BASE as U,encodeRestliDecoration as L,fetchInboxRows as E,fetchSalesnavJson as k,getCsrf as P,normalizeWhitespace as o,parseLimit as g}from"./salesnav-inbox.js";const T="www.linkedin.com",M="https://www.linkedin.com/sales/inbox/",h=200,_=20;function D(e){const r=String(e||"").toLowerCase();return r==="linkedin.com"||r.endsWith(".linkedin.com")}function y(e){const r=o(e),a=r.match(/^urn:li:fs_salesProfile:\(([^,()]+),([^,()]+),([^,()]+)\)$/);if(!a)return"";if([a[1],a[2],a[3]].map((n)=>o(n).toLowerCase()).some((n)=>!n||n==="undefined"||n==="null"||n==="not_available"))return"";return r}function b(e){const r=o(e);if(!r)return["empty",""];if(/^2-[A-Za-z0-9+/=_-]+$/.test(r))return["thread_id",r];if(/^urn:li:fs_salesProfile:\(/.test(r)){const a=y(r);if(!a)throw new f("Sales Navigator recipient urn must be urn:li:fs_salesProfile:(profileId,authType,authToken)");return["recipient_urn",a]}try{const a=new URL(r);if(a.protocol!=="https:"||a.username||a.password||a.port||!D(a.hostname))return["name",r.toLowerCase()];const s=a.pathname.match(/^\/sales\/inbox\/([^/]+)\/?$/i);if(s)return["thread_id",decodeURIComponent(s[1])];const n=a.pathname.match(/^\/sales\/lead\/([^,/]+),([^,/]+),([^/]+)\/?$/i);if(n){const t=`urn:li:fs_salesProfile:(${decodeURIComponent(n[1])},${decodeURIComponent(n[2])},${decodeURIComponent(n[3])})`;if(!y(t))throw new f("Sales Navigator lead URL must contain resolved profileId, authType, and authToken");return["recipient_urn",t]}}catch(a){if(a instanceof f)throw a}return["name",r.toLowerCase()]}function v(e){return e?`https://www.linkedin.com/sales/inbox/${encodeURIComponent(e)}`:""}function I(e,r){return`${U}/${encodeURIComponent(e)}?decoration=${L(C)}&count=1&messageCount=${r}`}function j(e){return o(e?.fullName||[e?.firstName,e?.lastName].filter(Boolean).join(" "))}function N(e){const r=e?.participantsResolutionResults||{},a=Array.isArray(e?.participants)?e.participants:Object.keys(r),s=new Map;for(const n of a){const t=r[n]||{entityUrn:n};s.set(n,t)}return s}function A(e){if(!e||typeof e!=="object")throw new l("Sales Navigator messaging thread API returned malformed payload");const r=o(e?.id||"");if(!r)throw new l("Sales Navigator messaging thread API returned a thread without id");if(!Array.isArray(e?.messages))throw new l("Sales Navigator messaging thread API returned malformed messages");const a=N(e),n=e.messages.map((t)=>{if(!t||typeof t!=="object")throw new l("Sales Navigator messaging thread API returned malformed message row");const i=Number(t?.deliveredAt||0),c=a.get(t?.author);return{message_id:o(t?.id||""),thread_id:r,sender:j(c)||o(t?.author||""),sender_urn:o(t?.author||""),text:o(t?.body||t?.systemMessageContent||""),subject:o(t?.subject||""),timestamp:i?new Date(i).toISOString():"",delivered_at:i||"",type:o(t?.type||"")}}).filter((t)=>t.text||t.subject||t.message_id);n.sort((t,i)=>Number(t.delivered_at||0)-Number(i.delivered_at||0));return n.map((t,i)=>({index:i,...t}))}function S(e,r){if(!e||!r)return!1;const[a,s]=r;if(a==="thread_id")return e.thread_id===s;if(a==="recipient_urn")return(e.participants||[]).some((n)=>o(n.entity_urn)===s);if(a==="name"){const n=o(s).toLowerCase();if(!n)return!1;if(o(e.person_name).toLowerCase()===n)return!0;return(e.participants||[]).some((t)=>o(t.name).toLowerCase()===n)}return!1}async function q(e,r,{maxPages:a=30}={}){const s=b(r);if(s[0]==="empty")throw new f("thread or recipient is required");if(s[0]==="thread_id")return s[1];const t=(await E(e,{limit:500,maxPages:a})).find((i)=>S(i,s));if(!t)throw new w("linkedin salesnav-thread",`No Sales Navigator thread matched ${r}`);return t.thread_id}async function O(e,r,a,s=h){let n=_;if(s<n)n=s;let t=null;for(let u=0;u<30;u+=1){t=await k(e,r,I(a,n),"Sales Navigator messaging thread API");const d=Number(t?.totalMessageCount||0),p=Array.isArray(t?.messages)?t.messages.length:0;if(p>=s||d&&p>=d||n>=s)break;let m=n+_;if(d&&d>m)m=d;if(m>s)m=s;n=m}const i=Number(t?.totalMessageCount||0),c=Array.isArray(t?.messages)?t.messages.length:0;if(i&&c<i&&c<s)throw new l(`Sales Navigator messaging thread API returned partial history (${c}/${i})`);return t}R({site:"linkedin",name:"salesnav-thread",access:"read",description:"Return full Sales Navigator message history for a thread id, Sales Navigator inbox URL, lead URL, recipient urn, or exact recipient name",domain:T,strategy:x.UI,browser:!0,args:[{name:"thread-or-recipient",type:"string",required:!0,positional:!0,help:"Sales Navigator inbox URL/thread id, Sales Navigator lead URL, recipient urn, or exact participant name"},{name:"limit",type:"number",default:h,help:"Maximum messages to return (1-500)"},{name:"max-pages",type:"number",default:30,help:"Maximum inbox pages to scan when resolving a recipient"}],columns:["index","thread_id","thread_url","sender","text","timestamp","subject","message_id","sender_urn","delivered_at","type","total_message_count"],func:async(e,r)=>{if(!e)throw new l("Browser session required for linkedin salesnav-thread");const a=o(r["thread-or-recipient"]);if(!a)throw new f("thread-or-recipient is required");const s=g(r.limit,h),n=g(r["max-pages"],30);await e.goto(M);await e.wait(4);const t=await q(e,a,{maxPages:n}),i=await P(e),c=await O(e,i,t,s),u=A(c).slice(0,s);if(u.length===0)throw new w("linkedin salesnav-thread",`No messages found for ${t}`);return u.map((d)=>({...d,thread_url:v(t),total_message_count:Number(c?.totalMessageCount||u.length)}))}});export const __test__={parseThreadInput:b,threadApiUrl:I,participantIndex:N,parseSalesnavThreadMessages:A,threadMatchesInput:S,salesnavThreadUrl:v};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as u,CommandExecutionError as l}from"@jackwener/opencli/errors";import{unwrapEvaluateResult as y}from"./shared.js";export const SEARCH_CLUSTERS_QUERY_ID="voyagerSearchDashClusters.ef3d0937fb65bd7812e32e5a85028e79";function a({keywords:t,filters:n,start:s,count:i}){const o=t?`keywords:${encodeURIComponent(t)},`:"",r=`List(${n.join(",")})`;return`(start:${s},count:${i},origin:GLOBAL_SEARCH_HEADER,query:(${o}flagshipSearchIntent:SEARCH_SRP,queryParameters:${r},includeFiltersInResponse:false))`}function m(t,n){return`(async () => {
|
|
2
2
|
const norm = (s) => String(s == null ? '' : s).replace(/[ ]+/g, ' ').replace(/\\s+/g, ' ').trim();
|
|
3
3
|
const csrf = ((document.cookie.split('; ').find((c) => c.startsWith('JSESSIONID=')) || '').split('=')[1] || '').replace(/^"|"$/g, '');
|
|
4
4
|
if (!csrf) return { ok: false, auth: true };
|
|
5
|
-
const url = '/voyager/api/graphql?queryId=' + ${JSON.stringify(
|
|
5
|
+
const url = '/voyager/api/graphql?queryId=' + ${JSON.stringify(n)} + '&variables=' + ${JSON.stringify(t)};
|
|
6
6
|
const res = await fetch(url, { credentials: 'include', headers: {
|
|
7
7
|
'csrf-token': csrf,
|
|
8
8
|
'accept': 'application/vnd.linkedin.normalized+json+2.1',
|
|
@@ -39,4 +39,4 @@ import{AuthRequiredError as X,CommandExecutionError as Z}from"@jackwener/opencli
|
|
|
39
39
|
}
|
|
40
40
|
const paging = clusters.paging || {};
|
|
41
41
|
return { ok: true, rows, total: paging.total || 0 };
|
|
42
|
-
})()`}export async function fetchSearchClusters(
|
|
42
|
+
})()`}export async function fetchSearchClusters(t,{keywords:n="",filters:s=[],start:i=0,count:o=10},r){const c=a({keywords:n,filters:s,start:i,count:o}),e=y(await t.evaluate(m(c,SEARCH_CLUSTERS_QUERY_ID)));if(e?.auth)throw new u("linkedin.com",`LinkedIn ${r} requires an active signed-in browser session`);if(!e?.ok)throw new l(`LinkedIn ${r}: search API returned HTTP ${e?.status||"?"}`);return{rows:Array.isArray(e.rows)?e.rows:[],total:Number(e.total)||0}}export const __test__={buildVariables:a,SEARCH_CLUSTERS_QUERY_ID};
|
package/clis/linkedin/search.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as q,Strategy as P}from"@jackwener/opencli/registry";import{ArgumentError as p,AuthRequiredError as y,CommandExecutionError as R}from"@jackwener/opencli/errors";const g="linkedin.com",D=1,O=100,N=0,x={internship:"1",entry:"2","entry-level":"2",associate:"3",mid:"4",senior:"4","mid-senior":"4","mid-senior-level":"4",director:"5",executive:"6"},k={"full-time":"F",fulltime:"F",full:"F","part-time":"P",parttime:"P",part:"P",contract:"C",temporary:"T",temp:"T",volunteer:"V",internship:"I",other:"O"},L={any:"on",month:"r2592000","past-month":"r2592000",week:"r604800","past-week":"r604800",day:"r86400","24h":"r86400","past-24h":"r86400"},j={onsite:"1","on-site":"1",hybrid:"3",remote:"2"};function b(e){if(e===void 0||e===null||e==="")return[];return String(e).split(",").map((t)=>t.trim()).filter(Boolean)}function m(e,t,r){const o=b(e).map((i)=>{const s=i.toLowerCase(),c=t[s];if(!c)throw new p(`Unsupported ${r}: ${i}`);return c});return[...new Set(o)]}function J(e){return String(e??"").replace(/\s+/g," ").trim()}function w(e,t,r,n,o=1/0){if(e===void 0||e===null||e==="")return r;const i=Number(e);if(!Number.isFinite(i)||!Number.isInteger(i))throw new p(`${t} must be an integer, got ${JSON.stringify(e)}`);if(i<n||i>o){const s=Number.isFinite(o)?`between ${n} and ${o}`:`at least ${n}`;throw new p(`${t} must be ${s}, got ${i}`)}return i}function A(e){if(!e)return"";try{const t=new URL(e);if(t.pathname==="/redir/redirect/")return t.searchParams.get("url")||e}catch{}return e}function F(e){const r=["origin:"+(e.companyIds.length||e.experienceLevels.length||e.jobTypes.length||e.datePostedValues.length||e.remoteTypes.length?"JOB_SEARCH_PAGE_JOB_FILTER":"JOB_SEARCH_PAGE_OTHER_ENTRY"),"keywords:"+e.keywords];if(e.location)r.push("locationUnion:(seoLocation:(location:"+e.location+"))");const n=[];if(e.companyIds.length)n.push("company:List("+e.companyIds.join(",")+")");if(e.experienceLevels.length)n.push("experience:List("+e.experienceLevels.join(",")+")");if(e.jobTypes.length)n.push("jobType:List("+e.jobTypes.join(",")+")");if(e.datePostedValues.length)n.push("timePostedRange:List("+e.datePostedValues.join(",")+")");if(e.remoteTypes.length)n.push("workplaceType:List("+e.remoteTypes.join(",")+")");if(n.length)r.push("selectedFilters:("+n.join(",")+")");r.push("spellCorrectionEnabled:true");return"("+r.join(",")+")"}function U(e,t,r){const n=new URLSearchParams({decorationId:"com.linkedin.voyager.dash.deco.jobs.search.JobSearchCardsCollection-220",count:String(r),q:"jobSearch"}),o=encodeURIComponent(F(e)).replace(/%3A/gi,":").replace(/%2C/gi,",").replace(/%28/gi,"(").replace(/%29/gi,")");return"/voyager/api/voyagerJobsDashJobCards?"+n.toString()+"&query="+o+"&start="+t}function T(e){const t=String(e??"").replace(/\s+/g," ").trim().toLowerCase();if(!t)return!1;return/\b(sign in|log in|join linkedin)\b/.test(t)||/linkedin\.com\/(login|checkpoint|authwall)/i.test(t)||/\b(captcha|verification required)\b/.test(t)||/(请登录|登录领英|安全验证)/.test(t)}function B(){return`(() => {
|
|
2
2
|
const text = [
|
|
3
3
|
window.location.href || '',
|
|
4
4
|
document.title || '',
|
|
5
5
|
document.body ? (document.body.innerText || '').slice(0, 4000) : '',
|
|
6
6
|
].join('\\n');
|
|
7
|
-
return ${
|
|
8
|
-
})()`}async function
|
|
9
|
-
const res = await fetch(${JSON.stringify(
|
|
7
|
+
return ${T.toString()}(text);
|
|
8
|
+
})()`}async function _(e,t){if(await e.evaluate(B()))throw new y(g,`${t} requires an active signed-in LinkedIn browser session`)}function M(e){const t=new Set,r=[];for(const n of b(e)){const o=n.replace(/^urn:li:[a-z_]+:/,"");if(/^\d+$/.test(o))t.add(o);else r.push(n)}if(r.length)throw new p(`--company now requires numeric LinkedIn company IDs (got name(s): ${r.join(", ")}). Find an ID from the company's LinkedIn page URL or its /company/<slug>/ Voyager data.`);return[...t]}async function V(e,t){const r=25,n=[];let o=t.start;const s=(await e.getCookies({url:"https://www.linkedin.com"})).find((a)=>a.name==="JSESSIONID")?.value;if(!s)throw new y(g,"LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.");const c=s.replace(/^"|"$/g,"");while(n.length<t.limit){const a=Math.min(r,t.limit-n.length),u=U(t,o,a),d=await e.evaluate(`(async () => {
|
|
9
|
+
const res = await fetch(${JSON.stringify(u)}, {
|
|
10
10
|
credentials: 'include',
|
|
11
|
-
headers: { 'csrf-token': ${JSON.stringify(
|
|
11
|
+
headers: { 'csrf-token': ${JSON.stringify(c)}, 'x-restli-protocol-version': '2.0.0' },
|
|
12
12
|
});
|
|
13
13
|
if (res.status === 401 || res.status === 403) {
|
|
14
14
|
const text = await res.text();
|
|
@@ -22,14 +22,14 @@ import{cli as w,Strategy as A}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
22
22
|
return { error: 'LinkedIn API error: HTTP ' + res.status + ' ' + text.slice(0, 200) };
|
|
23
23
|
}
|
|
24
24
|
return res.json();
|
|
25
|
-
})()`);if(!
|
|
25
|
+
})()`);if(!d||d.error){if(d?.authRequired)throw new y(g,d.error);throw new R(d?.error||"LinkedIn search returned an unexpected response")}const h=Array.isArray(d?.elements)?d.elements:[];if(h.length===0)break;for(const v of h){const l=v?.jobCardUnion?.jobPostingCard;if(!l)continue;const I=[l.jobPostingUrn,l.jobPosting?.entityUrn,l.entityUrn].filter(Boolean).map((f)=>String(f).match(/(\d+)/)?.[1]).find(Boolean)??"",S=(l.footerItems||[]).find((f)=>f?.type==="LISTED_DATE"&&f?.timeAt),E=S?.timeAt?new Date(S.timeAt).toISOString().slice(0,10):"";n.push({title:l.jobPostingTitle||l.title?.text||"",company:l.primaryDescription?.text||"",location:l.secondaryDescription?.text||"",listed:E,salary:l.tertiaryDescription?.text||"",url:I?"https://www.linkedin.com/jobs/view/"+I:""})}if(h.length<a)break;o+=h.length}return n.slice(0,t.limit).map((a,u)=>({rank:t.start+u+1,...a}))}async function C(e,t){const r=[];for(let n=0;n<t.length;n++){const o=t[n];console.error(`[ppcli:linkedin] Fetching details ${n+1}/${t.length}: ${o.title}`);if(!o.url){const i="no url";console.error(`[ppcli:linkedin] Skipping detail for "${o.title}": ${i}`);r.push({...o,description:null,apply_url:null,detail_error:i});continue}try{await e.goto(o.url);await _(e,"LinkedIn job detail");await e.wait({text:"About the job",timeout:8});await e.evaluate(`(() => {
|
|
26
26
|
const norm = (v) => (v || '').replace(/\\s+/g, ' ').trim().toLowerCase();
|
|
27
27
|
const section = [...document.querySelectorAll('div, section, article')]
|
|
28
28
|
.find(el => norm(el.querySelector('h1,h2,h3,h4')?.textContent || '') === 'about the job');
|
|
29
29
|
const btn = [...(section?.querySelectorAll('button, a[role="button"]') || [])]
|
|
30
30
|
.find(el => /more/.test(norm(el.textContent || '')) || /more/.test(norm(el.getAttribute('aria-label') || '')));
|
|
31
31
|
if (btn) btn.click();
|
|
32
|
-
})()`);await
|
|
32
|
+
})()`);await e.wait(1);const i=await e.evaluate(`(() => {
|
|
33
33
|
const norm = (v) => (v || '').replace(/\\s+/g, ' ').trim();
|
|
34
34
|
// Find the most specific (shortest) container with "About the job" heading
|
|
35
35
|
// Shortest = most specific DOM node, avoiding outer wrappers that include unrelated text
|
|
@@ -47,4 +47,4 @@ import{cli as w,Strategy as A}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
47
47
|
.find(a => /apply/i.test(a.text) || /apply/i.test(a.aria));
|
|
48
48
|
|
|
49
49
|
return { description, applyUrl: applyLink?.href || '' };
|
|
50
|
-
})()`),
|
|
50
|
+
})()`),s=J(i?.description),c=A(String(i?.applyUrl??"")),a=s?null:"missing description";r.push({...o,description:s||null,apply_url:c||null,detail_error:a})}catch(i){if(i instanceof y)throw i;const s=`fetch failed: ${i?.message||i}`;console.error(`[ppcli:linkedin] Detail fetch failed for ${o.url}: ${s}`);r.push({...o,description:null,apply_url:null,detail_error:s})}}return r}q({site:"linkedin",name:"search",access:"read",description:"Search LinkedIn jobs",domain:"www.linkedin.com",strategy:P.COOKIE,browser:!0,args:[{name:"query",type:"string",required:!0,positional:!0,help:"Job search keywords"},{name:"location",type:"string",required:!1,help:"Location text such as San Francisco Bay Area"},{name:"limit",type:"int",default:10,help:"Number of jobs to return (max 100)"},{name:"start",type:"int",default:0,help:"Result offset for pagination"},{name:"details",type:"bool",default:!1,help:"Include full job description and apply URL (slower)"},{name:"company",type:"string",required:!1,help:"Comma-separated company names or LinkedIn company IDs"},{name:"experience-level",type:"string",required:!1,help:"Comma-separated: internship, entry, associate, mid-senior, director, executive"},{name:"job-type",type:"string",required:!1,help:"Comma-separated: full-time, part-time, contract, temporary, volunteer, internship, other"},{name:"date-posted",type:"string",required:!1,help:"One of: any, month, week, 24h"},{name:"remote",type:"string",required:!1,help:"Comma-separated: on-site, hybrid, remote"}],columns:["rank","title","company","location","listed","salary","url"],func:async(e,t)=>{const r=w(t.limit,"--limit",10,D,O),n=w(t.start,"--start",0,N),o=Boolean(t.details),i=(t.location??"").trim(),s=String(t.query??"").trim();if(!s)throw new p("query is required");await e.goto("https://www.linkedin.com/jobs/");await e.wait(2);const c=M(t.company),a={keywords:s,location:i,limit:r,start:n,companyIds:c,experienceLevels:m(t["experience-level"],x,"experience_level"),jobTypes:m(t["job-type"],k,"job_type"),datePostedValues:m(t["date-posted"],L,"date_posted"),remoteTypes:m(t.remote,j,"remote")},u=await V(e,a);if(!o)return u;return C(e,u)}});export const __test__={parseCsvArg:b,parseIntegerArg:w,mapFilterValues:m,decodeLinkedinRedirect:A,looksLinkedInAuthWallText:T,assertLinkedInAuthenticated:_,enrichJobDetails:C,EXPERIENCE_LEVELS:x,JOB_TYPES:k,DATE_POSTED:L,REMOTE_TYPES:j};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as a}from"@jackwener/opencli/errors";export const NORM_COMMENT_DECORATION="com.linkedin.voyager.dash.deco.social.NormComment-43",REACTION_CREATE_QID="voyagerSocialDashReactions.b731222600772fd42464c0fe19bd722b",REACTION_DELETE_QID="voyagerSocialDashReactions.f68b48ae5bc0085d7a45c7003b772a39",REPOST_CREATE_QID="voyagerFeedDashReposts.a0663ae5c654123343da36617d2dbfde";export function looksLikeCommentUrn(e){const t=String(e??"");return/urn:li:(fsd_)?comment:\(/.test(t)}export const REACTION_TYPES=["LIKE","CELEBRATE","SUPPORT","LOVE","INSIGHTFUL","FUNNY"];const s={like:"LIKE",celebrate:"PRAISE",praise:"PRAISE",support:"EMPATHY",empathy:"EMPATHY",love:"APPRECIATION",appreciation:"APPRECIATION",insightful:"INTEREST",interest:"INTEREST",funny:"ENTERTAINMENT",entertainment:"ENTERTAINMENT",haha:"ENTERTAINMENT"};export function parseReactionType(e){const t=String(e??"like").trim().toLowerCase(),n=s[t];if(!n)throw new a(`--reaction 只能是 like / celebrate / support / love / insightful / funny(收到 "${e}")`);return n}export function normalizeThreadUrn(e){const t=String(e??"").trim();if(!t)throw new a("post 标识必填(帖子 URL 或 urn:li:activity:… / urn:li:ugcPost:…)");const n=t.match(/urn:li:(activity|ugcPost|share):(\d+)/);if(n)return`urn:li:${n[1]}:${n[2]}`;const r=t.match(/activity[:\-](\d{6,})/i);if(r)return`urn:li:activity:${r[1]}`;const o=t.match(/ugcPost[:\-](\d{6,})/i);if(o)return`urn:li:ugcPost:${o[1]}`;throw new a(`无法从 "${t}" 解析出帖子 urn(需 activity/ugcPost urn 或含 activity-<id> 的 LinkedIn 链接)`)}export function normalizeCommentUrn(e){const t=String(e??"").trim();if(!t)throw new a("comment 标识必填(urn:li:comment:(…) 或 urn:li:fsd_comment:(…))");const n=t.match(/urn:li:comment:\((activity|ugcPost):(\d+),(\d+)\)/);if(n)return`urn:li:comment:(${n[1]}:${n[2]},${n[3]})`;const r=t.match(/urn:li:fsd_comment:\((\d+),urn:li:(activity|ugcPost):(\d+)\)/);if(r)return`urn:li:comment:(${r[2]}:${r[3]},${r[1]})`;throw new a(`无法解析评论 urn "${t}"(需 urn:li:comment:(…) 或 urn:li:fsd_comment:(…);可从 linkedin post-comments 的 comment_urn 列直接取)`)}export const SOCIAL_PREAMBLE=String.raw`
|
|
2
2
|
const jsessionRaw = (document.cookie.split('; ').find((c) => c.startsWith('JSESSIONID=')) || '').split('=')[1] || '';
|
|
3
3
|
const csrf = jsessionRaw.replace(/^"|"$/g, '');
|
|
4
4
|
if (!csrf) return { ok: false, stage: 'auth', error: 'JSESSIONID_missing' };
|
|
@@ -9,11 +9,11 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
9
9
|
'x-li-lang': 'en_US',
|
|
10
10
|
'content-type': 'application/json; charset=UTF-8',
|
|
11
11
|
};
|
|
12
|
-
`;export function buildReactScript({threadUrn:
|
|
12
|
+
`;export function buildReactScript({threadUrn:e,reactionType:t,remove:n}){return`(async () => {
|
|
13
13
|
${SOCIAL_PREAMBLE}
|
|
14
|
-
const THREAD = ${JSON.stringify(
|
|
15
|
-
const REMOVE = ${JSON.stringify(Boolean(
|
|
16
|
-
const REACTION = ${JSON.stringify(
|
|
14
|
+
const THREAD = ${JSON.stringify(e)};
|
|
15
|
+
const REMOVE = ${JSON.stringify(Boolean(n))};
|
|
16
|
+
const REACTION = ${JSON.stringify(t)};
|
|
17
17
|
if (REMOVE) {
|
|
18
18
|
const res = await fetch('/voyager/api/voyagerSocialDashReactions?action=deleteReaction', {
|
|
19
19
|
method: 'POST', credentials: 'include', headers: H,
|
|
@@ -28,15 +28,15 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
28
28
|
});
|
|
29
29
|
if (res.status === 201 || res.status === 200) return { ok: true, removed: false, reaction: REACTION, httpStatus: res.status };
|
|
30
30
|
return { ok: false, stage: 'react', httpStatus: res.status, error: (await res.text()).slice(0, 300) };
|
|
31
|
-
})()`}export function buildCommentScript({threadUrn:
|
|
31
|
+
})()`}export function buildCommentScript({threadUrn:e,text:t,decorationId:n}){return`(async () => {
|
|
32
32
|
${SOCIAL_PREAMBLE}
|
|
33
|
-
const THREAD = ${JSON.stringify(
|
|
34
|
-
const TEXT = ${JSON.stringify(
|
|
33
|
+
const THREAD = ${JSON.stringify(e)};
|
|
34
|
+
const TEXT = ${JSON.stringify(t)};
|
|
35
35
|
const payload = {
|
|
36
36
|
commentary: { text: TEXT, attributesV2: [], $type: 'com.linkedin.voyager.dash.common.text.TextViewModel' },
|
|
37
37
|
threadUrn: THREAD,
|
|
38
38
|
};
|
|
39
|
-
const res = await fetch('/voyager/api/voyagerSocialDashNormComments?decorationId=' + ${JSON.stringify(
|
|
39
|
+
const res = await fetch('/voyager/api/voyagerSocialDashNormComments?decorationId=' + ${JSON.stringify(n)}, {
|
|
40
40
|
method: 'POST', credentials: 'include', headers: H,
|
|
41
41
|
body: JSON.stringify(payload),
|
|
42
42
|
});
|
|
@@ -49,9 +49,9 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
49
49
|
const m = body.match(/urn:li:fsd_comment:\\((\\d+),urn:li:(activity|ugcPost):(\\d+)\\)/);
|
|
50
50
|
if (m) commentUrn = 'urn:li:comment:(' + m[2] + ':' + m[3] + ',' + m[1] + ')';
|
|
51
51
|
return { ok: true, commentUrn, httpStatus: res.status };
|
|
52
|
-
})()`}export function buildPostDetailScript({activityUrn:
|
|
52
|
+
})()`}export function buildPostDetailScript({activityUrn:e}){return`(async () => {
|
|
53
53
|
${SOCIAL_PREAMBLE}
|
|
54
|
-
const ACTIVITY = ${JSON.stringify(
|
|
54
|
+
const ACTIVITY = ${JSON.stringify(e)};
|
|
55
55
|
const res = await fetch('/voyager/api/feed/updates/' + encodeURIComponent(ACTIVITY) + '?commentsCount=0&likesCount=0', { credentials: 'include', headers: H });
|
|
56
56
|
if (!res.ok) return { ok: false, stage: 'read', httpStatus: res.status, error: (await res.text()).slice(0, 300) };
|
|
57
57
|
const j = await res.json();
|
|
@@ -85,11 +85,11 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
85
85
|
url: perm,
|
|
86
86
|
},
|
|
87
87
|
};
|
|
88
|
-
})()`}export function buildReadCommentsScript({activityUrn:
|
|
88
|
+
})()`}export function buildReadCommentsScript({activityUrn:e,count:t,start:n,sortOrder:r}){return`(async () => {
|
|
89
89
|
${SOCIAL_PREAMBLE}
|
|
90
|
-
const ACTIVITY = ${JSON.stringify(
|
|
91
|
-
const url = '/voyager/api/feed/comments?count=' + ${JSON.stringify(
|
|
92
|
-
+ '&q=comments&sortOrder=' + ${JSON.stringify(
|
|
90
|
+
const ACTIVITY = ${JSON.stringify(e)};
|
|
91
|
+
const url = '/voyager/api/feed/comments?count=' + ${JSON.stringify(t)} + '&start=' + ${JSON.stringify(n)}
|
|
92
|
+
+ '&q=comments&sortOrder=' + ${JSON.stringify(r)} + '&updateId=' + encodeURIComponent(ACTIVITY);
|
|
93
93
|
const res = await fetch(url, { credentials: 'include', headers: H });
|
|
94
94
|
if (!res.ok) return { ok: false, stage: 'read', httpStatus: res.status, error: (await res.text()).slice(0, 300) };
|
|
95
95
|
const j = await res.json();
|
|
@@ -133,14 +133,14 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
133
133
|
});
|
|
134
134
|
const total = (j.data && j.data.paging && j.data.paging.total) || rows.length;
|
|
135
135
|
return { ok: true, rows, total };
|
|
136
|
-
})()`}export function buildCommentReactScript({commentUrn:
|
|
136
|
+
})()`}export function buildCommentReactScript({commentUrn:e,reactionType:t,remove:n,createQid:r,deleteQid:o}){return`(async () => {
|
|
137
137
|
${SOCIAL_PREAMBLE}
|
|
138
138
|
const GH = Object.assign({}, H, { 'x-li-graphql-pegasus-client': 'true' });
|
|
139
|
-
const COMMENT = ${JSON.stringify(
|
|
140
|
-
const REMOVE = ${JSON.stringify(Boolean(
|
|
141
|
-
const REACTION = ${JSON.stringify(
|
|
139
|
+
const COMMENT = ${JSON.stringify(e)};
|
|
140
|
+
const REMOVE = ${JSON.stringify(Boolean(n))};
|
|
141
|
+
const REACTION = ${JSON.stringify(t)};
|
|
142
142
|
if (REMOVE) {
|
|
143
|
-
const qid = ${JSON.stringify(
|
|
143
|
+
const qid = ${JSON.stringify(o)};
|
|
144
144
|
const res = await fetch('/voyager/api/graphql?action=execute&queryId=' + qid, {
|
|
145
145
|
method: 'POST', credentials: 'include', headers: GH,
|
|
146
146
|
body: JSON.stringify({ variables: { threadUrn: COMMENT }, queryId: qid, includeWebMetadata: true }),
|
|
@@ -148,17 +148,17 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
148
148
|
if (res.status === 200 || res.status === 201) return { ok: true, removed: true };
|
|
149
149
|
return { ok: false, stage: 'unreact_comment', httpStatus: res.status, error: (await res.text()).slice(0, 300) };
|
|
150
150
|
}
|
|
151
|
-
const qid = ${JSON.stringify(
|
|
151
|
+
const qid = ${JSON.stringify(r)};
|
|
152
152
|
const res = await fetch('/voyager/api/graphql?action=execute&queryId=' + qid, {
|
|
153
153
|
method: 'POST', credentials: 'include', headers: GH,
|
|
154
154
|
body: JSON.stringify({ variables: { entity: { reactionType: REACTION }, threadUrn: COMMENT }, queryId: qid, includeWebMetadata: true }),
|
|
155
155
|
});
|
|
156
156
|
if (res.status === 200 || res.status === 201) return { ok: true, removed: false, reaction: REACTION };
|
|
157
157
|
return { ok: false, stage: 'react_comment', httpStatus: res.status, error: (await res.text()).slice(0, 300) };
|
|
158
|
-
})()`}export function buildRepostScript({activityUrn:
|
|
158
|
+
})()`}export function buildRepostScript({activityUrn:e,commentary:t,repostQid:n}){return`(async () => {
|
|
159
159
|
${SOCIAL_PREAMBLE}
|
|
160
|
-
const ACTIVITY = ${JSON.stringify(
|
|
161
|
-
const COMMENTARY = ${JSON.stringify(
|
|
160
|
+
const ACTIVITY = ${JSON.stringify(e)};
|
|
161
|
+
const COMMENTARY = ${JSON.stringify(t||"")};
|
|
162
162
|
// 1. 解析 shareUrn
|
|
163
163
|
const u = await fetch('/voyager/api/feed/updates/' + encodeURIComponent(ACTIVITY) + '?commentsCount=0&likesCount=0', { credentials: 'include', headers: H });
|
|
164
164
|
if (!u.ok) return { ok: false, stage: 'resolve', httpStatus: u.status, error: (await u.text()).slice(0, 200) };
|
|
@@ -178,7 +178,7 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
178
178
|
}
|
|
179
179
|
// 2b. 纯转发 → GraphQL Reposts
|
|
180
180
|
const GH = Object.assign({}, H, { 'x-li-graphql-pegasus-client': 'true' });
|
|
181
|
-
const qid = ${JSON.stringify(
|
|
181
|
+
const qid = ${JSON.stringify(n)};
|
|
182
182
|
const r = await fetch('/voyager/api/graphql?action=execute&queryId=' + qid, {
|
|
183
183
|
method: 'POST', credentials: 'include', headers: GH,
|
|
184
184
|
body: JSON.stringify({ variables: { entity: { rootContentUrn: shareUrn } }, queryId: qid, includeWebMetadata: true }),
|
|
@@ -189,10 +189,10 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
189
189
|
const act = (rt.match(/urn:li:activity:[0-9]+/g) || [])[0] || '';
|
|
190
190
|
const rk = (rt.match(/urn:li:fsd_repost:[^"\\\\]+/) || [])[0] || '';
|
|
191
191
|
return { ok: true, quote: false, shared_urn: shareUrn, repost_urn: act || rk };
|
|
192
|
-
})()`}export function buildNotificationsScript({count:
|
|
192
|
+
})()`}export function buildNotificationsScript({count:e,start:t,filter:n}){return`(async () => {
|
|
193
193
|
${SOCIAL_PREAMBLE}
|
|
194
|
-
const url = '/voyager/api/voyagerIdentityDashNotificationCards?q=filterVanityName&filterVanityName=' + ${JSON.stringify(
|
|
195
|
-
+ '&count=' + ${JSON.stringify(
|
|
194
|
+
const url = '/voyager/api/voyagerIdentityDashNotificationCards?q=filterVanityName&filterVanityName=' + ${JSON.stringify(n)}
|
|
195
|
+
+ '&count=' + ${JSON.stringify(e)} + '&start=' + ${JSON.stringify(t)};
|
|
196
196
|
const res = await fetch(url, { credentials: 'include', headers: H });
|
|
197
197
|
if (!res.ok) return { ok: false, stage: 'read', httpStatus: res.status, error: (await res.text()).slice(0, 300) };
|
|
198
198
|
const j = await res.json();
|
|
@@ -212,10 +212,10 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const NORM_COMM
|
|
|
212
212
|
});
|
|
213
213
|
const meta = j.data && j.data.metadata;
|
|
214
214
|
return { ok: true, rows, numUnseen: (meta && meta.numUnseen) || 0, nextStart: (meta && meta.nextStart) || 0 };
|
|
215
|
-
})()`}export function buildFollowScript({target:
|
|
215
|
+
})()`}export function buildFollowScript({target:e,following:t}){return`(async () => {
|
|
216
216
|
${SOCIAL_PREAMBLE}
|
|
217
|
-
const TARGET = ${JSON.stringify(String(
|
|
218
|
-
const FOLLOWING = ${JSON.stringify(Boolean(
|
|
217
|
+
const TARGET = ${JSON.stringify(String(e||"").trim())};
|
|
218
|
+
const FOLLOWING = ${JSON.stringify(Boolean(t))};
|
|
219
219
|
|
|
220
220
|
async function resolveEntityUrn() {
|
|
221
221
|
// 1. 原生 urn 直接用
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as c,Strategy as u}from"@jackwener/opencli/registry";import{AuthRequiredError as m,CommandExecutionError as r,EmptyResultError as l}from"@jackwener/opencli/errors";import{unwrapEvaluateResult as d}from"./shared.js";function p(t){return`(async () => {
|
|
2
2
|
const norm = (s) => String(s == null ? '' : s).replace(/[ ]+/g, ' ').replace(/\\s+/g, ' ').trim();
|
|
3
3
|
const csrf = ((document.cookie.split('; ').find((c) => c.startsWith('JSESSIONID=')) || '').split('=')[1] || '').replace(/^"|"$/g, '');
|
|
4
4
|
if (!csrf) return { ok: false, auth: true };
|
|
5
|
-
const res = await fetch('/voyager/api/voyagerFeedDashMainFeed?q=mainFeed&count=' + ${
|
|
5
|
+
const res = await fetch('/voyager/api/voyagerFeedDashMainFeed?q=mainFeed&count=' + ${t}, { credentials: 'include', headers: {
|
|
6
6
|
'csrf-token': csrf,
|
|
7
7
|
'accept': 'application/vnd.linkedin.normalized+json+2.1',
|
|
8
8
|
'x-restli-protocol-version': '2.0.0',
|
|
@@ -34,4 +34,4 @@ import{cli as L,Strategy as M}from"@jackwener/opencli/registry";import{AuthRequi
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
return { ok: true, posts };
|
|
37
|
-
})()`}
|
|
37
|
+
})()`}c({site:"linkedin",name:"timeline",access:"read",description:"Read LinkedIn home timeline posts via the Voyager feed API",domain:"www.linkedin.com",strategy:u.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:20,help:"Number of posts to return (max 50)"}],columns:["rank","author","author_url","headline","text","posted_at","reactions","comments","url"],func:async(t,s)=>{if(!t)throw new r("Browser session required for linkedin timeline");const n=Math.max(1,Math.min(s.limit??20,50));await t.goto("https://www.linkedin.com/feed/");await t.wait(2);const e=d(await t.evaluate(p(n)));if(e?.auth)throw new m("linkedin.com","LinkedIn timeline requires an active signed-in browser session");if(!e?.ok)throw new r(`LinkedIn timeline: feed API returned HTTP ${e?.status||"?"}`);const o=Array.isArray(e.posts)?e.posts:[];if(o.length===0)throw new l("linkedin timeline","The Voyager feed API returned no posts.");return o.slice(0,n).map((i,a)=>({rank:a+1,...i}))}});export const __test__={};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as E,Strategy as
|
|
1
|
+
import{cli as E,Strategy as N}from"@jackwener/opencli/registry";import{ArgumentError as m,AuthRequiredError as g,CommandExecutionError as s,EmptyResultError as A}from"@jackwener/opencli/errors";const c="www.linkedin.com",l=50;function d(e){return String(e??"").replace(/[ ]/g," ").replace(/\s+/g," ").trim()}function h(e){if(e===void 0||e===null||e==="")return 10;const n=Number(e);if(!Number.isInteger(n)||n<1||n>l)throw new m(`--limit must be an integer between 1 and ${l}`);return n}function C(e){if(e&&typeof e==="object"&&"data"in e&&"session"in e)return e.data;return e}function p(e,n){return String.raw`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
const res = await fetch(${JSON.stringify(e)}, {
|
|
4
4
|
credentials: 'include',
|
|
@@ -14,4 +14,4 @@ import{cli as E,Strategy as C}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
14
14
|
} catch (e) {
|
|
15
15
|
return { error: 'fetch failed: ' + ((e && e.message) || String(e)) };
|
|
16
16
|
}
|
|
17
|
-
})()`}function
|
|
17
|
+
})()`}function y(e){if(!Array.isArray(e))return"";return e.map((n)=>d((n?.firstName??"")+" "+(n?.lastName??""))).filter(Boolean).join(", ")}function k(e){const n=e?.["com.linkedin.common.TimeSpan"];if(!n||n.unit!=="SECOND")return"";return String(n.duration??"")}function S(e){if(!e)return"";if(typeof e.averageRating==="number")return e.averageRating.toFixed(2);if(typeof e.ratingSum==="number"&&typeof e.ratingCount==="number"&&e.ratingCount>0)return(e.ratingSum/e.ratingCount).toFixed(2);return""}function I(e,n){const r=e?.entityType||"",t=e?.slug||"";if(!t)return null;return{rank:n,type:r,title:e?.headline?.title?.text||"",instructor:y(e?.authors),difficulty:e?.difficultyLevel||"",duration_sec:k(e?.length),rating:S(e?.rating),rating_count:e?.rating?.ratingCount??"",viewers:e?.viewerCount??"",url:t?`https://www.linkedin.com/learning/${t}`:""}}E({site:"linkedin-learning",name:"search",access:"read",description:"Search LinkedIn Learning courses, videos, and learning paths by keyword",domain:c,strategy:N.COOKIE,browser:!0,args:[{name:"keywords",type:"string",required:!0,positional:!0,help:'Search keywords, e.g. "AI agent"'},{name:"limit",type:"int",default:10,help:`Maximum results to return (1-${l})`}],columns:["rank","type","title","instructor","difficulty","duration_sec","rating","rating_count","viewers","url"],func:async(e,n)=>{if(!e)throw new s("Browser session required for linkedin-learning search");const r=d(n.keywords);if(!r)throw new m("--keywords is required");const t=h(n.limit);await e.goto("https://www.linkedin.com/learning/");await e.wait(3);const f=(await e.getCookies({url:"https://www.linkedin.com"})).find((u)=>u.name==="JSESSIONID")?.value;if(!f)throw new g(c,"LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.");const L=f.replace(/^"|"$/g,""),b=`https://www.linkedin.com/learning-api/searchV2?keywords=${encodeURIComponent(r)}&q=keywords`,i=C(await e.evaluate(p(b,L)));if(i?.authRequired)throw new g(c,`LinkedIn Learning auth failed (HTTP ${i.status??""}).`);if(!i?.json)throw new s(`LinkedIn Learning searchV2 failed: ${i?.error??"no payload"}`);const a=i.json?.elements;if(!Array.isArray(a))throw new s("LinkedIn Learning searchV2 returned malformed payload: missing elements array");if(a.length===0)throw new A(`No LinkedIn Learning results for "${r}"`);const o=[];for(const u of a){if(o.length>=t)break;const w=I(u,o.length+1);if(w)o.push(w)}if(o.length===0)throw new s("LinkedIn Learning searchV2 returned no parseable rows with slug identity");return o}});export const __test__={normalizeWhitespace:d,parseLimit:h,parseAuthors:y,durationSeconds:k,averageRating:S,parseRow:I,buildFetchScript:p};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as R,Strategy as
|
|
1
|
+
import{cli as R,Strategy as x}from"@jackwener/opencli/registry";import{ArgumentError as C,AuthRequiredError as y,CommandExecutionError as a,EmptyResultError as N}from"@jackwener/opencli/errors";const c="www.linkedin.com",d=50,O=25;function L(e){if(e===void 0||e===null||e==="")return 10;const n=Number(e);if(!Number.isInteger(n)||n<1||n>d)throw new C(`--limit must be an integer between 1 and ${d}`);return n}function j(e){if(e&&typeof e==="object"&&"data"in e&&"session"in e)return e.data;return e}function _(e,n){return String.raw`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
const res = await fetch(${JSON.stringify(e)}, {
|
|
4
4
|
credentials: 'include',
|
|
@@ -14,4 +14,4 @@ import{cli as R,Strategy as $}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
14
14
|
} catch (e) {
|
|
15
15
|
return { error: 'fetch failed: ' + ((e && e.message) || String(e)) };
|
|
16
16
|
}
|
|
17
|
-
})()`}function I(e,n,r){const s=e?.slug||"";if(!s)return null;return{rank:r,group:n?.title?.text||n?.annotation||"",type:e?.entityType||e?.localizedEntityName||"",title:e?.title?.text||e?.headline?.title?.text||e?.headline?.text||"",difficulty:e?.difficultyLevel||"",viewers:e?.viewerCount??"",url:s?`https://www.linkedin.com/learning/${s}`:""}}R({site:"linkedin-learning",name:"trending",access:"read",description:"Browse LinkedIn Learning recommended courses across personalized carousels",domain:c,strategy
|
|
17
|
+
})()`}function I(e,n,r){const s=e?.slug||"";if(!s)return null;return{rank:r,group:n?.title?.text||n?.annotation||"",type:e?.entityType||e?.localizedEntityName||"",title:e?.title?.text||e?.headline?.title?.text||e?.headline?.text||"",difficulty:e?.difficultyLevel||"",viewers:e?.viewerCount??"",url:s?`https://www.linkedin.com/learning/${s}`:""}}R({site:"linkedin-learning",name:"trending",access:"read",description:"Browse LinkedIn Learning recommended courses across personalized carousels",domain:c,strategy:x.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:10,help:`Maximum results to return (1-${d})`}],columns:["rank","group","type","title","difficulty","viewers","url"],func:async(e,n)=>{if(!e)throw new a("Browser session required for linkedin-learning trending");const r=L(n.limit);await e.goto("https://www.linkedin.com/learning/");await e.wait(3);const f=(await e.getCookies({url:"https://www.linkedin.com"})).find((o)=>o.name==="JSESSIONID")?.value;if(!f)throw new y(c,"LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.");const S=f.replace(/^"|"$/g,""),E=`https://www.linkedin.com/learning-api/feedRecommendationGroups?countPerCarousel=${O}&q=learner`,i=j(await e.evaluate(_(E,S)));if(i?.authRequired)throw new y(c,`LinkedIn Learning auth failed (HTTP ${i.status??""}).`);if(!i?.json)throw new a(`LinkedIn Learning feedRecommendationGroups failed: ${i?.error??"no payload"}`);const w=i.json?.elements;if(!Array.isArray(w))throw new a("LinkedIn Learning feedRecommendationGroups returned malformed payload: missing elements array");const t=[],m=new Set;let g=1,h=!1;for(const o of w){const b=Array.isArray(o?.carousels)?o.carousels:[];for(const u of b){const A=Array.isArray(u?.cards)?u.cards:[];for(const p of A){h=!0;if(t.length>=r)break;const l=p?.slug;if(!l||m.has(l))continue;m.add(l);const k=I(p,u,g);if(!k)continue;t.push(k);g+=1}if(t.length>=r)break}if(t.length>=r)break}if(t.length===0){if(h)throw new a("LinkedIn Learning feedRecommendationGroups returned no parseable cards with slug identity");throw new N("LinkedIn Learning returned no personalized recommendations")}return t}});export const __test__={parseLimit:L,parseCard:I};
|