publishport-opencli 1.0.20 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1041) hide show
  1. package/clis/12306/me.js +2 -2
  2. package/clis/12306/orders.js +3 -3
  3. package/clis/12306/passengers.js +3 -3
  4. package/clis/12306/price.js +1 -1
  5. package/clis/12306/stations.js +1 -1
  6. package/clis/12306/train.js +1 -1
  7. package/clis/12306/trains.js +1 -1
  8. package/clis/12306/utils.js +1 -1
  9. package/clis/1688/download.js +1 -1
  10. package/clis/1688/item.js +4 -4
  11. package/clis/1688/search.js +4 -4
  12. package/clis/1688/store.js +4 -4
  13. package/clis/1point3acres/forum.js +1 -1
  14. package/clis/1point3acres/forums.js +1 -1
  15. package/clis/1point3acres/notifications.js +1 -1
  16. package/clis/1point3acres/search.js +1 -1
  17. package/clis/1point3acres/thread.js +2 -2
  18. package/clis/1point3acres/user.js +1 -1
  19. package/clis/1point3acres/utils.js +2 -2
  20. package/clis/36kr/article.js +2 -2
  21. package/clis/36kr/hot.js +2 -2
  22. package/clis/36kr/news.js +1 -1
  23. package/clis/36kr/search.js +2 -2
  24. package/clis/51job/company.js +2 -2
  25. package/clis/51job/detail.js +2 -2
  26. package/clis/51job/hot.js +1 -1
  27. package/clis/51job/search.js +1 -1
  28. package/clis/51job/utils.js +7 -7
  29. package/clis/_atlassian/shared.js +9 -9
  30. package/clis/_shared/article/auth.js +4 -4
  31. package/clis/_shared/article/douban-md2draft.js +4 -4
  32. package/clis/_shared/article/format.js +1 -1
  33. package/clis/_shared/article/images.js +7 -7
  34. package/clis/_shared/article/login.js +1 -1
  35. package/clis/_shared/article/publish.js +11 -11
  36. package/clis/_shared/common.js +1 -1
  37. package/clis/_shared/content-guard.js +1 -1
  38. package/clis/_shared/desktop-commands.js +1 -1
  39. package/clis/_shared/file-inject.js +12 -12
  40. package/clis/_shared/self-hosted-sites.js +2 -2
  41. package/clis/_shared/site-auth.js +1 -1
  42. package/clis/_shared/token-auth.js +2 -2
  43. package/clis/_shared/video-publish.js +9 -9
  44. package/clis/amazon/offer.js +3 -3
  45. package/clis/amazon/product.js +5 -5
  46. package/clis/amazon/shared.js +6 -6
  47. package/clis/antigravity/_actions.js +13 -13
  48. package/clis/antigravity/audit-extras.js +10 -10
  49. package/clis/antigravity/delete.js +1 -1
  50. package/clis/antigravity/model.js +6 -6
  51. package/clis/antigravity/new.js +2 -2
  52. package/clis/antigravity/read.js +2 -2
  53. package/clis/antigravity/rename.js +1 -1
  54. package/clis/antigravity/send.js +3 -3
  55. package/clis/antigravity/serve.js +17 -17
  56. package/clis/antigravity/storage.js +6 -6
  57. package/clis/antigravity/watch.js +2 -2
  58. package/clis/apple-podcasts/episodes.js +1 -1
  59. package/clis/apple-podcasts/top.js +1 -1
  60. package/clis/apple-podcasts/utils.js +1 -1
  61. package/clis/archive/item.js +1 -1
  62. package/clis/archive/search.js +1 -1
  63. package/clis/archive/snapshots.js +1 -1
  64. package/clis/archive/wayback.js +1 -1
  65. package/clis/arxiv/author.js +1 -1
  66. package/clis/arxiv/utils.js +1 -1
  67. package/clis/autohome/brand.js +1 -1
  68. package/clis/autohome/score.js +1 -1
  69. package/clis/autohome/utils.js +1 -1
  70. package/clis/baijiahao/article.js +1 -1
  71. package/clis/baijiahao/lists.js +1 -1
  72. package/clis/baijiahao/login.js +1 -1
  73. package/clis/baijiahao/publish.js +9 -9
  74. package/clis/baijiahao/stats.js +1 -1
  75. package/clis/baijiahao/whoami.js +1 -1
  76. package/clis/band/bands.js +2 -2
  77. package/clis/band/mentions.js +2 -2
  78. package/clis/band/post.js +4 -4
  79. package/clis/band/posts.js +3 -3
  80. package/clis/barchart/flow.js +3 -3
  81. package/clis/barchart/greeks.js +2 -2
  82. package/clis/barchart/quote.js +3 -3
  83. package/clis/bbc/news.js +1 -1
  84. package/clis/bbc/topic.js +1 -1
  85. package/clis/bbc/utils.js +1 -1
  86. package/clis/bilibili/article.js +1 -1
  87. package/clis/bilibili/categories.js +1 -1
  88. package/clis/bilibili/coin.js +1 -1
  89. package/clis/bilibili/comment-del.js +1 -1
  90. package/clis/bilibili/comment-like.js +1 -1
  91. package/clis/bilibili/comment.js +1 -1
  92. package/clis/bilibili/comments.js +1 -1
  93. package/clis/bilibili/dm-list.js +1 -1
  94. package/clis/bilibili/dm-read.js +1 -1
  95. package/clis/bilibili/dm-send.js +1 -1
  96. package/clis/bilibili/download.js +2 -2
  97. package/clis/bilibili/drafts.js +1 -1
  98. package/clis/bilibili/dynamic-post.js +3 -3
  99. package/clis/bilibili/favorite-add.js +1 -1
  100. package/clis/bilibili/favorite.js +1 -1
  101. package/clis/bilibili/feed.js +2 -2
  102. package/clis/bilibili/follow.js +1 -1
  103. package/clis/bilibili/following.js +1 -1
  104. package/clis/bilibili/like.js +1 -1
  105. package/clis/bilibili/partitions.js +1 -1
  106. package/clis/bilibili/stats.js +1 -1
  107. package/clis/bilibili/subtitle.js +3 -3
  108. package/clis/bilibili/summary.js +1 -1
  109. package/clis/bilibili/topics.js +1 -1
  110. package/clis/bilibili/unfollow.js +1 -1
  111. package/clis/bilibili/upload.js +1 -1
  112. package/clis/bilibili/utils.js +10 -10
  113. package/clis/bilibili/video-drafts.js +1 -1
  114. package/clis/bilibili/video.js +1 -1
  115. package/clis/bloomberg/businessweek.js +4 -4
  116. package/clis/bloomberg/news.js +2 -2
  117. package/clis/bloomberg/utils.js +13 -13
  118. package/clis/bluesky/post.js +1 -1
  119. package/clis/bluesky/shared.js +11 -11
  120. package/clis/bluesky/whoami.js +1 -1
  121. package/clis/booking/search.js +2 -2
  122. package/clis/boss/accept.js +1 -1
  123. package/clis/boss/applied.js +1 -1
  124. package/clis/boss/auth.js +1 -1
  125. package/clis/boss/batchgreet.js +1 -1
  126. package/clis/boss/bossinfo.js +1 -1
  127. package/clis/boss/chatlist.js +1 -1
  128. package/clis/boss/chatmsg.js +1 -1
  129. package/clis/boss/cities.js +1 -1
  130. package/clis/boss/detail.js +1 -1
  131. package/clis/boss/exchange.js +1 -1
  132. package/clis/boss/greet.js +1 -1
  133. package/clis/boss/interviews.js +1 -1
  134. package/clis/boss/invite.js +1 -1
  135. package/clis/boss/joblist.js +1 -1
  136. package/clis/boss/mark.js +1 -1
  137. package/clis/boss/me.js +2 -2
  138. package/clis/boss/recommend.js +1 -1
  139. package/clis/boss/resumedelete.js +1 -1
  140. package/clis/boss/resumelist.js +1 -1
  141. package/clis/boss/resumeupload.js +11 -11
  142. package/clis/boss/search.js +1 -1
  143. package/clis/boss/send.js +1 -1
  144. package/clis/boss/sendresume.js +1 -1
  145. package/clis/boss/stats.js +1 -1
  146. package/clis/boss/unread.js +1 -1
  147. package/clis/boss/utils.js +13 -13
  148. package/clis/chaoxing/assignments.js +1 -1
  149. package/clis/chaoxing/exams.js +1 -1
  150. package/clis/chaoxing/utils.js +9 -9
  151. package/clis/chatgpt/ask.js +1 -1
  152. package/clis/chatgpt/auth.js +2 -2
  153. package/clis/chatgpt/detail.js +1 -1
  154. package/clis/chatgpt/image.js +1 -1
  155. package/clis/chatgpt/read.js +1 -1
  156. package/clis/chatgpt/send.js +1 -1
  157. package/clis/chatgpt/utils.js +59 -59
  158. package/clis/chatgpt-app/ask.js +1 -1
  159. package/clis/chatgpt-app/send.js +1 -1
  160. package/clis/chatwise/model.js +6 -6
  161. package/clis/chess/analyze.js +1 -1
  162. package/clis/chess/game.js +1 -1
  163. package/clis/chess/games.js +1 -1
  164. package/clis/chess/stats.js +1 -1
  165. package/clis/chess/utils.js +1 -1
  166. package/clis/claude/ask.js +2 -2
  167. package/clis/claude/detail.js +1 -1
  168. package/clis/claude/new.js +1 -1
  169. package/clis/claude/read.js +1 -1
  170. package/clis/claude/send.js +1 -1
  171. package/clis/claude/utils.js +23 -23
  172. package/clis/cnblogs/article.js +1 -1
  173. package/clis/cnblogs/login.js +1 -1
  174. package/clis/cnblogs/stats.js +7 -7
  175. package/clis/cnblogs/whoami.js +1 -1
  176. package/clis/codex/_actions.js +3 -3
  177. package/clis/codex/archive.js +1 -1
  178. package/clis/codex/ask.js +6 -6
  179. package/clis/codex/model.js +8 -8
  180. package/clis/codex/pin.js +1 -1
  181. package/clis/codex/rename.js +4 -4
  182. package/clis/codex/send.js +3 -3
  183. package/clis/codex/sidebar.js +1 -1
  184. package/clis/coingecko/categories.js +1 -1
  185. package/clis/coingecko/coin.js +1 -1
  186. package/clis/coingecko/derivatives.js +1 -1
  187. package/clis/coingecko/exchanges.js +1 -1
  188. package/clis/coingecko/global.js +1 -1
  189. package/clis/coingecko/trending.js +1 -1
  190. package/clis/confluence/search.js +1 -1
  191. package/clis/coupang/product.js +3 -3
  192. package/clis/coupang/utils.js +1 -1
  193. package/clis/crates/crate.js +1 -1
  194. package/clis/crates/search.js +1 -1
  195. package/clis/crates/utils.js +1 -1
  196. package/clis/csdn/article.js +13 -13
  197. package/clis/csdn/columns.js +1 -1
  198. package/clis/csdn/login.js +1 -1
  199. package/clis/csdn/stats.js +4 -4
  200. package/clis/csdn/whoami.js +1 -1
  201. package/clis/cto51/article.js +1 -1
  202. package/clis/cto51/whoami.js +1 -1
  203. package/clis/ctrip/flight.js +2 -2
  204. package/clis/ctrip/hotel-search.js +3 -3
  205. package/clis/ctrip/hotel-suggest.js +1 -1
  206. package/clis/ctrip/search.js +1 -1
  207. package/clis/ctrip/utils.js +6 -6
  208. package/clis/cursor/ask.js +5 -5
  209. package/clis/cursor/composer.js +2 -2
  210. package/clis/cursor/model.js +4 -4
  211. package/clis/cursor/send.js +2 -2
  212. package/clis/dblp/author.js +1 -1
  213. package/clis/dblp/paper.js +1 -1
  214. package/clis/dblp/search.js +1 -1
  215. package/clis/dblp/utils.js +1 -1
  216. package/clis/dblp/venue.js +1 -1
  217. package/clis/deepseek/ask.js +1 -1
  218. package/clis/deepseek/auth.js +2 -2
  219. package/clis/deepseek/detail.js +1 -1
  220. package/clis/deepseek/new.js +1 -1
  221. package/clis/deepseek/read.js +1 -1
  222. package/clis/deepseek/send.js +7 -7
  223. package/clis/deepseek/utils.js +25 -25
  224. package/clis/defillama/protocol.js +1 -1
  225. package/clis/defillama/protocols.js +1 -1
  226. package/clis/defillama/utils.js +1 -1
  227. package/clis/devto/auth.js +2 -2
  228. package/clis/devto/latest.js +1 -1
  229. package/clis/devto/publish.js +5 -5
  230. package/clis/devto/read.js +2 -2
  231. package/clis/devto/stats.js +3 -3
  232. package/clis/dianping/auth.js +2 -2
  233. package/clis/dianping/cityResolver.js +2 -2
  234. package/clis/dianping/search.js +1 -1
  235. package/clis/dianping/shop.js +1 -1
  236. package/clis/dianping/utils.js +1 -1
  237. package/clis/discord-app/delete.js +3 -3
  238. package/clis/discord-app/read.js +1 -1
  239. package/clis/discord-app/thread-read.js +1 -1
  240. package/clis/discord-web/auth.js +2 -2
  241. package/clis/discord-web/send.js +5 -5
  242. package/clis/dockerhub/image.js +1 -1
  243. package/clis/dockerhub/search.js +1 -1
  244. package/clis/dockerhub/utils.js +1 -1
  245. package/clis/dongchedi/koubei.js +1 -1
  246. package/clis/dongchedi/models.js +1 -1
  247. package/clis/dongchedi/score.js +1 -1
  248. package/clis/dongchedi/search.js +1 -1
  249. package/clis/dongchedi/series.js +1 -1
  250. package/clis/dongchedi/specs.js +1 -1
  251. package/clis/dongchedi/utils.js +1 -1
  252. package/clis/douban/article.js +3 -3
  253. package/clis/douban/auth.js +2 -2
  254. package/clis/douban/download.js +1 -1
  255. package/clis/douban/utils.js +23 -23
  256. package/clis/doubao/auth.js +3 -3
  257. package/clis/doubao/utils.js +39 -39
  258. package/clis/doubao-app/ask.js +1 -1
  259. package/clis/doubao-app/utils.js +4 -4
  260. package/clis/douyin/_shared/browser-fetch.js +7 -7
  261. package/clis/douyin/_shared/draft-cache.js +1 -1
  262. package/clis/douyin/_shared/imagex-upload.js +1 -1
  263. package/clis/douyin/_shared/sts2.js +1 -1
  264. package/clis/douyin/_shared/text-extra.js +1 -1
  265. package/clis/douyin/_shared/tos-upload.js +4 -4
  266. package/clis/douyin/_shared/transcode.js +1 -1
  267. package/clis/douyin/_shared/vod-upload.js +4 -4
  268. package/clis/douyin/draft.js +18 -18
  269. package/clis/douyin/drafts.js +1 -1
  270. package/clis/douyin/publish-image.js +12 -12
  271. package/clis/douyin/publish.js +9 -9
  272. package/clis/douyin/search.js +3 -3
  273. package/clis/douyin/videos.js +1 -1
  274. package/clis/eastmoney/_secid.js +1 -1
  275. package/clis/eastmoney/announcement.js +1 -1
  276. package/clis/eastmoney/article.js +1 -1
  277. package/clis/eastmoney/convertible.js +1 -1
  278. package/clis/eastmoney/etf.js +1 -1
  279. package/clis/eastmoney/holders.js +1 -1
  280. package/clis/eastmoney/index-board.js +1 -1
  281. package/clis/eastmoney/kline.js +1 -1
  282. package/clis/eastmoney/kuaixun.js +1 -1
  283. package/clis/eastmoney/longhu.js +1 -1
  284. package/clis/eastmoney/money-flow.js +1 -1
  285. package/clis/eastmoney/northbound.js +1 -1
  286. package/clis/eastmoney/quote.js +1 -1
  287. package/clis/eastmoney/rank.js +1 -1
  288. package/clis/eastmoney/sectors.js +1 -1
  289. package/clis/endoflife/product.js +1 -1
  290. package/clis/endoflife/utils.js +1 -1
  291. package/clis/facebook/comment.js +8 -8
  292. package/clis/facebook/feed.js +4 -4
  293. package/clis/facebook/like.js +5 -5
  294. package/clis/facebook/notifications.js +3 -3
  295. package/clis/facebook/post.js +11 -11
  296. package/clis/facebook/search.js +3 -3
  297. package/clis/flathub/app.js +1 -1
  298. package/clis/flathub/search.js +1 -1
  299. package/clis/flathub/utils.js +1 -1
  300. package/clis/flomo/memos.js +1 -1
  301. package/clis/gemini/deep-research-result.js +4 -4
  302. package/clis/gemini/deep-research.js +1 -1
  303. package/clis/gemini/detail.js +1 -1
  304. package/clis/gemini/history.js +1 -1
  305. package/clis/gemini/image.js +2 -2
  306. package/clis/gemini/status.js +1 -1
  307. package/clis/gemini/utils.js +43 -43
  308. package/clis/geogebra/hexagon.js +1 -1
  309. package/clis/geogebra/info.js +3 -3
  310. package/clis/geogebra/triangle.js +1 -1
  311. package/clis/geogebra/utils.js +11 -11
  312. package/clis/ghost/login.js +1 -1
  313. package/clis/ghost/shared.js +2 -2
  314. package/clis/gitee/auth.js +2 -2
  315. package/clis/github-trending/repos.js +1 -1
  316. package/clis/google/news.js +1 -1
  317. package/clis/google/search.js +2 -2
  318. package/clis/google/suggest.js +1 -1
  319. package/clis/google/trends.js +1 -1
  320. package/clis/google/utils.js +1 -1
  321. package/clis/goproxy/module.js +1 -1
  322. package/clis/goproxy/utils.js +1 -1
  323. package/clis/goproxy/versions.js +1 -1
  324. package/clis/gov-policy/recent.js +2 -2
  325. package/clis/gov-policy/search.js +2 -2
  326. package/clis/grok/ask.js +1 -1
  327. package/clis/grok/detail.js +1 -1
  328. package/clis/grok/image.js +8 -8
  329. package/clis/grok/pin.js +1 -1
  330. package/clis/grok/send.js +1 -1
  331. package/clis/grok/status.js +1 -1
  332. package/clis/grok/utils.js +21 -21
  333. package/clis/guazi/browse.js +1 -1
  334. package/clis/guazi/car.js +1 -1
  335. package/clis/guazi/utils.js +1 -1
  336. package/clis/hackernews/auth.js +2 -2
  337. package/clis/hackernews/comment.js +8 -8
  338. package/clis/hackernews/read.js +7 -7
  339. package/clis/hackernews/submit.js +7 -7
  340. package/clis/hashnode/auth.js +3 -3
  341. package/clis/hashnode/publish.js +14 -14
  342. package/clis/hf/auth.js +2 -2
  343. package/clis/hf/models.js +1 -1
  344. package/clis/hf/paper.js +1 -1
  345. package/clis/hf/spaces.js +1 -1
  346. package/clis/hf/top.js +1 -1
  347. package/clis/homebrew/cask.js +1 -1
  348. package/clis/homebrew/formula.js +1 -1
  349. package/clis/homebrew/popular.js +1 -1
  350. package/clis/homebrew/utils.js +1 -1
  351. package/clis/huodongxing/events.js +1 -1
  352. package/clis/hupu/detail.js +4 -4
  353. package/clis/hupu/hot.js +3 -3
  354. package/clis/hupu/reply.js +1 -1
  355. package/clis/hupu/search.js +1 -1
  356. package/clis/hupu/unlike.js +1 -1
  357. package/clis/hupu/utils.js +10 -10
  358. package/clis/imdb/person.js +2 -2
  359. package/clis/imdb/reviews.js +3 -3
  360. package/clis/imdb/search.js +2 -2
  361. package/clis/imdb/title.js +1 -1
  362. package/clis/imdb/top.js +1 -1
  363. package/clis/imdb/trending.js +1 -1
  364. package/clis/imdb/utils.js +13 -13
  365. package/clis/imooc/article.js +6 -6
  366. package/clis/imooc/login.js +1 -1
  367. package/clis/imooc/whoami.js +1 -1
  368. package/clis/indeed/job.js +2 -2
  369. package/clis/indeed/search.js +2 -2
  370. package/clis/indeed/utils.js +1 -1
  371. package/clis/infoq/article.js +2 -2
  372. package/clis/infoq/login.js +1 -1
  373. package/clis/infoq/whoami.js +1 -1
  374. package/clis/instagram/_shared/private-publish.js +4 -4
  375. package/clis/instagram/_shared/protocol-capture.js +9 -9
  376. package/clis/instagram/detail.js +3 -3
  377. package/clis/instagram/post.js +25 -25
  378. package/clis/instagram/reel.js +18 -18
  379. package/clis/instagram/story.js +4 -4
  380. package/clis/instagram/user.js +2 -2
  381. package/clis/jd/item.js +65 -65
  382. package/clis/jianshu/article.js +1 -1
  383. package/clis/jianshu/login.js +1 -1
  384. package/clis/jianshu/notebooks.js +1 -1
  385. package/clis/jianshu/whoami.js +1 -1
  386. package/clis/jianyu/search.js +6 -6
  387. package/clis/jianyu/shared/procurement-contract.js +1 -1
  388. package/clis/jike/api.js +6 -6
  389. package/clis/jike/auth.js +3 -3
  390. package/clis/jike/comment.js +1 -1
  391. package/clis/jike/create.js +6 -6
  392. package/clis/jike/feed.js +3 -3
  393. package/clis/jike/like.js +1 -1
  394. package/clis/jike/notifications.js +3 -3
  395. package/clis/jike/repost.js +13 -13
  396. package/clis/jike/search.js +3 -3
  397. package/clis/jimeng/auth.js +2 -2
  398. package/clis/jimeng/generate.js +10 -10
  399. package/clis/jira/shared.js +1 -1
  400. package/clis/juejin/article.js +4 -4
  401. package/clis/juejin/categories.js +1 -1
  402. package/clis/juejin/hot.js +1 -1
  403. package/clis/juejin/login.js +1 -1
  404. package/clis/juejin/recommend.js +1 -1
  405. package/clis/juejin/stats.js +3 -3
  406. package/clis/juejin/tags.js +1 -1
  407. package/clis/juejin/utils.js +1 -1
  408. package/clis/juejin/whoami.js +1 -1
  409. package/clis/ke/utils.js +4 -4
  410. package/clis/kimi/_utils.js +7 -7
  411. package/clis/kimi/audit-extras.js +14 -14
  412. package/clis/kimi/auth.js +3 -3
  413. package/clis/kimi/chat.js +15 -15
  414. package/clis/kimi/storage.js +5 -5
  415. package/clis/kimi/ui.js +13 -13
  416. package/clis/kimi/usage.js +3 -3
  417. package/clis/kuaishou/auth.js +1 -1
  418. package/clis/kuaishou/publish.js +6 -6
  419. package/clis/lesswrong/_helpers.js +5 -5
  420. package/clis/lesswrong/comments.js +5 -5
  421. package/clis/lichess/top.js +1 -1
  422. package/clis/lichess/user.js +1 -1
  423. package/clis/lichess/utils.js +1 -1
  424. package/clis/linkedin/comment.js +1 -1
  425. package/clis/linkedin/connect.js +11 -11
  426. package/clis/linkedin/create.js +5 -5
  427. package/clis/linkedin/follow.js +1 -1
  428. package/clis/linkedin/inbox.js +1 -1
  429. package/clis/linkedin/job-detail.js +3 -3
  430. package/clis/linkedin/like.js +1 -1
  431. package/clis/linkedin/notifications.js +1 -1
  432. package/clis/linkedin/people-search.js +1 -1
  433. package/clis/linkedin/post-comments.js +1 -1
  434. package/clis/linkedin/post-detail.js +1 -1
  435. package/clis/linkedin/profile-analytics.js +1 -1
  436. package/clis/linkedin/profile-api.js +13 -13
  437. package/clis/linkedin/profile-experience.js +1 -1
  438. package/clis/linkedin/profile-projects.js +1 -1
  439. package/clis/linkedin/profile-read.js +3 -3
  440. package/clis/linkedin/reply.js +1 -1
  441. package/clis/linkedin/repost.js +1 -1
  442. package/clis/linkedin/safe-send.js +8 -8
  443. package/clis/linkedin/salesnav-inbox.js +5 -5
  444. package/clis/linkedin/salesnav-message.js +3 -3
  445. package/clis/linkedin/salesnav-search.js +4 -4
  446. package/clis/linkedin/salesnav-thread.js +1 -1
  447. package/clis/linkedin/search-api.js +3 -3
  448. package/clis/linkedin/search.js +8 -8
  449. package/clis/linkedin/social-api.js +31 -31
  450. package/clis/linkedin/timeline.js +3 -3
  451. package/clis/linkedin-learning/search.js +2 -2
  452. package/clis/linkedin-learning/trending.js +2 -2
  453. package/clis/linux-do/feed.js +4 -4
  454. package/clis/linux-do/topic-content.js +8 -8
  455. package/clis/lobsters/domain.js +1 -1
  456. package/clis/lobsters/read.js +7 -7
  457. package/clis/maimai/auth.js +2 -2
  458. package/clis/maimai/search-talents.js +4 -4
  459. package/clis/manus/_utils.js +1 -1
  460. package/clis/mastodon/login.js +1 -1
  461. package/clis/mastodon/post.js +1 -1
  462. package/clis/mastodon/shared.js +12 -12
  463. package/clis/mastodon/whoami.js +1 -1
  464. package/clis/maven/artifact.js +1 -1
  465. package/clis/maven/search.js +1 -1
  466. package/clis/maven/utils.js +1 -1
  467. package/clis/mdn/search.js +1 -1
  468. package/clis/medium/article.js +5 -5
  469. package/clis/medium/login.js +1 -1
  470. package/clis/medium/stats.js +3 -3
  471. package/clis/medium/tag.js +1 -1
  472. package/clis/medium/whoami.js +1 -1
  473. package/clis/mubu/notes.js +1 -1
  474. package/clis/mubu/utils.js +15 -15
  475. package/clis/note/auth.js +2 -2
  476. package/clis/note/note-utils.js +2 -2
  477. package/clis/note/publish.js +8 -8
  478. package/clis/notebooklm/add-source.js +8 -8
  479. package/clis/notebooklm/create.js +1 -1
  480. package/clis/notebooklm/generate-slides.js +1 -1
  481. package/clis/notebooklm/notes-get.js +1 -1
  482. package/clis/notebooklm/rpc.js +8 -8
  483. package/clis/notebooklm/source-fulltext.js +1 -1
  484. package/clis/notebooklm/utils.js +10 -10
  485. package/clis/nowcoder/auth.js +2 -2
  486. package/clis/nowcoder/comment.js +1 -1
  487. package/clis/nowcoder/comments.js +1 -1
  488. package/clis/nowcoder/dm-list.js +1 -1
  489. package/clis/nowcoder/dm-read.js +1 -1
  490. package/clis/nowcoder/dm-send.js +1 -1
  491. package/clis/nowcoder/drafts.js +1 -1
  492. package/clis/nowcoder/inbox.js +1 -1
  493. package/clis/nowcoder/like.js +1 -1
  494. package/clis/nowcoder/my.js +1 -1
  495. package/clis/nowcoder/post.js +1 -1
  496. package/clis/nowcoder/utils.js +13 -13
  497. package/clis/npm/downloads.js +1 -1
  498. package/clis/npm/package.js +1 -1
  499. package/clis/npm/search.js +1 -1
  500. package/clis/npm/utils.js +1 -1
  501. package/clis/nuget/package.js +1 -1
  502. package/clis/nuget/search.js +1 -1
  503. package/clis/nuget/utils.js +1 -1
  504. package/clis/nvd/cve.js +1 -1
  505. package/clis/oeis/search.js +1 -1
  506. package/clis/oeis/sequence.js +1 -1
  507. package/clis/oeis/utils.js +1 -1
  508. package/clis/ones/common.js +6 -6
  509. package/clis/ones/enrich-tasks.js +1 -1
  510. package/clis/ones/my-tasks.js +1 -1
  511. package/clis/ones/resolve-labels.js +1 -1
  512. package/clis/ones/task-helpers.js +1 -1
  513. package/clis/ones/task.js +1 -1
  514. package/clis/ones/worklog.js +7 -7
  515. package/clis/openalex/search.js +1 -1
  516. package/clis/openalex/utils.js +1 -1
  517. package/clis/openalex/work.js +1 -1
  518. package/clis/openfda/drug-label.js +1 -1
  519. package/clis/openfda/food-recall.js +1 -1
  520. package/clis/openfda/utils.js +1 -1
  521. package/clis/openreview/author.js +1 -1
  522. package/clis/openreview/paper.js +1 -1
  523. package/clis/openreview/reviews.js +3 -3
  524. package/clis/openreview/search.js +1 -1
  525. package/clis/openreview/utils.js +1 -1
  526. package/clis/openreview/venue.js +1 -1
  527. package/clis/oschina/article.js +1 -1
  528. package/clis/oschina/catalogs.js +1 -1
  529. package/clis/oschina/login.js +1 -1
  530. package/clis/oschina/stats.js +6 -6
  531. package/clis/oschina/whoami.js +1 -1
  532. package/clis/osv/query.js +1 -1
  533. package/clis/osv/utils.js +1 -1
  534. package/clis/osv/vulnerability.js +1 -1
  535. package/clis/packagist/package.js +1 -1
  536. package/clis/packagist/search.js +1 -1
  537. package/clis/packagist/utils.js +1 -1
  538. package/clis/pinterest/api.js +1 -1
  539. package/clis/pinterest/auth.js +1 -1
  540. package/clis/pinterest/boards.js +1 -1
  541. package/clis/pinterest/client.js +6 -6
  542. package/clis/pinterest/publish.js +5 -5
  543. package/clis/pixiv/auth.js +2 -2
  544. package/clis/pixiv/download.js +1 -1
  545. package/clis/pixiv/illusts.js +1 -1
  546. package/clis/pixiv/search.js +1 -1
  547. package/clis/pixiv/utils.js +3 -3
  548. package/clis/powerchina/auth.js +2 -2
  549. package/clis/powerchina/search.js +1 -1
  550. package/clis/producthunt/browse.js +2 -2
  551. package/clis/producthunt/hot.js +2 -2
  552. package/clis/producthunt/posts.js +1 -1
  553. package/clis/producthunt/today.js +1 -1
  554. package/clis/producthunt/utils.js +1 -1
  555. package/clis/pypi/downloads.js +1 -1
  556. package/clis/pypi/package.js +1 -1
  557. package/clis/pypi/utils.js +1 -1
  558. package/clis/qiita/auth.js +1 -1
  559. package/clis/qiita/gql.js +6 -6
  560. package/clis/qiita/publish.js +4 -4
  561. package/clis/qiita/stats.js +4 -4
  562. package/clis/qoder/_utils.js +16 -16
  563. package/clis/qoder/composer.js +1 -1
  564. package/clis/qoder/quest.js +1 -1
  565. package/clis/qoder/ui.js +14 -14
  566. package/clis/quark/auth.js +2 -2
  567. package/clis/quark/utils.js +2 -2
  568. package/clis/quora/answer-comments.js +3 -3
  569. package/clis/quora/create-answer.js +4 -4
  570. package/clis/quora/create-question.js +3 -3
  571. package/clis/quora/shared.js +17 -17
  572. package/clis/quora/whoami.js +1 -1
  573. package/clis/qwen/ask.js +1 -1
  574. package/clis/qwen/auth.js +3 -3
  575. package/clis/qwen/detail.js +1 -1
  576. package/clis/qwen/image.js +5 -5
  577. package/clis/qwen/status.js +1 -1
  578. package/clis/qwen/utils.js +16 -16
  579. package/clis/reddit/home.js +3 -3
  580. package/clis/reddit/read.js +10 -10
  581. package/clis/reddit/reply.js +4 -4
  582. package/clis/reddit/submit.js +11 -11
  583. package/clis/reddit/subreddit-info.js +3 -3
  584. package/clis/reddit/subscribed.js +4 -4
  585. package/clis/reddit/whoami.js +2 -2
  586. package/clis/rednote/comments.js +1 -1
  587. package/clis/rednote/download.js +1 -1
  588. package/clis/rednote/feed.js +1 -1
  589. package/clis/rednote/note.js +1 -1
  590. package/clis/rednote/notifications.js +2 -2
  591. package/clis/rednote/search.js +2 -2
  592. package/clis/rest-countries/country.js +1 -1
  593. package/clis/rest-countries/region.js +1 -1
  594. package/clis/rest-countries/utils.js +1 -1
  595. package/clis/reuters/article-detail.js +1 -1
  596. package/clis/reuters/auth.js +3 -3
  597. package/clis/reuters/search.js +1 -1
  598. package/clis/reuters/utils.js +4 -4
  599. package/clis/rfc/rfc.js +1 -1
  600. package/clis/rfc/utils.js +1 -1
  601. package/clis/rubygems/gem.js +1 -1
  602. package/clis/rubygems/search.js +1 -1
  603. package/clis/rubygems/utils.js +1 -1
  604. package/clis/segmentfault/article.js +3 -3
  605. package/clis/segmentfault/channels.js +1 -1
  606. package/clis/segmentfault/login.js +1 -1
  607. package/clis/segmentfault/stats.js +4 -4
  608. package/clis/segmentfault/tags.js +1 -1
  609. package/clis/segmentfault/whoami.js +1 -1
  610. package/clis/semanticscholar/citations.js +1 -1
  611. package/clis/semanticscholar/paper.js +1 -1
  612. package/clis/semanticscholar/recommendations.js +1 -1
  613. package/clis/semanticscholar/search.js +1 -1
  614. package/clis/semanticscholar/utils.js +1 -1
  615. package/clis/sinafinance/news.js +1 -1
  616. package/clis/sinafinance/stock-rank.js +1 -1
  617. package/clis/sinafinance/stock.js +1 -1
  618. package/clis/slock/attachment-download.js +1 -1
  619. package/clis/slock/attachment-upload.js +7 -7
  620. package/clis/slock/attachment-url.js +1 -1
  621. package/clis/slock/auth-verify.js +1 -1
  622. package/clis/slock/bookmark-add.js +1 -1
  623. package/clis/slock/bookmark-remove.js +1 -1
  624. package/clis/slock/channel-action.js +1 -1
  625. package/clis/slock/channel-create.js +1 -1
  626. package/clis/slock/channel-files.js +1 -1
  627. package/clis/slock/channel-list.js +1 -1
  628. package/clis/slock/channel-mark.js +1 -1
  629. package/clis/slock/channel-members.js +1 -1
  630. package/clis/slock/channel-unarchive.js +1 -1
  631. package/clis/slock/dm-list.js +1 -1
  632. package/clis/slock/errors.js +1 -1
  633. package/clis/slock/in-page.js +28 -28
  634. package/clis/slock/inbox-done.js +5 -5
  635. package/clis/slock/inbox.js +1 -1
  636. package/clis/slock/message-read.js +22 -22
  637. package/clis/slock/message-search.js +10 -10
  638. package/clis/slock/message-send.js +25 -25
  639. package/clis/slock/reaction-add.js +1 -1
  640. package/clis/slock/reaction-remove.js +1 -1
  641. package/clis/slock/resolve.js +1 -1
  642. package/clis/slock/server-list.js +2 -2
  643. package/clis/slock/task-claim.js +4 -4
  644. package/clis/slock/task-convert.js +13 -13
  645. package/clis/slock/task-create.js +1 -1
  646. package/clis/slock/task-delete.js +5 -5
  647. package/clis/slock/task-get.js +5 -5
  648. package/clis/slock/task-list-server.js +4 -4
  649. package/clis/slock/task-list.js +5 -5
  650. package/clis/slock/task-status.js +3 -3
  651. package/clis/slock/task-unclaim.js +3 -3
  652. package/clis/slock/thread-follow.js +1 -1
  653. package/clis/slock/thread-state.js +1 -1
  654. package/clis/slock/unread-summary.js +5 -5
  655. package/clis/slock/whoami.js +1 -1
  656. package/clis/smzdm/search.js +3 -3
  657. package/clis/sohu/article.js +1 -1
  658. package/clis/sohu/attributes.js +1 -1
  659. package/clis/sohu/categories.js +1 -1
  660. package/clis/sohu/channels.js +1 -1
  661. package/clis/sohu/columns.js +1 -1
  662. package/clis/sohu/login.js +1 -1
  663. package/clis/sohu/stats.js +3 -3
  664. package/clis/sohu/topics.js +1 -1
  665. package/clis/sohu/whoami.js +1 -1
  666. package/clis/spotify/spotify.js +1 -1
  667. package/clis/stackoverflow/read.js +6 -6
  668. package/clis/stackoverflow/related.js +1 -1
  669. package/clis/stackoverflow/tag.js +1 -1
  670. package/clis/stackoverflow/user.js +1 -1
  671. package/clis/stackoverflow/utils.js +1 -1
  672. package/clis/steam/app.js +1 -1
  673. package/clis/steam/search.js +1 -1
  674. package/clis/steam/utils.js +1 -1
  675. package/clis/substack/auth.js +2 -2
  676. package/clis/substack/post-utils.js +2 -2
  677. package/clis/substack/publish.js +5 -5
  678. package/clis/suno/auth.js +2 -2
  679. package/clis/suno/download.js +5 -5
  680. package/clis/suno/generate.js +3 -3
  681. package/clis/suno/list.js +1 -1
  682. package/clis/suno/status.js +1 -1
  683. package/clis/suno/utils.js +29 -29
  684. package/clis/telegram/send.js +7 -7
  685. package/clis/telegram/shared.js +2 -2
  686. package/clis/telegram/whoami.js +1 -1
  687. package/clis/test-utils.js +1 -1
  688. package/clis/threads/post.js +23 -23
  689. package/clis/threads/shared.js +3 -3
  690. package/clis/threads/whoami.js +1 -1
  691. package/clis/tieba/hot.js +3 -3
  692. package/clis/tieba/posts.js +1 -1
  693. package/clis/tieba/read.js +2 -2
  694. package/clis/tieba/search.js +3 -3
  695. package/clis/tieba/utils.js +1 -1
  696. package/clis/tiktok/comment.js +2 -2
  697. package/clis/tiktok/creator-videos.js +3 -3
  698. package/clis/tiktok/explore.js +3 -3
  699. package/clis/tiktok/follow.js +8 -8
  700. package/clis/tiktok/following.js +4 -4
  701. package/clis/tiktok/friends.js +7 -7
  702. package/clis/tiktok/live.js +3 -3
  703. package/clis/tiktok/notifications.js +6 -6
  704. package/clis/tiktok/publish.js +17 -17
  705. package/clis/tiktok/unfollow.js +4 -4
  706. package/clis/tiktok/user.js +2 -2
  707. package/clis/tiktok/utils.js +1 -1
  708. package/clis/toutiao/article.js +1 -1
  709. package/clis/toutiao/articles.js +2 -2
  710. package/clis/toutiao/auth.js +2 -2
  711. package/clis/toutiao/hot.js +1 -1
  712. package/clis/toutiao/recommend.js +1 -1
  713. package/clis/toutiao/utils.js +2 -2
  714. package/clis/trae-solo/_actions.js +4 -4
  715. package/clis/trae-solo/_fs.js +5 -5
  716. package/clis/trae-solo/_state.js +2 -2
  717. package/clis/trae-solo/automation.js +4 -4
  718. package/clis/trae-solo/mode.js +4 -4
  719. package/clis/trae-solo/model.js +4 -4
  720. package/clis/trae-solo/renderer-storage.js +4 -4
  721. package/clis/trae-solo/settings.js +1 -1
  722. package/clis/trae-solo/skill-fs.js +1 -1
  723. package/clis/trae-solo/skill.js +12 -12
  724. package/clis/trae-solo/state-fs.js +2 -2
  725. package/clis/trae-solo/task-fs.js +5 -5
  726. package/clis/trae-solo/workspaces-fs.js +1 -1
  727. package/clis/tumblr/auth.js +2 -2
  728. package/clis/tumblr/publish.js +3 -3
  729. package/clis/tvmaze/search.js +1 -1
  730. package/clis/tvmaze/show.js +1 -1
  731. package/clis/tvmaze/utils.js +1 -1
  732. package/clis/twitter/accept.js +7 -7
  733. package/clis/twitter/article.js +7 -7
  734. package/clis/twitter/bookmark-folder.js +3 -3
  735. package/clis/twitter/bookmark-folders.js +3 -3
  736. package/clis/twitter/bookmarks.js +4 -4
  737. package/clis/twitter/delete.js +5 -5
  738. package/clis/twitter/device-follow.js +3 -3
  739. package/clis/twitter/dm-list.js +1 -1
  740. package/clis/twitter/dm-read.js +1 -1
  741. package/clis/twitter/dm-send.js +5 -5
  742. package/clis/twitter/dm-shared.js +3 -3
  743. package/clis/twitter/download.js +6 -6
  744. package/clis/twitter/followers.js +5 -5
  745. package/clis/twitter/following.js +2 -2
  746. package/clis/twitter/like.js +3 -3
  747. package/clis/twitter/likes.js +8 -8
  748. package/clis/twitter/list-add-core.js +9 -9
  749. package/clis/twitter/list-create.js +5 -5
  750. package/clis/twitter/list-remove-core.js +9 -9
  751. package/clis/twitter/list-tweets.js +7 -7
  752. package/clis/twitter/lists.js +6 -6
  753. package/clis/twitter/notifications.js +2 -2
  754. package/clis/twitter/post.js +24 -24
  755. package/clis/twitter/profile.js +7 -7
  756. package/clis/twitter/quote.js +7 -7
  757. package/clis/twitter/reply-dm.js +7 -7
  758. package/clis/twitter/reply.js +12 -12
  759. package/clis/twitter/retweet.js +3 -3
  760. package/clis/twitter/scheduled-delete.js +3 -3
  761. package/clis/twitter/scheduled-list.js +2 -2
  762. package/clis/twitter/scheduled-utils.js +3 -3
  763. package/clis/twitter/search.js +5 -5
  764. package/clis/twitter/shared.js +6 -6
  765. package/clis/twitter/thread.js +4 -4
  766. package/clis/twitter/timeline.js +3 -3
  767. package/clis/twitter/trending.js +2 -2
  768. package/clis/twitter/tweets.js +11 -11
  769. package/clis/twitter/unlike.js +3 -3
  770. package/clis/twitter/unretweet.js +3 -3
  771. package/clis/twitter/utils.js +6 -6
  772. package/clis/upwork/detail.js +2 -2
  773. package/clis/upwork/feed.js +2 -2
  774. package/clis/upwork/search.js +2 -2
  775. package/clis/upwork/utils.js +1 -1
  776. package/clis/v2ex/auth.js +2 -2
  777. package/clis/v2ex/daily.js +3 -3
  778. package/clis/v2ex/me.js +2 -2
  779. package/clis/v2ex/notifications.js +2 -2
  780. package/clis/vk/post.js +1 -1
  781. package/clis/vk/shared.js +2 -2
  782. package/clis/vk/whoami.js +1 -1
  783. package/clis/web/read.js +8 -8
  784. package/clis/wechat-channels/auth.js +2 -2
  785. package/clis/wechat-channels/publish.js +30 -30
  786. package/clis/weibo/article.js +1 -1
  787. package/clis/weibo/auth.js +3 -3
  788. package/clis/weibo/comments.js +1 -1
  789. package/clis/weibo/delete.js +2 -2
  790. package/clis/weibo/feed.js +3 -3
  791. package/clis/weibo/hot.js +1 -1
  792. package/clis/weibo/publish.js +10 -10
  793. package/clis/weibo/search.js +2 -2
  794. package/clis/weibo/user-posts.js +3 -3
  795. package/clis/weibo/user.js +2 -2
  796. package/clis/weibo/utils.js +3 -3
  797. package/clis/weixin/article.js +1 -1
  798. package/clis/weixin/create-draft.js +26 -26
  799. package/clis/weixin/download.js +2 -2
  800. package/clis/weixin/login.js +1 -1
  801. package/clis/weixin/search.js +2 -2
  802. package/clis/weixin/stats.js +3 -3
  803. package/clis/weixin/whoami.js +1 -1
  804. package/clis/weread/ai-outline.js +2 -2
  805. package/clis/weread/book-search.js +2 -2
  806. package/clis/weread/book.js +2 -2
  807. package/clis/weread/notebooks.js +1 -1
  808. package/clis/weread/search.js +1 -1
  809. package/clis/weread/shelf.js +1 -1
  810. package/clis/weread/utils.js +6 -6
  811. package/clis/weread-official/book.js +1 -1
  812. package/clis/weread-official/discover.js +1 -1
  813. package/clis/weread-official/list-apis.js +1 -1
  814. package/clis/weread-official/notes.js +1 -1
  815. package/clis/weread-official/readdata.js +1 -1
  816. package/clis/weread-official/review.js +1 -1
  817. package/clis/weread-official/search.js +1 -1
  818. package/clis/weread-official/shelf.js +1 -1
  819. package/clis/weread-official/utils.js +1 -1
  820. package/clis/wikidata/entity.js +1 -1
  821. package/clis/wikidata/search.js +1 -1
  822. package/clis/wikidata/utils.js +1 -1
  823. package/clis/wikipedia/page.js +1 -1
  824. package/clis/wikipedia/trending.js +1 -1
  825. package/clis/wikipedia/utils.js +1 -1
  826. package/clis/wordpress/login.js +1 -1
  827. package/clis/wordpress/publish.js +1 -1
  828. package/clis/wordpress/shared.js +3 -3
  829. package/clis/wordpress/whoami.js +1 -1
  830. package/clis/woshipm/article.js +1 -1
  831. package/clis/woshipm/login.js +1 -1
  832. package/clis/woshipm/stats.js +4 -4
  833. package/clis/woshipm/whoami.js +1 -1
  834. package/clis/wttr/current.js +1 -1
  835. package/clis/wttr/forecast.js +1 -1
  836. package/clis/wttr/utils.js +1 -1
  837. package/clis/xianyu/collect.js +1 -1
  838. package/clis/xianyu/inbox.js +1 -1
  839. package/clis/xianyu/item-stats.js +2 -2
  840. package/clis/xianyu/location.js +1 -1
  841. package/clis/xianyu/manage.js +1 -1
  842. package/clis/xianyu/messages.js +1 -1
  843. package/clis/xianyu/mtop.js +5 -5
  844. package/clis/xianyu/order.js +1 -1
  845. package/clis/xianyu/promote-stats.js +2 -2
  846. package/clis/xianyu/publish.js +17 -17
  847. package/clis/xianyu/rate.js +1 -1
  848. package/clis/xianyu/reply.js +1 -1
  849. package/clis/xianyu/search.js +8 -8
  850. package/clis/xianyu/seller-data.js +1 -1
  851. package/clis/xianyu/seller-list.js +1 -1
  852. package/clis/xianyu/user.js +1 -1
  853. package/clis/xiaoe/catalog.js +2 -2
  854. package/clis/xiaoe/content.js +2 -2
  855. package/clis/xiaoe/courses.js +2 -2
  856. package/clis/xiaohongshu/ask.js +6 -6
  857. package/clis/xiaohongshu/comments.js +6 -6
  858. package/clis/xiaohongshu/creator-note-detail.js +7 -7
  859. package/clis/xiaohongshu/creator-notes-summary.js +1 -1
  860. package/clis/xiaohongshu/creator-notes.js +13 -13
  861. package/clis/xiaohongshu/creator-profile.js +2 -2
  862. package/clis/xiaohongshu/creator-stats.js +2 -2
  863. package/clis/xiaohongshu/delete-note.js +7 -7
  864. package/clis/xiaohongshu/download.js +4 -4
  865. package/clis/xiaohongshu/feed.js +2 -2
  866. package/clis/xiaohongshu/follow.js +3 -3
  867. package/clis/xiaohongshu/human.js +3 -3
  868. package/clis/xiaohongshu/note-helpers.js +1 -1
  869. package/clis/xiaohongshu/note.js +2 -2
  870. package/clis/xiaohongshu/notifications.js +1 -1
  871. package/clis/xiaohongshu/publish-video.js +8 -8
  872. package/clis/xiaohongshu/publish.js +59 -59
  873. package/clis/xiaohongshu/search.js +8 -8
  874. package/clis/xiaohongshu/unfollow.js +4 -4
  875. package/clis/xiaohongshu/user-helpers.js +1 -1
  876. package/clis/xiaohongshu/user.js +2 -2
  877. package/clis/xiaoyuzhou/auth.js +3 -3
  878. package/clis/xiaoyuzhou/download.js +1 -1
  879. package/clis/xiaoyuzhou/utils.js +1 -1
  880. package/clis/xueqiu/article.js +4 -4
  881. package/clis/xueqiu/comments.js +4 -4
  882. package/clis/xueqiu/danjuan-utils.js +4 -4
  883. package/clis/xueqiu/earnings-date.js +1 -1
  884. package/clis/xueqiu/events.js +3 -3
  885. package/clis/xueqiu/hashtags.js +3 -3
  886. package/clis/xueqiu/stocks.js +3 -3
  887. package/clis/xueqiu/users.js +3 -3
  888. package/clis/xueqiu/utils.js +3 -3
  889. package/clis/yahoo-finance/quote.js +1 -1
  890. package/clis/yollomi/background.js +1 -1
  891. package/clis/yollomi/edit.js +1 -1
  892. package/clis/yollomi/face-swap.js +1 -1
  893. package/clis/yollomi/generate.js +1 -1
  894. package/clis/yollomi/object-remover.js +1 -1
  895. package/clis/yollomi/remove-bg.js +1 -1
  896. package/clis/yollomi/restore.js +1 -1
  897. package/clis/yollomi/try-on.js +1 -1
  898. package/clis/yollomi/upload.js +4 -4
  899. package/clis/yollomi/upscale.js +1 -1
  900. package/clis/yollomi/utils.js +4 -4
  901. package/clis/yollomi/video.js +1 -1
  902. package/clis/youtube/channel.js +4 -4
  903. package/clis/youtube/feed.js +2 -2
  904. package/clis/youtube/like.js +5 -5
  905. package/clis/youtube/playlist.js +7 -7
  906. package/clis/youtube/publish.js +11 -11
  907. package/clis/youtube/search.js +3 -3
  908. package/clis/youtube/subscribe.js +7 -7
  909. package/clis/youtube/subscriptions.js +1 -1
  910. package/clis/youtube/transcript-group.js +2 -2
  911. package/clis/youtube/transcript.js +13 -13
  912. package/clis/youtube/unlike.js +5 -5
  913. package/clis/youtube/unsubscribe.js +7 -7
  914. package/clis/youtube/utils.js +3 -3
  915. package/clis/youtube/video.js +4 -4
  916. package/clis/youtube/watch-later.js +2 -2
  917. package/clis/yuanbao/ask.js +18 -18
  918. package/clis/yuanbao/detail.js +1 -1
  919. package/clis/yuanbao/read.js +1 -1
  920. package/clis/yuanbao/shared.js +9 -9
  921. package/clis/yuanbao/status.js +1 -1
  922. package/clis/yuque/article.js +1 -1
  923. package/clis/yuque/whoami.js +1 -1
  924. package/clis/zhihu/answer-comments.js +2 -2
  925. package/clis/zhihu/answer-detail.js +3 -3
  926. package/clis/zhihu/answer.js +1 -1
  927. package/clis/zhihu/article-transform.js +1 -1
  928. package/clis/zhihu/article.js +1 -1
  929. package/clis/zhihu/auth.js +2 -2
  930. package/clis/zhihu/collection.js +3 -3
  931. package/clis/zhihu/collections.js +3 -3
  932. package/clis/zhihu/download.js +2 -2
  933. package/clis/zhihu/image-profile.js +6 -6
  934. package/clis/zhihu/paginate.js +3 -3
  935. package/clis/zhihu/pin.js +4 -4
  936. package/clis/zhihu/question.js +3 -3
  937. package/clis/zhihu/recommend.js +3 -3
  938. package/clis/zhihu/search.js +3 -3
  939. package/clis/zhihu/stats.js +3 -3
  940. package/clis/zhihu/user-arg.js +1 -1
  941. package/clis/zhihu/write-shared.js +7 -7
  942. package/clis/zlibrary/utils.js +6 -6
  943. package/clis/zsxq/auth.js +3 -3
  944. package/clis/zsxq/search.js +1 -1
  945. package/clis/zsxq/topic.js +1 -1
  946. package/clis/zsxq/utils.js +5 -5
  947. package/dist/src/adapter-source.js +1 -1
  948. package/dist/src/browser/analyze.js +1 -1
  949. package/dist/src/browser/article-extract.js +2 -2
  950. package/dist/src/browser/ax-snapshot.js +2 -2
  951. package/dist/src/browser/base-page.js +25 -25
  952. package/dist/src/browser/bridge.js +1 -1
  953. package/dist/src/browser/cdp.js +1 -1
  954. package/dist/src/browser/daemon-client.js +1 -1
  955. package/dist/src/browser/daemon-lifecycle.js +7 -7
  956. package/dist/src/browser/dom-helpers.js +35 -35
  957. package/dist/src/browser/dom-snapshot.js +19 -19
  958. package/dist/src/browser/errors.js +3 -3
  959. package/dist/src/browser/extract.js +5 -5
  960. package/dist/src/browser/find.js +13 -13
  961. package/dist/src/browser/fingerprint.js +2 -2
  962. package/dist/src/browser/html-tree.js +6 -6
  963. package/dist/src/browser/managed-chrome.js +1 -1
  964. package/dist/src/browser/network-cache.js +1 -1
  965. package/dist/src/browser/network-key.js +1 -1
  966. package/dist/src/browser/page.js +7 -7
  967. package/dist/src/browser/profile.js +2 -2
  968. package/dist/src/browser/proxy-test.js +8 -8
  969. package/dist/src/browser/shape-filter.js +1 -1
  970. package/dist/src/browser/shape.js +1 -1
  971. package/dist/src/browser/stealth.js +3 -3
  972. package/dist/src/browser/tabs.js +2 -2
  973. package/dist/src/browser/target-errors.js +1 -1
  974. package/dist/src/browser/target-resolver.js +23 -23
  975. package/dist/src/browser/trace.js +2 -2
  976. package/dist/src/browser/utils.js +1 -1
  977. package/dist/src/browser/verify-fixture.js +2 -2
  978. package/dist/src/browser-session-lock.js +1 -1
  979. package/dist/src/build-manifest.js +11 -11
  980. package/dist/src/capabilityRouting.js +1 -1
  981. package/dist/src/cli-argv-preprocess.js +1 -1
  982. package/dist/src/cli.js +32 -32
  983. package/dist/src/commanderAdapter.js +3 -3
  984. package/dist/src/commands/auth.js +3 -3
  985. package/dist/src/commands/daemon.js +1 -1
  986. package/dist/src/completion-fast.js +1 -1
  987. package/dist/src/completion.js +1 -1
  988. package/dist/src/constants.js +1 -1
  989. package/dist/src/convention-audit.js +2 -2
  990. package/dist/src/daemon-utils.js +1 -1
  991. package/dist/src/daemon.js +1 -1
  992. package/dist/src/discovery.js +2 -2
  993. package/dist/src/doctor.js +9 -9
  994. package/dist/src/download/article-download.js +15 -15
  995. package/dist/src/download/index.js +4 -4
  996. package/dist/src/download/media-download.js +1 -1
  997. package/dist/src/download/progress.js +3 -3
  998. package/dist/src/electron-apps.js +1 -1
  999. package/dist/src/errors.js +2 -2
  1000. package/dist/src/execution.js +2 -2
  1001. package/dist/src/external.js +1 -1
  1002. package/dist/src/help.js +8 -8
  1003. package/dist/src/hooks.js +1 -1
  1004. package/dist/src/interceptor.js +21 -21
  1005. package/dist/src/launcher.js +7 -7
  1006. package/dist/src/logger.js +8 -8
  1007. package/dist/src/main.js +7 -7
  1008. package/dist/src/observation/artifact.js +5 -5
  1009. package/dist/src/observation/retention.js +1 -1
  1010. package/dist/src/output.js +2 -2
  1011. package/dist/src/package-paths.js +1 -1
  1012. package/dist/src/pipeline/executor.js +1 -1
  1013. package/dist/src/pipeline/registry.js +1 -1
  1014. package/dist/src/pipeline/steps/browser.js +1 -1
  1015. package/dist/src/pipeline/steps/download.js +1 -1
  1016. package/dist/src/pipeline/steps/fetch.js +6 -6
  1017. package/dist/src/pipeline/steps/intercept.js +1 -1
  1018. package/dist/src/pipeline/steps/tap.js +17 -17
  1019. package/dist/src/pipeline/steps/transform.js +1 -1
  1020. package/dist/src/pipeline/template.js +1 -1
  1021. package/dist/src/plugin-manifest.js +1 -1
  1022. package/dist/src/plugin-scaffold.js +19 -19
  1023. package/dist/src/plugin.js +12 -12
  1024. package/dist/src/rate-limit.js +1 -1
  1025. package/dist/src/registry.js +1 -1
  1026. package/dist/src/runtime-detect.js +1 -1
  1027. package/dist/src/runtime.js +1 -1
  1028. package/dist/src/scripts/framework.js +1 -1
  1029. package/dist/src/scripts/interact.js +1 -1
  1030. package/dist/src/scripts/store.js +1 -1
  1031. package/dist/src/serialization.js +2 -2
  1032. package/dist/src/session-lease.js +1 -1
  1033. package/dist/src/snapshotFormatter.js +2 -2
  1034. package/dist/src/tui.js +12 -12
  1035. package/dist/src/user-runtime.js +1 -1
  1036. package/dist/src/utils.d.ts +12 -0
  1037. package/dist/src/utils.js +4 -4
  1038. package/dist/src/validate.js +2 -2
  1039. package/dist/src/verify.js +2 -2
  1040. package/dist/src/version.js +1 -1
  1041. package/package.json +1 -1
@@ -1 +1 @@
1
- import*as l from"node:path";import{cli as n,Strategy as p}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as m}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as c,yollomiPost as f,downloadOutput as d,fmtBytes as w}from"./utils.js";n({site:"yollomi",name:"face-swap",access:"write",description:"Swap faces between two photos (3 credits)",domain:c,strategy:p.COOKIE,args:[{name:"source",required:!0,help:"Source face image URL"},{name:"target",required:!0,help:"Target photo URL"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(o,t)=>{m.status("Swapping faces...");const a=await f(o,"/api/ai/face-swap",{swap_image:t.source,input_image:t.target}),e=a.image||a.images?.[0];if(!e)throw new u("EMPTY_RESPONSE","No result","Make sure both images contain clear faces");if(t["no-download"])return[{status:"swapped",file:"-",size:"-",url:e}];try{const i=`yollomi_faceswap_${Date.now()}.jpg`,{path:s,size:r}=await d(e,t.output,i);return[{status:"saved",file:l.relative(".",s),size:w(r),url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",url:e}]}}});
1
+ import*as l from"node:path";import{cli as u,Strategy as n}from"@jackwener/opencli/registry";import{CliError as p}from"@jackwener/opencli/errors";import{log as m}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as c,yollomiPost as f,downloadOutput as d,fmtBytes as w}from"./utils.js";u({site:"yollomi",name:"face-swap",access:"write",description:"Swap faces between two photos (3 credits)",domain:c,strategy:n.COOKIE,args:[{name:"source",required:!0,help:"Source face image URL"},{name:"target",required:!0,help:"Target photo URL"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(o,t)=>{m.status("Swapping faces...");const a=await f(o,"/api/ai/face-swap",{swap_image:t.source,input_image:t.target}),e=a.image||a.images?.[0];if(!e)throw new p("EMPTY_RESPONSE","No result","Make sure both images contain clear faces");if(t["no-download"])return[{status:"swapped",file:"-",size:"-",url:e}];try{const i=`yollomi_faceswap_${Date.now()}.jpg`,{path:s,size:r}=await d(e,t.output,i);return[{status:"saved",file:l.relative(".",s),size:w(r),url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",url:e}]}}});
@@ -1 +1 @@
1
- import*as w from"node:path";import{cli as b,Strategy as I}from"@jackwener/opencli/registry";import{CliError as c}from"@jackwener/opencli/errors";import{log as f}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as U,yollomiPost as z,downloadOutput as D,fmtBytes as E,MODEL_ROUTES as L}from"./utils.js";function P(p){const e={"1:1":[1024,1024],"16:9":[1344,768],"9:16":[768,1344],"4:3":[1152,896],"3:4":[896,1152]},[n,t]=e[p]||[1024,1024];return{width:n,height:t}}b({site:"yollomi",name:"generate",access:"write",description:"Generate images with AI (text-to-image or image-to-image)",domain:U,strategy:I.COOKIE,args:[{name:"prompt",fromFile:!0,positional:!0,required:!0,help:"Text prompt describing the image"},{name:"model",default:"z-image-turbo",help:"Model ID (z-image-turbo, flux-schnell, nano-banana, flux-2-pro, ...)"},{name:"ratio",default:"1:1",choices:["1:1","16:9","9:16","4:3","3:4"],help:"Aspect ratio"},{name:"image",help:'Input image URL for image-to-image (upload via "ppcli yollomi upload" first)'},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URLs, skip download"}],columns:["index","status","file","size","url"],func:async(p,e)=>{const{prompt:n,model:t,ratio:l}=e,d=L[t];if(!d)throw new c("INVALID_MODEL",`Unknown model: ${t}`,'Run "ppcli yollomi models --type image" to see available models');let i;if(t==="z-image-turbo"){const{width:o,height:a}=P(l);i={prompt:n,width:o,height:a,output_format:"jpg",output_quality:85,guidance_scale:0,num_inference_steps:8}}else if(t==="flux-2-pro"){i={prompt:n,aspectRatio:l,outputNumber:1};if(e.image)i.imageUrl=e.image}else if(t==="flux-kontext-pro"){i={prompt:n,output_format:"jpg"};if(e.image)i.imageUrl=e.image;if(l!=="1:1")i.aspect_ratio=l}else{i={prompt:n,aspect_ratio:l};if(e.image)i.imageUrl=e.image}f.status(`Generating with ${t}...`);const r=await z(p,d,i),u=r.images||(r.image?[r.image]:[]);if(!u.length)throw new c("EMPTY_RESPONSE","No images returned","Try a different prompt or model");const g=e["no-download"],h=e.output,m=[];for(let o=0;o<u.length;o++){const a=u[o];if(g){m.push({index:o+1,status:"generated",file:"-",size:"-",url:a});continue}try{const s=(()=>{try{return new URL(a).pathname}catch{return a}})(),y=s.endsWith(".png")||s.endsWith(".webp")?s.slice(s.lastIndexOf(".")):".jpg",x=`yollomi_${t}_${Date.now()}_${o+1}${y}`,{path:O,size:_}=await D(a,h,x);m.push({index:o+1,status:"saved",file:w.relative(".",O),size:E(_),url:a})}catch{m.push({index:o+1,status:"download-failed",file:"-",size:"-",url:a})}}if(r.remainingCredits!==void 0)f.status(`Credits remaining: ${r.remainingCredits}`);return m}});
1
+ import*as O from"node:path";import{cli as b,Strategy as I}from"@jackwener/opencli/registry";import{CliError as f}from"@jackwener/opencli/errors";import{log as c}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as D,yollomiPost as z,downloadOutput as E,fmtBytes as L,MODEL_ROUTES as U}from"./utils.js";function R(u){const e={"1:1":[1024,1024],"16:9":[1344,768],"9:16":[768,1344],"4:3":[1152,896],"3:4":[896,1152]},[n,t]=e[u]||[1024,1024];return{width:n,height:t}}b({site:"yollomi",name:"generate",access:"write",description:"Generate images with AI (text-to-image or image-to-image)",domain:D,strategy:I.COOKIE,args:[{name:"prompt",fromFile:!0,positional:!0,required:!0,help:"Text prompt describing the image"},{name:"model",default:"z-image-turbo",help:"Model ID (z-image-turbo, flux-schnell, nano-banana, flux-2-pro, ...)"},{name:"ratio",default:"1:1",choices:["1:1","16:9","9:16","4:3","3:4"],help:"Aspect ratio"},{name:"image",help:'Input image URL for image-to-image (upload via "ppcli yollomi upload" first)'},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URLs, skip download"}],columns:["index","status","file","size","url"],func:async(u,e)=>{const{prompt:n,model:t,ratio:l}=e,d=U[t];if(!d)throw new f("INVALID_MODEL",`Unknown model: ${t}`,'Run "ppcli yollomi models --type image" to see available models');let i;if(t==="z-image-turbo"){const{width:o,height:a}=R(l);i={prompt:n,width:o,height:a,output_format:"jpg",output_quality:85,guidance_scale:0,num_inference_steps:8}}else if(t==="flux-2-pro"){i={prompt:n,aspectRatio:l,outputNumber:1};if(e.image)i.imageUrl=e.image}else if(t==="flux-kontext-pro"){i={prompt:n,output_format:"jpg"};if(e.image)i.imageUrl=e.image;if(l!=="1:1")i.aspect_ratio=l}else{i={prompt:n,aspect_ratio:l};if(e.image)i.imageUrl=e.image}c.status(`Generating with ${t}...`);const r=await z(u,d,i),p=r.images||(r.image?[r.image]:[]);if(!p.length)throw new f("EMPTY_RESPONSE","No images returned","Try a different prompt or model");const g=e["no-download"],h=e.output,m=[];for(let o=0;o<p.length;o++){const a=p[o];if(g){m.push({index:o+1,status:"generated",file:"-",size:"-",url:a});continue}try{const s=(()=>{try{return new URL(a).pathname}catch{return a}})(),y=s.endsWith(".png")||s.endsWith(".webp")?s.slice(s.lastIndexOf(".")):".jpg",_=`yollomi_${t}_${Date.now()}_${o+1}${y}`,{path:w,size:x}=await E(a,h,_);m.push({index:o+1,status:"saved",file:O.relative(".",w),size:L(x),url:a})}catch{m.push({index:o+1,status:"download-failed",file:"-",size:"-",url:a})}}if(r.remainingCredits!==void 0)c.status(`Credits remaining: ${r.remainingCredits}`);return m}});
@@ -1 +1 @@
1
- import*as s from"node:path";import{cli as l,Strategy as n}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as p}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as d,yollomiPost as c,downloadOutput as f,fmtBytes as g}from"./utils.js";l({site:"yollomi",name:"object-remover",access:"write",description:"Remove unwanted objects from images (3 credits)",domain:d,strategy:n.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL"},{name:"mask",positional:!0,required:!0,help:"Mask image URL (white = area to remove)"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(a,t)=>{p.status("Removing object...");const o=await c(a,"/api/ai/object-remover",{image:t.image,mask:t.mask}),e=o.image||o.images?.[0];if(!e)throw new u("EMPTY_RESPONSE","No result","Check image and mask");if(t["no-download"])return[{status:"removed",file:"-",size:"-",url:e}];try{const i=`yollomi_removed_${Date.now()}.png`,{path:r,size:m}=await f(e,t.output,i);return[{status:"saved",file:s.relative(".",r),size:g(m),url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",url:e}]}}});
1
+ import*as s from"node:path";import{cli as l,Strategy as n}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as d}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as p,yollomiPost as c,downloadOutput as f,fmtBytes as g}from"./utils.js";l({site:"yollomi",name:"object-remover",access:"write",description:"Remove unwanted objects from images (3 credits)",domain:p,strategy:n.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL"},{name:"mask",positional:!0,required:!0,help:"Mask image URL (white = area to remove)"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(a,t)=>{d.status("Removing object...");const o=await c(a,"/api/ai/object-remover",{image:t.image,mask:t.mask}),e=o.image||o.images?.[0];if(!e)throw new u("EMPTY_RESPONSE","No result","Check image and mask");if(t["no-download"])return[{status:"removed",file:"-",size:"-",url:e}];try{const i=`yollomi_removed_${Date.now()}.png`,{path:r,size:m}=await f(e,t.output,i);return[{status:"saved",file:s.relative(".",r),size:g(m),url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",url:e}]}}});
@@ -1 +1 @@
1
- import*as m from"node:path";import{cli as s,Strategy as n}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as p}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as d,yollomiPost as f,downloadOutput as c,fmtBytes as g}from"./utils.js";s({site:"yollomi",name:"remove-bg",access:"write",description:"Remove image background with AI (free)",domain:d,strategy:n.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL to remove background from"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(a,o)=>{p.status("Removing background...");const t=await f(a,"/api/ai/remove-bg",{imageUrl:o.image}),e=t.image||t.images?.[0];if(!e)throw new u("EMPTY_RESPONSE","No result","Check the input image URL");if(o["no-download"])return[{status:"processed",file:"-",size:"-",url:e}];try{const i=`yollomi_nobg_${Date.now()}.png`,{path:r,size:l}=await c(e,o.output,i);return[{status:"saved",file:m.relative(".",r),size:g(l),url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",url:e}]}}});
1
+ import*as m from"node:path";import{cli as s,Strategy as n}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as p}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as d,yollomiPost as f,downloadOutput as c,fmtBytes as g}from"./utils.js";s({site:"yollomi",name:"remove-bg",access:"write",description:"Remove image background with AI (free)",domain:d,strategy:n.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL to remove background from"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(a,t)=>{p.status("Removing background...");const o=await f(a,"/api/ai/remove-bg",{imageUrl:t.image}),e=o.image||o.images?.[0];if(!e)throw new u("EMPTY_RESPONSE","No result","Check the input image URL");if(t["no-download"])return[{status:"processed",file:"-",size:"-",url:e}];try{const i=`yollomi_nobg_${Date.now()}.png`,{path:r,size:l}=await c(e,t.output,i);return[{status:"saved",file:m.relative(".",r),size:g(l),url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",url:e}]}}});
@@ -1 +1 @@
1
- import*as l from"node:path";import{cli as n,Strategy as m}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as p}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as d,yollomiPost as f,downloadOutput as c,fmtBytes as h}from"./utils.js";n({site:"yollomi",name:"restore",access:"write",description:"Restore old or damaged photos with AI (4 credits)",domain:d,strategy:m.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL to restore"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(i,o)=>{p.status("Restoring photo...");const e=await f(i,"/api/ai/photo-restoration",{imageUrl:o.image}),t=e.image||e.images?.[0];if(!t)throw new u("EMPTY_RESPONSE","No result","Check the input image");if(o["no-download"])return[{status:"restored",file:"-",size:"-",url:t}];try{const a=`yollomi_restored_${Date.now()}.jpg`,{path:r,size:s}=await c(t,o.output,a);return[{status:"saved",file:l.relative(".",r),size:h(s),url:t}]}catch{return[{status:"download-failed",file:"-",size:"-",url:t}]}}});
1
+ import*as l from"node:path";import{cli as n,Strategy as m}from"@jackwener/opencli/registry";import{CliError as u}from"@jackwener/opencli/errors";import{log as p}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as d,yollomiPost as f,downloadOutput as c,fmtBytes as h}from"./utils.js";n({site:"yollomi",name:"restore",access:"write",description:"Restore old or damaged photos with AI (4 credits)",domain:d,strategy:m.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL to restore"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(a,e)=>{p.status("Restoring photo...");const o=await f(a,"/api/ai/photo-restoration",{imageUrl:e.image}),t=o.image||o.images?.[0];if(!t)throw new u("EMPTY_RESPONSE","No result","Check the input image");if(e["no-download"])return[{status:"restored",file:"-",size:"-",url:t}];try{const i=`yollomi_restored_${Date.now()}.jpg`,{path:r,size:s}=await c(t,e.output,i);return[{status:"saved",file:l.relative(".",r),size:h(s),url:t}]}catch{return[{status:"download-failed",file:"-",size:"-",url:t}]}}});
@@ -1 +1 @@
1
- import*as n from"node:path";import{cli as s,Strategy as u}from"@jackwener/opencli/registry";import{CliError as p}from"@jackwener/opencli/errors";import{log as m}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as c,yollomiPost as h,downloadOutput as y,fmtBytes as d}from"./utils.js";s({site:"yollomi",name:"try-on",access:"write",description:"Virtual try-on — see how clothes look on a person (3 credits)",domain:c,strategy:u.COOKIE,args:[{name:"person",required:!0,help:'Person photo URL (upload via "ppcli yollomi upload" first)'},{name:"cloth",required:!0,help:"Clothing image URL"},{name:"cloth-type",default:"upper",choices:["upper","lower","overall"],help:"Clothing type"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(l,t)=>{m.status("Processing virtual try-on...");const e=await h(l,"/api/ai/virtual-try-on",{person_image:t.person,cloth_image:t.cloth,cloth_type:t["cloth-type"],output_format:"png",output_quality:100}),o=e.image||e.images?.[0];if(!o)throw new p("EMPTY_RESPONSE","No result","Check both images have clear subjects");if(t["no-download"])return[{status:"generated",file:"-",size:"-",url:o}];try{const a=`yollomi_tryon_${Date.now()}.png`,{path:i,size:r}=await y(o,t.output,a);return[{status:"saved",file:n.relative(".",i),size:d(r),url:o}]}catch{return[{status:"download-failed",file:"-",size:"-",url:o}]}}});
1
+ import*as n from"node:path";import{cli as s,Strategy as u}from"@jackwener/opencli/registry";import{CliError as p}from"@jackwener/opencli/errors";import{log as m}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as c,yollomiPost as h,downloadOutput as d,fmtBytes as y}from"./utils.js";s({site:"yollomi",name:"try-on",access:"write",description:"Virtual try-on — see how clothes look on a person (3 credits)",domain:c,strategy:u.COOKIE,args:[{name:"person",required:!0,help:'Person photo URL (upload via "ppcli yollomi upload" first)'},{name:"cloth",required:!0,help:"Clothing image URL"},{name:"cloth-type",default:"upper",choices:["upper","lower","overall"],help:"Clothing type"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","url"],func:async(l,t)=>{m.status("Processing virtual try-on...");const e=await h(l,"/api/ai/virtual-try-on",{person_image:t.person,cloth_image:t.cloth,cloth_type:t["cloth-type"],output_format:"png",output_quality:100}),o=e.image||e.images?.[0];if(!o)throw new p("EMPTY_RESPONSE","No result","Check both images have clear subjects");if(t["no-download"])return[{status:"generated",file:"-",size:"-",url:o}];try{const a=`yollomi_tryon_${Date.now()}.png`,{path:r,size:i}=await d(o,t.output,a);return[{status:"saved",file:n.relative(".",r),size:y(i),url:o}]}catch{return[{status:"download-failed",file:"-",size:"-",url:o}]}}});
@@ -1,10 +1,10 @@
1
- import*as W from"node:fs";import*as R from"node:path";import{cli as J,Strategy as v}from"@jackwener/opencli/registry";import{CliError as H}from"@jackwener/opencli/errors";import{log as X}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as A,ensureOnYollomi as L,fmtBytes as T}from"./utils.js";const Y={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".mp4":"video/mp4",".mov":"video/quicktime"};J({site:"yollomi",name:"upload",access:"write",description:"Upload an image or video to Yollomi (returns URL for other commands)",domain:A,strategy:v.COOKIE,args:[{name:"file",positional:!0,required:!0,help:"Local file path to upload"}],columns:["status","file","size","url"],func:async(U,Z)=>{const q=R.resolve(Z.file);if(!W.existsSync(q))throw new H("FILE_NOT_FOUND",`File not found: ${q}`,"Provide a valid file path");const V=R.extname(q).toLowerCase(),G=Y[V];if(!G)throw new H("INVALID_TYPE",`Unsupported file type: ${V}`,"Supported: jpg, png, gif, webp, mp4, mov");const F=W.readFileSync(q),$=G.startsWith("video/")?20971520:10485760;if(F.length>$)throw new H("FILE_TOO_LARGE",`File too large: ${T(F.length)}`,`Max ${G.startsWith("video/")?"20MB":"10MB"} (upload larger videos from a URL)`);const z=F.toString("base64"),K=R.basename(q);X.status(`Uploading ${K} (${T(F.length)})...`);await L(U);const Q=await U.evaluate(`
1
+ import*as d from"node:fs";import*as s from"node:path";import{cli as h,Strategy as w}from"@jackwener/opencli/registry";import{CliError as a}from"@jackwener/opencli/errors";import{log as p}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as y,ensureOnYollomi as O,fmtBytes as n}from"./utils.js";const v={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".mp4":"video/mp4",".mov":"video/quicktime"};h({site:"yollomi",name:"upload",access:"write",description:"Upload an image or video to Yollomi (returns URL for other commands)",domain:y,strategy:w.COOKIE,args:[{name:"file",positional:!0,required:!0,help:"Local file path to upload"}],columns:["status","file","size","url"],func:async(l,f)=>{const e=s.resolve(f.file);if(!d.existsSync(e))throw new a("FILE_NOT_FOUND",`File not found: ${e}`,"Provide a valid file path");const m=s.extname(e).toLowerCase(),o=v[m];if(!o)throw new a("INVALID_TYPE",`Unsupported file type: ${m}`,"Supported: jpg, png, gif, webp, mp4, mov");const t=d.readFileSync(e),c=o.startsWith("video/")?20971520:10485760;if(t.length>c)throw new a("FILE_TOO_LARGE",`File too large: ${n(t.length)}`,`Max ${o.startsWith("video/")?"20MB":"10MB"} (upload larger videos from a URL)`);const g=t.toString("base64"),r=s.basename(e);p.status(`Uploading ${r} (${n(t.length)})...`);await O(l);const i=await l.evaluate(`
2
2
  (async () => {
3
3
  try {
4
- const raw = atob(${JSON.stringify(z)});
4
+ const raw = atob(${JSON.stringify(g)});
5
5
  const arr = new Uint8Array(raw.length);
6
6
  for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);
7
- const file = new File([arr], ${JSON.stringify(K)}, { type: ${JSON.stringify(G)} });
7
+ const file = new File([arr], ${JSON.stringify(r)}, { type: ${JSON.stringify(o)} });
8
8
  const fd = new FormData();
9
9
  fd.append('file', file);
10
10
  const res = await fetch('/api/upload', { method: 'POST', body: fd, credentials: 'include' });
@@ -14,4 +14,4 @@ import*as W from"node:fs";import*as R from"node:path";import{cli as J,Strategy a
14
14
  return { ok: false, status: 0, data: { error: err.message } };
15
15
  }
16
16
  })()
17
- `);if(!Q?.ok)throw new H("UPLOAD_ERROR",Q?.data?.error||"Upload failed","Make sure you are logged in to yollomi.com");const D=Q.data.url;X.success("Uploaded! Use this URL as input for other commands.");return[{status:"uploaded",file:K,size:T(F.length),url:D}]}});
17
+ `);if(!i?.ok)throw new a("UPLOAD_ERROR",i?.data?.error||"Upload failed","Make sure you are logged in to yollomi.com");const u=i.data.url;p.success("Uploaded! Use this URL as input for other commands.");return[{status:"uploaded",file:r,size:n(t.length),url:u}]}});
@@ -1 +1 @@
1
- import*as m from"node:path";import{cli as p,Strategy as d}from"@jackwener/opencli/registry";import{CliError as f}from"@jackwener/opencli/errors";import{log as l}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as g,yollomiPost as h,downloadOutput as y,fmtBytes as w}from"./utils.js";p({site:"yollomi",name:"upscale",access:"write",description:"Upscale image resolution with AI (1 credit)",domain:g,strategy:d.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL to upscale"},{name:"scale",default:"2",choices:["2","4"],help:"Upscale factor (2 or 4)"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","scale","url"],func:async(o,a)=>{const t=parseInt(a.scale,10);l.status(`Upscaling ${t}x...`);const i=await h(o,"/api/ai/image-upscaler",{imageUrl:a.image,scale:t,face_enhance:!1}),e=i.image||i.images?.[0];if(!e)throw new f("EMPTY_RESPONSE","No result","Check the input image");if(a["no-download"])return[{status:"upscaled",file:"-",size:"-",scale:`${t}x`,url:e}];try{const s=(()=>{try{return new URL(e).pathname}catch{return e}})(),n=s.endsWith(".png")||s.endsWith(".webp")?s.slice(s.lastIndexOf(".")):".jpg",r=`yollomi_upscale_${t}x_${Date.now()}${n}`,{path:c,size:u}=await y(e,a.output,r);if(i.remainingCredits!==void 0)l.status(`Credits remaining: ${i.remainingCredits}`);return[{status:"saved",file:m.relative(".",c),size:w(u),scale:`${t}x`,url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",scale:`${t}x`,url:e}]}}});
1
+ import*as m from"node:path";import{cli as p,Strategy as d}from"@jackwener/opencli/registry";import{CliError as f}from"@jackwener/opencli/errors";import{log as o}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as h,yollomiPost as g,downloadOutput as y,fmtBytes as w}from"./utils.js";p({site:"yollomi",name:"upscale",access:"write",description:"Upscale image resolution with AI (1 credit)",domain:h,strategy:d.COOKIE,args:[{name:"image",positional:!0,required:!0,help:"Image URL to upscale"},{name:"scale",default:"2",choices:["2","4"],help:"Upscale factor (2 or 4)"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL"}],columns:["status","file","size","scale","url"],func:async(l,a)=>{const t=parseInt(a.scale,10);o.status(`Upscaling ${t}x...`);const i=await g(l,"/api/ai/image-upscaler",{imageUrl:a.image,scale:t,face_enhance:!1}),e=i.image||i.images?.[0];if(!e)throw new f("EMPTY_RESPONSE","No result","Check the input image");if(a["no-download"])return[{status:"upscaled",file:"-",size:"-",scale:`${t}x`,url:e}];try{const s=(()=>{try{return new URL(e).pathname}catch{return e}})(),n=s.endsWith(".png")||s.endsWith(".webp")?s.slice(s.lastIndexOf(".")):".jpg",r=`yollomi_upscale_${t}x_${Date.now()}${n}`,{path:c,size:u}=await y(e,a.output,r);if(i.remainingCredits!==void 0)o.status(`Credits remaining: ${i.remainingCredits}`);return[{status:"saved",file:m.relative(".",c),size:w(u),scale:`${t}x`,url:e}]}catch{return[{status:"download-failed",file:"-",size:"-",scale:`${t}x`,url:e}]}}});
@@ -1,11 +1,11 @@
1
- import*as L from"node:fs";import*as M from"node:path";import{CliError as K}from"@jackwener/opencli/errors";export const YOLLOMI_DOMAIN="yollomi.com";export async function ensureOnYollomi(A){const B=await A.evaluate("(() => location.href)()");if(!B||!B.includes("yollomi.com")){await A.goto("https://yollomi.com");await A.wait(3)}}export async function yollomiPost(A,B,G){const F=JSON.stringify(G);await ensureOnYollomi(A);const q=await A.evaluate(`
1
+ import*as s from"node:fs";import*as c from"node:path";import{CliError as n}from"@jackwener/opencli/errors";export const YOLLOMI_DOMAIN="yollomi.com";export async function ensureOnYollomi(t){const i=await t.evaluate("(() => location.href)()");if(!i||!i.includes("yollomi.com")){await t.goto("https://yollomi.com");await t.wait(3)}}export async function yollomiPost(t,i,a){const o=JSON.stringify(a);await ensureOnYollomi(t);const e=await t.evaluate(`
2
2
  (async () => {
3
3
  try {
4
- const res = await fetch(${JSON.stringify(B)}, {
4
+ const res = await fetch(${JSON.stringify(i)}, {
5
5
  method: 'POST',
6
6
  headers: { 'Content-Type': 'application/json' },
7
7
  credentials: 'include',
8
- body: ${JSON.stringify(F)},
8
+ body: ${JSON.stringify(o)},
9
9
  });
10
10
  const text = await res.text();
11
11
  return { ok: res.ok, status: res.status, body: text };
@@ -13,4 +13,4 @@ import*as L from"node:fs";import*as M from"node:path";import{CliError as K}from"
13
13
  return { ok: false, status: 0, body: err.message || 'fetch failed (on ' + location.href + ')' };
14
14
  }
15
15
  })()
16
- `);if(!q||q.status===0)throw new K("FETCH_ERROR",`Network error: ${q?.body||"Failed to fetch"}`,"Make sure Chrome is logged in to https://yollomi.com and the Browser Bridge is running");if(!q.ok){let H=q.body;try{H=JSON.parse(q.body)?.error||JSON.parse(q.body)?.message||q.body}catch{}throw new K("API_ERROR",`Yollomi API ${q.status}: ${H}`,q.status===401?"Not logged in — open Chrome, go to https://yollomi.com and log in":q.status===402?"Insufficient credits — top up at https://yollomi.com/pricing":q.status===429?"Rate limited — wait a moment and retry":"Check the model and parameters")}try{return JSON.parse(q.body)}catch{throw new K("API_ERROR","Invalid JSON response","Try again")}}export function resolveImageInput(A){if(A.startsWith("http://")||A.startsWith("https://")||A.startsWith("data:"))return A;const B=M.resolve(A);if(!L.existsSync(B))throw new K("FILE_NOT_FOUND",`File not found: ${B}`,"Provide a valid file path or URL");const G=M.extname(B).toLowerCase(),q={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"}[G]||"image/png",H=L.readFileSync(B);return`data:${q};base64,${H.toString("base64")}`}export async function downloadOutput(A,B,G){L.mkdirSync(B,{recursive:!0});const F=M.join(B,G),q=await fetch(A);if(!q.ok)throw new K("DOWNLOAD_ERROR",`Download failed: HTTP ${q.status}`,"URL may have expired");const H=Buffer.from(await q.arrayBuffer());L.writeFileSync(F,H);return{path:F,size:H.length}}export function fmtBytes(A){if(A===0)return"0 B";const B=1024,G=["B","KB","MB","GB"],F=Math.floor(Math.log(A)/Math.log(B));return`${(A/Math.pow(B,F)).toFixed(1)} ${G[F]}`}export const MODEL_ROUTES={flux:"/api/ai/flux","flux-schnell":"/api/ai/flux-schnell","flux-2-pro":"/api/ai/flux-2-pro","flux-kontext-pro":"/api/ai/flux-kontext-pro","nano-banana":"/api/ai/nano-banana","nano-banana-pro":"/api/ai/nano-banana-pro","nano-banana-2":"/api/ai/nano-banana-2","z-image-turbo":"/api/ai/z-image-turbo","imagen-4-ultra":"/api/ai/imagen-4-ultra","imagen-4-fast":"/api/ai/imagen-4-fast","ideogram-v3-turbo":"/api/ai/ideogram-v3-turbo","stable-diffusion-3-5-large":"/api/ai/stable-diffusion-3-5-large","seedream-4-5":"/api/ai/seedream-4-5","seedream-5-lite":"/api/ai/seedream-5-lite","qwen-image-edit":"/api/ai/qwen-image-edit","qwen-image-edit-plus":"/api/ai/qwen-image-edit-plus","remove-bg":"/api/ai/remove-bg","image-upscaler":"/api/ai/image-upscaler","face-swap":"/api/ai/face-swap","virtual-try-on":"/api/ai/virtual-try-on","photo-restoration":"/api/ai/photo-restoration","ai-background-generator":"/api/ai/ai-background-generator","object-remover":"/api/ai/object-remover"},IMAGE_MODELS={"z-image-turbo":{credits:1,description:"Alibaba Qwen turbo (cheapest, 1 credit)"},"flux-schnell":{credits:2,description:"High-speed Flux generation"},"ideogram-v3-turbo":{credits:3,description:"Ideogram V3 Turbo"},"imagen-4-fast":{credits:3,description:"Google Imagen 4 Fast"},"seedream-4-5":{credits:4,description:"Seedream 4.5 (ByteDance)"},"seedream-5-lite":{credits:4,description:"Seedream 5 Lite — 2K/3K"},flux:{credits:4,description:"Flux 1.1 Pro"},"nano-banana":{credits:4,description:"Google Nano Banana"},"flux-kontext-pro":{credits:4,description:"Flux Kontext Pro (img2img)"},"imagen-4-ultra":{credits:6,description:"Google Imagen 4 Ultra"},"nano-banana-2":{credits:7,description:"Google Nano Banana 2"},"stable-diffusion-3-5-large":{credits:7,description:"Stable Diffusion 3.5 Large"},"nano-banana-pro":{credits:15,description:"Nano Banana Pro"},"flux-2-pro":{credits:15,description:"Flux 2 Pro (premium)"}},VIDEO_MODELS={"kling-v2-6-motion-control":{credits:7,description:"Kling v2.6 Motion Control"},"bytedance-seedance-1-pro-fast":{credits:8,description:"Seedance 1.0 Pro Fast"},"kling-2-1":{credits:9,description:"Kling 2.1"},"minimax-hailuo-2-3":{credits:9,description:"Hailuo 2.3"},"pixverse-5":{credits:9,description:"PixVerse 5"},"wan-2-5-t2v":{credits:9,description:"Wan 2.5 Text-to-Video"},"wan-2-5-i2v":{credits:9,description:"Wan 2.5 Image-to-Video"},"google-veo-3-fast":{credits:9,description:"Google Veo 3 Fast"},"google-veo-3-1-fast":{credits:9,description:"Google Veo 3.1 Fast"},"openai-sora-2":{credits:10,description:"Sora 2"},"google-veo-3":{credits:10,description:"Google Veo 3"},"google-veo-3-1":{credits:10,description:"Google Veo 3.1"},"wan-2-6-t2v":{credits:29,description:"Wan 2.6 T2V (premium)"},"wan-2-6-i2v":{credits:29,description:"Wan 2.6 I2V (premium)"}},TOOL_MODELS={"remove-bg":{credits:0,description:"Remove background (free)"},"image-upscaler":{credits:1,description:"Enhance image resolution"},"object-remover":{credits:3,description:"Remove unwanted objects"},"face-swap":{credits:3,description:"Swap faces in photos"},"virtual-try-on":{credits:3,description:"Try clothes on photos"},"qwen-image-edit":{credits:3,description:"Edit image with text prompt"},"qwen-image-edit-plus":{credits:3,description:"Advanced image editing"},"photo-restoration":{credits:4,description:"Revive old/damaged photos"},"ai-background-generator":{credits:5,description:"Generate custom backgrounds"}};
16
+ `);if(!e||e.status===0)throw new n("FETCH_ERROR",`Network error: ${e?.body||"Failed to fetch"}`,"Make sure Chrome is logged in to https://yollomi.com and the Browser Bridge is running");if(!e.ok){let r=e.body;try{r=JSON.parse(e.body)?.error||JSON.parse(e.body)?.message||e.body}catch{}throw new n("API_ERROR",`Yollomi API ${e.status}: ${r}`,e.status===401?"Not logged in — open Chrome, go to https://yollomi.com and log in":e.status===402?"Insufficient credits — top up at https://yollomi.com/pricing":e.status===429?"Rate limited — wait a moment and retry":"Check the model and parameters")}try{return JSON.parse(e.body)}catch{throw new n("API_ERROR","Invalid JSON response","Try again")}}export function resolveImageInput(t){if(t.startsWith("http://")||t.startsWith("https://")||t.startsWith("data:"))return t;const i=c.resolve(t);if(!s.existsSync(i))throw new n("FILE_NOT_FOUND",`File not found: ${i}`,"Provide a valid file path or URL");const a=c.extname(i).toLowerCase(),e={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"}[a]||"image/png",r=s.readFileSync(i);return`data:${e};base64,${r.toString("base64")}`}export async function downloadOutput(t,i,a){s.mkdirSync(i,{recursive:!0});const o=c.join(i,a),e=await fetch(t);if(!e.ok)throw new n("DOWNLOAD_ERROR",`Download failed: HTTP ${e.status}`,"URL may have expired");const r=Buffer.from(await e.arrayBuffer());s.writeFileSync(o,r);return{path:o,size:r.length}}export function fmtBytes(t){if(t===0)return"0 B";const i=1024,a=["B","KB","MB","GB"],o=Math.floor(Math.log(t)/Math.log(i));return`${(t/Math.pow(i,o)).toFixed(1)} ${a[o]}`}export const MODEL_ROUTES={flux:"/api/ai/flux","flux-schnell":"/api/ai/flux-schnell","flux-2-pro":"/api/ai/flux-2-pro","flux-kontext-pro":"/api/ai/flux-kontext-pro","nano-banana":"/api/ai/nano-banana","nano-banana-pro":"/api/ai/nano-banana-pro","nano-banana-2":"/api/ai/nano-banana-2","z-image-turbo":"/api/ai/z-image-turbo","imagen-4-ultra":"/api/ai/imagen-4-ultra","imagen-4-fast":"/api/ai/imagen-4-fast","ideogram-v3-turbo":"/api/ai/ideogram-v3-turbo","stable-diffusion-3-5-large":"/api/ai/stable-diffusion-3-5-large","seedream-4-5":"/api/ai/seedream-4-5","seedream-5-lite":"/api/ai/seedream-5-lite","qwen-image-edit":"/api/ai/qwen-image-edit","qwen-image-edit-plus":"/api/ai/qwen-image-edit-plus","remove-bg":"/api/ai/remove-bg","image-upscaler":"/api/ai/image-upscaler","face-swap":"/api/ai/face-swap","virtual-try-on":"/api/ai/virtual-try-on","photo-restoration":"/api/ai/photo-restoration","ai-background-generator":"/api/ai/ai-background-generator","object-remover":"/api/ai/object-remover"},IMAGE_MODELS={"z-image-turbo":{credits:1,description:"Alibaba Qwen turbo (cheapest, 1 credit)"},"flux-schnell":{credits:2,description:"High-speed Flux generation"},"ideogram-v3-turbo":{credits:3,description:"Ideogram V3 Turbo"},"imagen-4-fast":{credits:3,description:"Google Imagen 4 Fast"},"seedream-4-5":{credits:4,description:"Seedream 4.5 (ByteDance)"},"seedream-5-lite":{credits:4,description:"Seedream 5 Lite — 2K/3K"},flux:{credits:4,description:"Flux 1.1 Pro"},"nano-banana":{credits:4,description:"Google Nano Banana"},"flux-kontext-pro":{credits:4,description:"Flux Kontext Pro (img2img)"},"imagen-4-ultra":{credits:6,description:"Google Imagen 4 Ultra"},"nano-banana-2":{credits:7,description:"Google Nano Banana 2"},"stable-diffusion-3-5-large":{credits:7,description:"Stable Diffusion 3.5 Large"},"nano-banana-pro":{credits:15,description:"Nano Banana Pro"},"flux-2-pro":{credits:15,description:"Flux 2 Pro (premium)"}},VIDEO_MODELS={"kling-v2-6-motion-control":{credits:7,description:"Kling v2.6 Motion Control"},"bytedance-seedance-1-pro-fast":{credits:8,description:"Seedance 1.0 Pro Fast"},"kling-2-1":{credits:9,description:"Kling 2.1"},"minimax-hailuo-2-3":{credits:9,description:"Hailuo 2.3"},"pixverse-5":{credits:9,description:"PixVerse 5"},"wan-2-5-t2v":{credits:9,description:"Wan 2.5 Text-to-Video"},"wan-2-5-i2v":{credits:9,description:"Wan 2.5 Image-to-Video"},"google-veo-3-fast":{credits:9,description:"Google Veo 3 Fast"},"google-veo-3-1-fast":{credits:9,description:"Google Veo 3.1 Fast"},"openai-sora-2":{credits:10,description:"Sora 2"},"google-veo-3":{credits:10,description:"Google Veo 3"},"google-veo-3-1":{credits:10,description:"Google Veo 3.1"},"wan-2-6-t2v":{credits:29,description:"Wan 2.6 T2V (premium)"},"wan-2-6-i2v":{credits:29,description:"Wan 2.6 I2V (premium)"}},TOOL_MODELS={"remove-bg":{credits:0,description:"Remove background (free)"},"image-upscaler":{credits:1,description:"Enhance image resolution"},"object-remover":{credits:3,description:"Remove unwanted objects"},"face-swap":{credits:3,description:"Swap faces in photos"},"virtual-try-on":{credits:3,description:"Try clothes on photos"},"qwen-image-edit":{credits:3,description:"Edit image with text prompt"},"qwen-image-edit-plus":{credits:3,description:"Advanced image editing"},"photo-restoration":{credits:4,description:"Revive old/damaged photos"},"ai-background-generator":{credits:5,description:"Generate custom backgrounds"}};
@@ -1 +1 @@
1
- import*as h from"node:path";import{cli as v,Strategy as g}from"@jackwener/opencli/registry";import{CliError as y}from"@jackwener/opencli/errors";import{log as n}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as w,yollomiPost as O,downloadOutput as I,fmtBytes as z}from"./utils.js";v({site:"yollomi",name:"video",access:"write",description:"Generate videos with AI (text-to-video or image-to-video)",domain:w,strategy:g.COOKIE,args:[{name:"prompt",fromFile:!0,positional:!0,required:!0,help:"Text prompt describing the video"},{name:"model",default:"kling-2-1",help:"Model (kling-2-1, openai-sora-2, google-veo-3-1, wan-2-5-t2v, ...)"},{name:"image",help:"Input image URL for image-to-video"},{name:"ratio",default:"16:9",choices:["1:1","16:9","9:16","4:3","3:4"],help:"Aspect ratio"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL, skip download"}],columns:["status","file","size","credits","url"],func:async(d,e)=>{const{prompt:l,model:i}=e,a={aspect_ratio:e.ratio};if(e.image)a.image=e.image;const s={modelId:i,prompt:l,inputs:a};n.status(`Generating video with ${i} (may take a while)...`);const r=await O(d,"/api/ai/video",s),t=r.video||"";if(!t)throw new y("EMPTY_RESPONSE","No video returned","Try a different prompt or model");const o=r.remainingCredits,m=e["no-download"],p=e.output;if(m)return[{status:"generated",file:"-",size:"-",credits:o??"-",url:t}];try{const u=`yollomi_${i}_${Date.now()}.mp4`,{path:c,size:f}=await I(t,p,u);if(o!==void 0)n.status(`Credits remaining: ${o}`);return[{status:"saved",file:h.relative(".",c),size:z(f),credits:o??"-",url:t}]}catch{return[{status:"download-failed",file:"-",size:"-",credits:o??"-",url:t}]}}});
1
+ import*as h from"node:path";import{cli as v,Strategy as y}from"@jackwener/opencli/registry";import{CliError as g}from"@jackwener/opencli/errors";import{log as n}from"@jackwener/opencli/logger";import{YOLLOMI_DOMAIN as w,yollomiPost as O,downloadOutput as I,fmtBytes as z}from"./utils.js";v({site:"yollomi",name:"video",access:"write",description:"Generate videos with AI (text-to-video or image-to-video)",domain:w,strategy:y.COOKIE,args:[{name:"prompt",fromFile:!0,positional:!0,required:!0,help:"Text prompt describing the video"},{name:"model",default:"kling-2-1",help:"Model (kling-2-1, openai-sora-2, google-veo-3-1, wan-2-5-t2v, ...)"},{name:"image",help:"Input image URL for image-to-video"},{name:"ratio",default:"16:9",choices:["1:1","16:9","9:16","4:3","3:4"],help:"Aspect ratio"},{name:"output",default:"./yollomi-output",help:"Output directory"},{name:"no-download",type:"boolean",default:!1,help:"Only show URL, skip download"}],columns:["status","file","size","credits","url"],func:async(l,e)=>{const{prompt:d,model:i}=e,a={aspect_ratio:e.ratio};if(e.image)a.image=e.image;const s={modelId:i,prompt:d,inputs:a};n.status(`Generating video with ${i} (may take a while)...`);const r=await O(l,"/api/ai/video",s),t=r.video||"";if(!t)throw new g("EMPTY_RESPONSE","No video returned","Try a different prompt or model");const o=r.remainingCredits,m=e["no-download"],p=e.output;if(m)return[{status:"generated",file:"-",size:"-",credits:o??"-",url:t}];try{const u=`yollomi_${i}_${Date.now()}.mp4`,{path:c,size:f}=await I(t,p,u);if(o!==void 0)n.status(`Credits remaining: ${o}`);return[{status:"saved",file:h.relative(".",c),size:z(f),credits:o??"-",url:t}]}catch{return[{status:"download-failed",file:"-",size:"-",credits:o??"-",url:t}]}}});
@@ -1,7 +1,7 @@
1
- import{cli as W,Strategy as X}from"@jackwener/opencli/registry";import{CommandExecutionError as U}from"@jackwener/opencli/errors";export function extractSelectedRichGridContents(L){const H=L?.contents?.twoColumnBrowseResultsRenderer?.tabs||[],J=(q)=>q?.tabRenderer?.content?.richGridRenderer?.contents,K=H.find((q)=>q?.tabRenderer?.selected),A=J(K);if(Array.isArray(A))return A;const B=J(H.find((q)=>{const F=J(q);return Array.isArray(F)&&F.length>0}))||J(H.find((q)=>Array.isArray(J(q))));return Array.isArray(B)?B:[]}export function parseVideoItem(L){const H=L?.richItemRenderer?.content||L||{},J=(B)=>{const q=String(B||"").trim();return/^[A-Za-z0-9_-]+$/.test(q)?q:""},K=H.lockupViewModel;if(K&&K.contentType==="LOCKUP_CONTENT_TYPE_VIDEO"){const B=J(K.contentId),q=K.metadata?.lockupMetadataViewModel,F=q?.title?.content||"";if(!B||!F)return null;const N=((q?.metadata?.contentMetadataViewModel?.metadataRows||[])[0]?.metadataParts||[]).map((O)=>O.text?.content).filter(Boolean);let P="";for(const O of K.contentImage?.thumbnailViewModel?.overlays||[])for(const Q of O.thumbnailBottomOverlayViewModel?.badges||[])if(Q.thumbnailBadgeViewModel?.text)P=Q.thumbnailBadgeViewModel.text;return{title:F,duration:P,views:N.join(" | "),url:"https://www.youtube.com/watch?v="+B}}const A=H.videoRenderer||H.gridVideoRenderer;if(A){const B=J(A.videoId),q=A.title?.runs?.[0]?.text||A.title?.simpleText||"";if(!B||!q)return null;return{title:q,duration:A.lengthText?.simpleText||A.thumbnailOverlays?.find((F)=>F.thumbnailOverlayTimeStatusRenderer)?.thumbnailOverlayTimeStatusRenderer?.text?.simpleText||"",views:(A.shortViewCountText?.simpleText||"")+(A.publishedTimeText?.simpleText?" | "+A.publishedTimeText.simpleText:""),url:"https://www.youtube.com/watch?v="+B}}return null}W({site:"youtube",name:"channel",access:"read",description:"Get YouTube channel info and recent videos",domain:"www.youtube.com",strategy:X.COOKIE,args:[{name:"id",required:!0,positional:!0,help:"Channel ID (UCxxxx) or handle (@name)"},{name:"limit",type:"int",default:10,help:"Max recent videos (max 30)"}],columns:["field","value"],func:async(L,H)=>{const J=String(H.id),K=Math.min(H.limit||10,30);await L.goto("https://www.youtube.com");await L.wait(2);const A=await L.evaluate(`
1
+ import{cli as h,Strategy as p}from"@jackwener/opencli/registry";import{CommandExecutionError as m}from"@jackwener/opencli/errors";export function extractSelectedRichGridContents(i){const r=i?.contents?.twoColumnBrowseResultsRenderer?.tabs||[],a=(e)=>e?.tabRenderer?.content?.richGridRenderer?.contents,s=r.find((e)=>e?.tabRenderer?.selected),t=a(s);if(Array.isArray(t))return t;const n=a(r.find((e)=>{const o=a(e);return Array.isArray(o)&&o.length>0}))||a(r.find((e)=>Array.isArray(a(e))));return Array.isArray(n)?n:[]}export function parseVideoItem(i){const r=i?.richItemRenderer?.content||i||{},a=(n)=>{const e=String(n||"").trim();return/^[A-Za-z0-9_-]+$/.test(e)?e:""},s=r.lockupViewModel;if(s&&s.contentType==="LOCKUP_CONTENT_TYPE_VIDEO"){const n=a(s.contentId),e=s.metadata?.lockupMetadataViewModel,o=e?.title?.content||"";if(!n||!o)return null;const c=((e?.metadata?.contentMetadataViewModel?.metadataRows||[])[0]?.metadataParts||[]).map((l)=>l.text?.content).filter(Boolean);let u="";for(const l of s.contentImage?.thumbnailViewModel?.overlays||[])for(const b of l.thumbnailBottomOverlayViewModel?.badges||[])if(b.thumbnailBadgeViewModel?.text)u=b.thumbnailBadgeViewModel.text;return{title:o,duration:u,views:c.join(" | "),url:"https://www.youtube.com/watch?v="+n}}const t=r.videoRenderer||r.gridVideoRenderer;if(t){const n=a(t.videoId),e=t.title?.runs?.[0]?.text||t.title?.simpleText||"";if(!n||!e)return null;return{title:e,duration:t.lengthText?.simpleText||t.thumbnailOverlays?.find((o)=>o.thumbnailOverlayTimeStatusRenderer)?.thumbnailOverlayTimeStatusRenderer?.text?.simpleText||"",views:(t.shortViewCountText?.simpleText||"")+(t.publishedTimeText?.simpleText?" | "+t.publishedTimeText.simpleText:""),url:"https://www.youtube.com/watch?v="+n}}return null}h({site:"youtube",name:"channel",access:"read",description:"Get YouTube channel info and recent videos",domain:"www.youtube.com",strategy:p.COOKIE,args:[{name:"id",required:!0,positional:!0,help:"Channel ID (UCxxxx) or handle (@name)"},{name:"limit",type:"int",default:10,help:"Max recent videos (max 30)"}],columns:["field","value"],func:async(i,r)=>{const a=String(r.id),s=Math.min(r.limit||10,30);await i.goto("https://www.youtube.com");await i.wait(2);const t=await i.evaluate(`
2
2
  (async () => {
3
- const channelId = ${JSON.stringify(J)};
4
- const limit = ${K};
3
+ const channelId = ${JSON.stringify(a)};
4
+ const limit = ${s};
5
5
  const cfg = window.ytcfg?.data_ || {};
6
6
  const apiKey = cfg.INNERTUBE_API_KEY;
7
7
  const context = cfg.INNERTUBE_CONTEXT;
@@ -115,4 +115,4 @@ import{cli as W,Strategy as X}from"@jackwener/opencli/registry";import{CommandEx
115
115
  recentVideos,
116
116
  };
117
117
  })()
118
- `);if(!A||typeof A!=="object")throw new U("Failed to fetch channel data");if(A.error)throw new U(String(A.error));const B=A,q=B.recentVideos;delete B.recentVideos;const F=Object.entries(B).map(([M,N])=>({field:M,value:String(N)}));if(q&&q.length>0){F.push({field:"---",value:"--- Recent Videos ---"});for(const M of q)F.push({field:M.title,value:`${M.duration} | ${M.views} | ${M.url}`})}return F}});export const __test__={extractSelectedRichGridContents,parseVideoItem};
118
+ `);if(!t||typeof t!=="object")throw new m("Failed to fetch channel data");if(t.error)throw new m(String(t.error));const n=t,e=n.recentVideos;delete n.recentVideos;const o=Object.entries(n).map(([d,c])=>({field:d,value:String(c)}));if(e&&e.length>0){o.push({field:"---",value:"--- Recent Videos ---"});for(const d of e)o.push({field:d.title,value:`${d.duration} | ${d.views} | ${d.url}`})}return o}});export const __test__={extractSelectedRichGridContents,parseVideoItem};
@@ -1,4 +1,4 @@
1
- import{cli as a,Strategy as r}from"@jackwener/opencli/registry";import{CommandExecutionError as s,EmptyResultError as d}from"@jackwener/opencli/errors";a({site:"youtube",name:"feed",access:"read",description:"Get YouTube homepage recommended videos",domain:"www.youtube.com",strategy:r.COOKIE,args:[{name:"limit",type:"int",default:20,help:"Max videos to return (default 20, max 100)"}],columns:["rank","title","channel","video_id","views","duration","published","url"],func:async(t,o)=>{const n=Math.min(o.limit||20,100);await t.goto("https://www.youtube.com");await t.wait(3);const e=await t.evaluate(`
1
+ import{cli as a,Strategy as r}from"@jackwener/opencli/registry";import{CommandExecutionError as s,EmptyResultError as d}from"@jackwener/opencli/errors";a({site:"youtube",name:"feed",access:"read",description:"Get YouTube homepage recommended videos",domain:"www.youtube.com",strategy:r.COOKIE,args:[{name:"limit",type:"int",default:20,help:"Max videos to return (default 20, max 100)"}],columns:["rank","title","channel","video_id","views","duration","published","url"],func:async(e,o)=>{const n=Math.min(o.limit||20,100);await e.goto("https://www.youtube.com");await e.wait(3);const t=await e.evaluate(`
2
2
  (async () => {
3
3
  const d = window.ytInitialData;
4
4
  if (!d) return { error: 'YouTube data not found — are you logged in?' };
@@ -86,4 +86,4 @@ import{cli as a,Strategy as r}from"@jackwener/opencli/registry";import{CommandEx
86
86
 
87
87
  return videos;
88
88
  })()
89
- `);if(!Array.isArray(e)){const i=e&&typeof e==="object"?String(e.error||""):"";throw new s(i||"Failed to fetch YouTube feed")}if(e.length===0)throw new d("youtube feed");return e}});
89
+ `);if(!Array.isArray(t)){const i=t&&typeof t==="object"?String(t.error||""):"";throw new s(i||"Failed to fetch YouTube feed")}if(t.length===0)throw new d("youtube feed");return t}});
@@ -1,13 +1,13 @@
1
- import{cli as O,Strategy as Q}from"@jackwener/opencli/registry";import{parseVideoId as T,prepareYoutubeApiPage as U,readYoutubeSapisid as W,SAPISID_HASH_FN as X}from"./utils.js";import{CommandExecutionError as Z,AuthRequiredError as L}from"@jackwener/opencli/errors";O({site:"youtube",name:"like",access:"write",description:"Like a YouTube video",domain:"www.youtube.com",strategy:Q.COOKIE,args:[{name:"url",required:!0,positional:!0,help:"YouTube video URL or video ID"}],columns:["status","message"],func:async(B,M)=>{const J=T(String(M.url));await U(B);const K=await W(B);if(!K)throw new L("www.youtube.com","Not logged in (SAPISID cookie missing)");const G=await B.evaluate(`
1
+ import{cli as a,Strategy as u}from"@jackwener/opencli/registry";import{parseVideoId as n,prepareYoutubeApiPage as c,readYoutubeSapisid as d,SAPISID_HASH_FN as g}from"./utils.js";import{CommandExecutionError as w,AuthRequiredError as s}from"@jackwener/opencli/errors";a({site:"youtube",name:"like",access:"write",description:"Like a YouTube video",domain:"www.youtube.com",strategy:u.COOKIE,args:[{name:"url",required:!0,positional:!0,help:"YouTube video URL or video ID"}],columns:["status","message"],func:async(e,i)=>{const r=n(String(i.url));await c(e);const o=await d(e);if(!o)throw new s("www.youtube.com","Not logged in (SAPISID cookie missing)");const t=await e.evaluate(`
2
2
  (async () => {
3
- ${X}
3
+ ${g}
4
4
 
5
5
  const cfg = window.ytcfg?.data_ || {};
6
6
  const apiKey = cfg.INNERTUBE_API_KEY;
7
7
  const context = cfg.INNERTUBE_CONTEXT;
8
8
  if (!apiKey || !context) return { error: 'config', message: 'YouTube config not found' };
9
9
 
10
- const authHash = await getSapisidHash(${JSON.stringify(K)}, 'https://www.youtube.com');
10
+ const authHash = await getSapisidHash(${JSON.stringify(o)}, 'https://www.youtube.com');
11
11
  if (!authHash) return { error: 'auth', message: 'Not logged in (SAPISID cookie missing)' };
12
12
 
13
13
  const resp = await fetch('/youtubei/v1/like/like?key=' + apiKey + '&prettyPrint=false', {
@@ -18,7 +18,7 @@ import{cli as O,Strategy as Q}from"@jackwener/opencli/registry";import{parseVide
18
18
  'Authorization': authHash,
19
19
  'X-Origin': 'https://www.youtube.com',
20
20
  },
21
- body: JSON.stringify({ context, target: { videoId: ${JSON.stringify(J)} } }),
21
+ body: JSON.stringify({ context, target: { videoId: ${JSON.stringify(r)} } }),
22
22
  });
23
23
 
24
24
  if (resp.status === 401 || resp.status === 403) return { error: 'auth', message: 'Not logged in' };
@@ -30,4 +30,4 @@ import{cli as O,Strategy as Q}from"@jackwener/opencli/registry";import{parseVide
30
30
  }
31
31
  return { ok: true };
32
32
  })()
33
- `);if(G?.error==="auth")throw new L("www.youtube.com");if(G?.error)throw new Z(G.message||"Failed to like video");return[{status:"success",message:"Liked: "+J}]}});
33
+ `);if(t?.error==="auth")throw new s("www.youtube.com");if(t?.error)throw new w(t.message||"Failed to like video");return[{status:"success",message:"Liked: "+r}]}});
@@ -1,14 +1,14 @@
1
- import{cli as M,Strategy as Q}from"@jackwener/opencli/registry";import{prepareYoutubeApiPage as X,FETCH_BROWSE_FN as Z,extractPlaylistVideos as $}from"./utils.js";import{CommandExecutionError as z,EmptyResultError as f}from"@jackwener/opencli/errors";function A(q){if(!q.startsWith("http"))return q;try{return new URL(q).searchParams.get("list")||q}catch{return q}}M({site:"youtube",name:"playlist",access:"read",description:"Get YouTube playlist info and video list",domain:"www.youtube.com",strategy:Q.COOKIE,args:[{name:"id",required:!0,positional:!0,help:"Playlist URL or playlist ID (PLxxxxxx)"},{name:"limit",type:"int",default:50,help:"Max videos to return (default 50, max 200)"}],columns:["rank","title","channel","duration","views","published","url"],func:async(q,v)=>{const G=A(String(v.id)),J=Math.min(v.limit||50,200);await X(q);const h=await q.evaluate(`
1
+ import{cli as s,Strategy as c}from"@jackwener/opencli/registry";import{prepareYoutubeApiPage as d,FETCH_BROWSE_FN as l,extractPlaylistVideos as m}from"./utils.js";import{CommandExecutionError as o,EmptyResultError as u}from"@jackwener/opencli/errors";function p(e){if(!e.startsWith("http"))return e;try{return new URL(e).searchParams.get("list")||e}catch{return e}}s({site:"youtube",name:"playlist",access:"read",description:"Get YouTube playlist info and video list",domain:"www.youtube.com",strategy:c.COOKIE,args:[{name:"id",required:!0,positional:!0,help:"Playlist URL or playlist ID (PLxxxxxx)"},{name:"limit",type:"int",default:50,help:"Max videos to return (default 50, max 200)"}],columns:["rank","title","channel","duration","views","published","url"],func:async(e,n)=>{const a=p(String(n.id)),i=Math.min(n.limit||50,200);await d(e);const t=await e.evaluate(`
2
2
  (async () => {
3
3
  const cfg = window.ytcfg?.data_ || {};
4
4
  const apiKey = cfg.INNERTUBE_API_KEY;
5
5
  const context = cfg.INNERTUBE_CONTEXT;
6
6
  if (!apiKey || !context) return { error: 'YouTube config not found' };
7
7
 
8
- const browseId = 'VL' + ${JSON.stringify(G)};
9
- const limit = ${J};
8
+ const browseId = 'VL' + ${JSON.stringify(a)};
9
+ const limit = ${i};
10
10
 
11
- ${Z}
11
+ ${l}
12
12
 
13
13
  const data = await fetchBrowse(apiKey, { context, browseId });
14
14
  if (data.error) return data;
@@ -25,7 +25,7 @@ import{cli as M,Strategy as Q}from"@jackwener/opencli/registry";import{prepareYo
25
25
  const tabs = data.contents?.twoColumnBrowseResultsRenderer?.tabs || [];
26
26
  let listContents = tabs[0]?.tabRenderer?.content?.sectionListRenderer?.contents?.[0]?.itemSectionRenderer?.contents?.[0]?.playlistVideoListRenderer?.contents || [];
27
27
 
28
- const extractVideos = ${$.toString()};
28
+ const extractVideos = ${m.toString()};
29
29
 
30
30
  let videos = extractVideos(listContents);
31
31
 
@@ -43,5 +43,5 @@ import{cli as M,Strategy as Q}from"@jackwener/opencli/registry";import{prepareYo
43
43
 
44
44
  return { title, channelName, stats, videos: videos.slice(0, limit) };
45
45
  })()
46
- `);if(!h||typeof h!=="object")throw new z("Failed to fetch playlist data");if(h.error)throw new z(String(h.error));if(!h.videos?.length)throw new f("youtube playlist");const K=(h.stats||[]).join(" | ");process.stderr.write(`${h.title} [${h.channelName}] ${K}
47
- `);return h.videos}});
46
+ `);if(!t||typeof t!=="object")throw new o("Failed to fetch playlist data");if(t.error)throw new o(String(t.error));if(!t.videos?.length)throw new u("youtube playlist");const r=(t.stats||[]).join(" | ");process.stderr.write(`${t.title} [${t.channelName}] ${r}
47
+ `);return t.videos}});
@@ -1,4 +1,4 @@
1
- import{cli as U,Strategy as _}from"@jackwener/opencli/registry";import{ArgumentError as C,CommandExecutionError as X}from"@jackwener/opencli/errors";import{resolveVideoFile as h,resolveImageFile as y,setVideoInput as B,unwrap as Z,currentUrl as F,waitForSelector as D,videoTimeoutArg as v}from"../_shared/video-publish.js";const S="https://www.youtube.com/upload",O={public:"PUBLIC",unlisted:"UNLISTED",private:"PRIVATE"},Y=`
1
+ import{cli as _,Strategy as S}from"@jackwener/opencli/registry";import{ArgumentError as T,CommandExecutionError as s}from"@jackwener/opencli/errors";import{resolveVideoFile as E,resolveImageFile as I,setVideoInput as h,unwrap as u,currentUrl as V,waitForSelector as w,videoTimeoutArg as C}from"../_shared/video-publish.js";const P="https://www.youtube.com/upload",v={public:"PUBLIC",unlisted:"UNLISTED",private:"PRIVATE"},p=`
2
2
  function __ytNorm(v) { return (v || '').replace(/\\s+/g, ' ').trim(); }
3
3
  function __ytVisible(el) {
4
4
  if (!el || el.offsetParent === null) return false;
@@ -27,19 +27,19 @@ import{cli as U,Strategy as _}from"@jackwener/opencli/registry";import{ArgumentE
27
27
  }
28
28
  return null;
29
29
  }
30
- `;async function G(q,z,H=4000){const Q=Date.now()+H;for(;;){if(Boolean(Z(await q.evaluate(`
30
+ `;async function e(t,i,a=4000){const r=Date.now()+a;for(;;){if(Boolean(u(await t.evaluate(`
31
31
  (() => {
32
- ${Y}
33
- var el = __ytResolve(${JSON.stringify(z)});
32
+ ${p}
33
+ var el = __ytResolve(${JSON.stringify(i)});
34
34
  if (!el) return false;
35
35
  el.click();
36
36
  return true;
37
37
  })()
38
- `))))return!0;if(Date.now()>=Q)return!1;await q.wait({time:0.4})}}async function M(q,z){return Boolean(Z(await q.evaluate(`
39
- (() => { ${Y} return !!__ytResolve(${JSON.stringify(z)}); })()
40
- `)))}async function L(q){try{await q.evaluate("() => { const a = document.activeElement; if (a && a.blur) a.blur(); }")}catch{}try{if(Boolean(Z(await q.evaluate(`
41
- (() => { ${Y} return !!__ytResolve('tp-yt-iron-dropdown'); })()
42
- `)))){await q.pressKey("Escape");await q.wait({time:0.2})}}catch{}}async function R(q,z,H){if(!await D(q,z,30000))throw new X(`YouTube 输入框未出现: ${z}`);await q.click(z);await q.pressKey("Control+a");await q.pressKey("Delete");await q.insertText(H);await q.wait({time:0.4});await L(q)}async function b(q,z=360){const H=/处理|检查|上传完成|已上传|Processing|complete|Checks|Finished/;for(let Q=0;Q<z;Q++){const W=String(Z(await q.evaluate(`
38
+ `))))return!0;if(Date.now()>=r)return!1;await t.wait({time:0.4})}}async function m(t,i){return Boolean(u(await t.evaluate(`
39
+ (() => { ${p} return !!__ytResolve(${JSON.stringify(i)}); })()
40
+ `)))}async function B(t){try{await t.evaluate("() => { const a = document.activeElement; if (a && a.blur) a.blur(); }")}catch{}try{if(Boolean(u(await t.evaluate(`
41
+ (() => { ${p} return !!__ytResolve('tp-yt-iron-dropdown'); })()
42
+ `)))){await t.pressKey("Escape");await t.wait({time:0.2})}}catch{}}async function x(t,i,a){if(!await w(t,i,30000))throw new s(`YouTube 输入框未出现: ${i}`);await t.click(i);await t.pressKey("Control+a");await t.pressKey("Delete");await t.insertText(a);await t.wait({time:0.4});await B(t)}async function O(t,i=360){const a=/处理|检查|上传完成|已上传|Processing|complete|Checks|Finished/;for(let r=0;r<i;r++){const l=String(u(await t.evaluate(`
43
43
  (() => {
44
44
  const sels = ['.progress-label', 'span.progress-label', 'ytcp-video-upload-progress'];
45
45
  for (const sel of sels) {
@@ -48,9 +48,9 @@ import{cli as U,Strategy as _}from"@jackwener/opencli/registry";import{ArgumentE
48
48
  }
49
49
  return '';
50
50
  })()
51
- `))||"");if(W&&H.test(W))return!0;await q.wait({time:5})}return!1}U({site:"youtube",name:"publish",access:"write",description:"Publish a video to YouTube via Studio (one command: upload + metadata + publish)",domain:"www.youtube.com",strategy:_.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"video",required:!0,positional:!0,help:"Video file path"},{name:"title",required:!0,help:"Video title (≤100 chars)"},{name:"description",fromFile:!0,default:"",help:"Video description"},{name:"tags",default:"",help:"Comma-separated tags"},{name:"thumbnail",default:"",help:"Thumbnail image path (optional)"},{name:"playlist",default:"",help:"Playlist name to add to (optional)"},{name:"visibility",default:"public",choices:["public","unlisted","private"],help:"Visibility"},v()],columns:["status","title","visibility","url"],func:async(q,z)=>{const H=String(z.title??"").trim();if(!H)throw new C("--title is required");const Q=h(z.video),W=String(z.description||""),j=z.thumbnail?y(z.thumbnail):"",$=String(z.playlist||"").trim(),T=O[z.visibility]?z.visibility:"public";await q.goto(S);await q.wait({time:3});const A=await F(q);if(/accounts\.google\.com/.test(A)||/signin/i.test(A))throw new X("YouTube 登录态失效,请先 ppcli youtube login");if(!await D(q,'input[type="file"]',60000))throw new X("YouTube 上传文件输入框未出现");await B(q,['input[type="file"]'],[Q]);if(!await D(q,"#title-textarea",120000))throw new X("YouTube 视频详情对话框未出现");await R(q,"#title-textarea #textbox",H.slice(0,100));if(W.trim())await R(q,"#description-textarea #textbox",W);if(j)try{await B(q,["#file-loader input[type='file']","ytcp-thumbnail-uploader input[type='file']"],[j]);await q.wait({time:2})}catch{}if($)try{await G(q,"#basics ytcp-text-dropdown-trigger, ytcp-video-metadata-playlists ytcp-dropdown-trigger",8000);await q.wait({time:1.2});const K=`tp-yt-paper-checkbox:has-text('${$}'), ytcp-checkbox-group:has-text('${$}')`;if(await M(q,K))await G(q,K,3000);else if(await G(q,"ytcp-button:has-text('New playlist'), ytcp-button:has-text('创建播放列表')",4000)){await q.wait({time:0.8});await G(q,"tp-yt-paper-item:has-text('New playlist'), tp-yt-paper-item:has-text('新建播放列表')",3000);const J="ytcp-playlist-metadata-editor #textbox, #create-playlist-form #textbox";if(await D(q,J.split(",")[0].trim(),4000)||await M(q,J)){await G(q,J,2000);await q.insertText($);await G(q,"ytcp-button#create-button, tp-yt-paper-dialog ytcp-button:has-text('Create'), tp-yt-paper-dialog ytcp-button:has-text('创建')",4000)}}}catch{}finally{await G(q,"ytcp-playlist-dialog #save-button, ytcp-button:has-text('Done'), ytcp-button:has-text('完成')",3000);await q.pressKey("Escape");await q.wait({time:0.6})}if(!await G(q,"tp-yt-paper-radio-button[name='VIDEO_MADE_FOR_KIDS_NOT_MFK']",1e4))await G(q,"tp-yt-paper-radio-button:has-text('not made for kids'), tp-yt-paper-radio-button:has-text('不是面向儿童')",6000);if(z.tags){const K=String(z.tags).split(",").map((J)=>J.trim()).filter(Boolean).join(",");try{await G(q,"#toggle-button",6000);await q.wait({time:0.8});const J="#tags-container #text-input, ytcp-form-input-container#tags-container input";if(await M(q,J)){await G(q,J,3000);await q.insertText(`${K.slice(0,500)},`)}}catch{}}for(let K=0;K<5;K++){if(await M(q,"tp-yt-paper-radio-button[name='PUBLIC']"))break;if(!await G(q,"#next-button",6000))await q.wait({time:1.2});await q.wait({time:1})}await G(q,`tp-yt-paper-radio-button[name='${O[T]}']`,1e4);await b(q);await q.wait({time:1.2});let N="";if(!await G(q,"#done-button",15000))throw new X("未找到 YouTube 发布按钮(上传可能未到可发布进度),请在窗口内手动发布");await q.wait({time:4});N=String(Z(await q.evaluate(`
51
+ `))||"");if(l&&a.test(l))return!0;await t.wait({time:5})}return!1}_({site:"youtube",name:"publish",access:"write",description:"Publish a video to YouTube via Studio (one command: upload + metadata + publish)",domain:"www.youtube.com",strategy:S.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"video",required:!0,positional:!0,help:"Video file path"},{name:"title",required:!0,help:"Video title (≤100 chars)"},{name:"description",fromFile:!0,default:"",help:"Video description"},{name:"tags",default:"",help:"Comma-separated tags"},{name:"thumbnail",default:"",help:"Thumbnail image path (optional)"},{name:"playlist",default:"",help:"Playlist name to add to (optional)"},{name:"visibility",default:"public",choices:["public","unlisted","private"],help:"Visibility"},C()],columns:["status","title","visibility","url"],func:async(t,i)=>{const a=String(i.title??"").trim();if(!a)throw new T("--title is required");const r=E(i.video),l=String(i.description||""),y=i.thumbnail?I(i.thumbnail):"",c=String(i.playlist||"").trim(),d=v[i.visibility]?i.visibility:"public";await t.goto(P);await t.wait({time:3});const f=await V(t);if(/accounts\.google\.com/.test(f)||/signin/i.test(f))throw new s("YouTube 登录态失效,请先 ppcli youtube login");if(!await w(t,'input[type="file"]',60000))throw new s("YouTube 上传文件输入框未出现");await h(t,['input[type="file"]'],[r]);if(!await w(t,"#title-textarea",120000))throw new s("YouTube 视频详情对话框未出现");await x(t,"#title-textarea #textbox",a.slice(0,100));if(l.trim())await x(t,"#description-textarea #textbox",l);if(y)try{await h(t,["#file-loader input[type='file']","ytcp-thumbnail-uploader input[type='file']"],[y]);await t.wait({time:2})}catch{}if(c)try{await e(t,"#basics ytcp-text-dropdown-trigger, ytcp-video-metadata-playlists ytcp-dropdown-trigger",8000);await t.wait({time:1.2});const n=`tp-yt-paper-checkbox:has-text('${c}'), ytcp-checkbox-group:has-text('${c}')`;if(await m(t,n))await e(t,n,3000);else if(await e(t,"ytcp-button:has-text('New playlist'), ytcp-button:has-text('创建播放列表')",4000)){await t.wait({time:0.8});await e(t,"tp-yt-paper-item:has-text('New playlist'), tp-yt-paper-item:has-text('新建播放列表')",3000);const o="ytcp-playlist-metadata-editor #textbox, #create-playlist-form #textbox";if(await w(t,o.split(",")[0].trim(),4000)||await m(t,o)){await e(t,o,2000);await t.insertText(c);await e(t,"ytcp-button#create-button, tp-yt-paper-dialog ytcp-button:has-text('Create'), tp-yt-paper-dialog ytcp-button:has-text('创建')",4000)}}}catch{}finally{await e(t,"ytcp-playlist-dialog #save-button, ytcp-button:has-text('Done'), ytcp-button:has-text('完成')",3000);await t.pressKey("Escape");await t.wait({time:0.6})}if(!await e(t,"tp-yt-paper-radio-button[name='VIDEO_MADE_FOR_KIDS_NOT_MFK']",1e4))await e(t,"tp-yt-paper-radio-button:has-text('not made for kids'), tp-yt-paper-radio-button:has-text('不是面向儿童')",6000);if(i.tags){const n=String(i.tags).split(",").map((o)=>o.trim()).filter(Boolean).join(",");try{await e(t,"#toggle-button",6000);await t.wait({time:0.8});const o="#tags-container #text-input, ytcp-form-input-container#tags-container input";if(await m(t,o)){await e(t,o,3000);await t.insertText(`${n.slice(0,500)},`)}}catch{}}for(let n=0;n<5;n++){if(await m(t,"tp-yt-paper-radio-button[name='PUBLIC']"))break;if(!await e(t,"#next-button",6000))await t.wait({time:1.2});await t.wait({time:1})}await e(t,`tp-yt-paper-radio-button[name='${v[d]}']`,1e4);await O(t);await t.wait({time:1.2});let b="";if(!await e(t,"#done-button",15000))throw new s("未找到 YouTube 发布按钮(上传可能未到可发布进度),请在窗口内手动发布");await t.wait({time:4});b=String(u(await t.evaluate(`
52
52
  (() => {
53
53
  const a = document.querySelector("a[href*='youtu.be'], a[href*='watch?v=']");
54
54
  return a ? (a.getAttribute('href') || '') : '';
55
55
  })()
56
- `))||"");await G(q,"ytcp-button:has-text('Close'), ytcp-button:has-text('关闭'), #close-button",8000);return[{status:"✅ Published",title:H,visibility:T,url:N}]}});
56
+ `))||"");await e(t,"ytcp-button:has-text('Close'), ytcp-button:has-text('关闭'), #close-button",8000);return[{status:"✅ Published",title:a,visibility:d,url:b}]}});
@@ -1,4 +1,4 @@
1
- import{cli as E,Strategy as F}from"@jackwener/opencli/registry";E({site:"youtube",name:"search",access:"read",description:"Search YouTube videos",domain:"www.youtube.com",strategy:F.COOKIE,args:[{name:"query",required:!0,positional:!0,help:"Search query"},{name:"limit",type:"int",default:20,help:"Max results (max 50)"},{name:"type",default:"",help:"Filter type: shorts, video, channel, playlist"},{name:"upload",default:"",help:"Upload date: hour, today, week, month, year"},{name:"sort",default:"",help:"Sort by: relevance, date, views, rating"}],columns:["rank","title","channel","views","duration","published","url"],func:async(x,b)=>{const C=Math.min(b.limit||20,50),D=encodeURIComponent(b.query),v={shorts:"EgIQCQ%3D%3D",video:"EgIQAQ%3D%3D",channel:"EgIQAg%3D%3D",playlist:"EgIQAw%3D%3D",hour:"EgIIAQ%3D%3D",today:"EgIIAg%3D%3D",week:"EgIIAw%3D%3D",month:"EgIIBA%3D%3D",year:"EgIIBQ%3D%3D"},z={date:"CAI%3D",views:"CAM%3D",rating:"CAE%3D"};let f="";if(b.type&&v[b.type])f=v[b.type];else if(b.upload&&v[b.upload])f=v[b.upload];else if(b.sort&&z[b.sort])f=z[b.sort];let A=`https://www.youtube.com/results?search_query=${D}`;if(f)A+=`&sp=${f}`;await x.goto(A);await x.wait(3);const B=await x.evaluate(`
1
+ import{cli as d,Strategy as u}from"@jackwener/opencli/registry";d({site:"youtube",name:"search",access:"read",description:"Search YouTube videos",domain:"www.youtube.com",strategy:u.COOKIE,args:[{name:"query",required:!0,positional:!0,help:"Search query"},{name:"limit",type:"int",default:20,help:"Max results (max 50)"},{name:"type",default:"",help:"Filter type: shorts, video, channel, playlist"},{name:"upload",default:"",help:"Upload date: hour, today, week, month, year"},{name:"sort",default:"",help:"Sort by: relevance, date, views, rating"}],columns:["rank","title","channel","views","duration","published","url"],func:async(r,e)=>{const a=Math.min(e.limit||20,50),l=encodeURIComponent(e.query),n={shorts:"EgIQCQ%3D%3D",video:"EgIQAQ%3D%3D",channel:"EgIQAg%3D%3D",playlist:"EgIQAw%3D%3D",hour:"EgIIAQ%3D%3D",today:"EgIIAg%3D%3D",week:"EgIIAw%3D%3D",month:"EgIIBA%3D%3D",year:"EgIIBQ%3D%3D"},i={date:"CAI%3D",views:"CAM%3D",rating:"CAE%3D"};let t="";if(e.type&&n[e.type])t=n[e.type];else if(e.upload&&n[e.upload])t=n[e.upload];else if(e.sort&&i[e.sort])t=i[e.sort];let o=`https://www.youtube.com/results?search_query=${l}`;if(t)o+=`&sp=${t}`;await r.goto(o);await r.wait(3);const s=await r.evaluate(`
2
2
  (async () => {
3
3
  const data = window.ytInitialData;
4
4
  if (!data) return {error: 'YouTube data not found'};
@@ -8,7 +8,7 @@ import{cli as E,Strategy as F}from"@jackwener/opencli/registry";E({site:"youtube
8
8
  for (const section of contents) {
9
9
  const items = section.itemSectionRenderer?.contents || section.reelShelfRenderer?.items || [];
10
10
  for (const item of items) {
11
- if (videos.length >= ${C}) break;
11
+ if (videos.length >= ${a}) break;
12
12
  if (item.videoRenderer) {
13
13
  const v = item.videoRenderer;
14
14
  videos.push({
@@ -36,4 +36,4 @@ import{cli as E,Strategy as F}from"@jackwener/opencli/registry";E({site:"youtube
36
36
  }
37
37
  return videos;
38
38
  })()
39
- `);if(!Array.isArray(B))return[];return B}});
39
+ `);if(!Array.isArray(s))return[];return s}});
@@ -1,22 +1,22 @@
1
- import{cli as T,Strategy as U}from"@jackwener/opencli/registry";import{prepareYoutubeApiPage as W,readYoutubeSapisid as X,SAPISID_HASH_FN as Z,RESOLVE_CHANNEL_HANDLE_FN as $}from"./utils.js";import{CommandExecutionError as f,AuthRequiredError as M}from"@jackwener/opencli/errors";T({site:"youtube",name:"subscribe",access:"write",description:"Subscribe to a YouTube channel",domain:"www.youtube.com",strategy:U.COOKIE,args:[{name:"channel",required:!0,positional:!0,help:"Channel ID (UCxxxx) or handle (@name)"}],columns:["status","message"],func:async(G,Q)=>{const J=String(Q.channel);await W(G);const K=await X(G);if(!K)throw new M("www.youtube.com","Not logged in (SAPISID cookie missing)");const B=await G.evaluate(`
1
+ import{cli as o,Strategy as i}from"@jackwener/opencli/registry";import{prepareYoutubeApiPage as u,readYoutubeSapisid as c,SAPISID_HASH_FN as h,RESOLVE_CHANNEL_HANDLE_FN as d}from"./utils.js";import{CommandExecutionError as l,AuthRequiredError as n}from"@jackwener/opencli/errors";o({site:"youtube",name:"subscribe",access:"write",description:"Subscribe to a YouTube channel",domain:"www.youtube.com",strategy:i.COOKIE,args:[{name:"channel",required:!0,positional:!0,help:"Channel ID (UCxxxx) or handle (@name)"}],columns:["status","message"],func:async(t,a)=>{const r=String(a.channel);await u(t);const s=await c(t);if(!s)throw new n("www.youtube.com","Not logged in (SAPISID cookie missing)");const e=await t.evaluate(`
2
2
  (async () => {
3
- ${Z}
3
+ ${h}
4
4
 
5
5
  const cfg = window.ytcfg?.data_ || {};
6
6
  const apiKey = cfg.INNERTUBE_API_KEY;
7
7
  const context = cfg.INNERTUBE_CONTEXT;
8
8
  if (!apiKey || !context) return { error: 'config', message: 'YouTube config not found' };
9
9
 
10
- const authHash = await getSapisidHash(${JSON.stringify(K)}, 'https://www.youtube.com');
10
+ const authHash = await getSapisidHash(${JSON.stringify(s)}, 'https://www.youtube.com');
11
11
  if (!authHash) return { error: 'auth', message: 'Not logged in (SAPISID cookie missing)' };
12
12
 
13
- ${$}
13
+ ${d}
14
14
 
15
- let channelId = ${JSON.stringify(J)};
15
+ let channelId = ${JSON.stringify(r)};
16
16
  channelId = await resolveChannelHandle(channelId, apiKey, context);
17
17
 
18
18
  if (!channelId.startsWith('UC')) {
19
- return { error: 'arg', message: 'Could not resolve channel ID from: ' + ${JSON.stringify(J)} };
19
+ return { error: 'arg', message: 'Could not resolve channel ID from: ' + ${JSON.stringify(r)} };
20
20
  }
21
21
 
22
22
  const resp = await fetch('/youtubei/v1/subscription/subscribe?key=' + apiKey + '&prettyPrint=false', {
@@ -39,4 +39,4 @@ import{cli as T,Strategy as U}from"@jackwener/opencli/registry";import{prepareYo
39
39
  }
40
40
  return { ok: true, channelId };
41
41
  })()
42
- `);if(B?.error==="auth")throw new M("www.youtube.com");if(B?.error)throw new f(B.message||"Failed to subscribe");return[{status:"success",message:"Subscribed to: "+(B.channelId||J)}]}});
42
+ `);if(e?.error==="auth")throw new n("www.youtube.com");if(e?.error)throw new l(e.message||"Failed to subscribe");return[{status:"success",message:"Subscribed to: "+(e.channelId||r)}]}});
@@ -1,4 +1,4 @@
1
- import{cli as i,Strategy as a}from"@jackwener/opencli/registry";import{CommandExecutionError as c,EmptyResultError as u}from"@jackwener/opencli/errors";import{extractSubscriptionChannel as l}from"./utils.js";i({site:"youtube",name:"subscriptions",access:"read",description:"List subscribed YouTube channels",domain:"www.youtube.com",strategy:a.COOKIE,args:[{name:"limit",type:"int",default:50,help:"Max channels to return (default 50)"}],columns:["rank","name","handle","subscribers","url"],func:async(t,r)=>{const o=Math.min(r.limit||50,1000);await t.goto("https://www.youtube.com/feed/channels");await t.wait(3);const e=await t.evaluate(`
1
+ import{cli as a,Strategy as i}from"@jackwener/opencli/registry";import{CommandExecutionError as c,EmptyResultError as u}from"@jackwener/opencli/errors";import{extractSubscriptionChannel as l}from"./utils.js";a({site:"youtube",name:"subscriptions",access:"read",description:"List subscribed YouTube channels",domain:"www.youtube.com",strategy:i.COOKIE,args:[{name:"limit",type:"int",default:50,help:"Max channels to return (default 50)"}],columns:["rank","name","handle","subscribers","url"],func:async(t,r)=>{const o=Math.min(r.limit||50,1000);await t.goto("https://www.youtube.com/feed/channels");await t.wait(3);const e=await t.evaluate(`
2
2
  (async () => {
3
3
  const d = window.ytInitialData;
4
4
  if (!d) return { error: 'YouTube data not found — are you logged in?' };
@@ -1,2 +1,2 @@
1
- const y=/[.!?\u3002\uFF01\uFF1F\uFF0E]["'\u2019\u201D)]*\s*$/,F=/[?\uFF1F]["'\u2019\u201D)]*\s*$/,M=20,A=80,U=45,D=3,G=8;function H(q){return q.split(/\s+/).filter(Boolean).length}export function groupTranscriptSegments(q){if(q.length===0)return[];return q.some((j)=>/^>>/.test(j.text))?b(q):B(q)}export function formatGroupedTranscript(q,K=[]){const j=[...K].sort((z,Y)=>z.start-Y.start);let J=0;const V=[],L=[];for(const z of q){while(J<j.length&&j[J].start<=z.start){const $=j[J].title;V.push({timestamp:k(j[J].start),speaker:"",text:`[Chapter] ${$}`});if(L.length>0)L.push("");L.push(`### ${$}`);L.push("");J++}const Y=k(z.start),Z=z.speaker!==void 0?`Speaker ${z.speaker+1}`:"";V.push({timestamp:Y,speaker:Z,text:z.text});if(z.speakerChange&&L.length>0)L.push("");L.push(`${Y} ${z.text}`)}return{rows:V,plainText:L.join(`
2
- `)}}function k(q){const K=Math.floor(q/3600),j=Math.floor(q%3600/60),J=Math.floor(q%60);if(K>0)return`${K}:${String(j).padStart(2,"0")}:${String(J).padStart(2,"0")}`;return`${j}:${String(J).padStart(2,"0")}`}const O=30;function B(q){const K=[];let j="",J=0,V=0;const L=()=>{if(j.trim()){K.push({start:J,text:j.trim(),speakerChange:!1});j=""}};for(const z of q){if(j&&z.start-V>M)L();if(j&&z.start-J>O)L();if(!j)J=z.start;j+=(j?" ":"")+z.text;V=z.start;if(y.test(z.text))L()}L();return K}function b(q){const K=[];let j=null,J=-1,V="";for(const z of q){const Y=/^>>/.test(z.text),Z=z.text.replace(/^>>\s*/,"").replace(/^-\s+/,""),$=/,\s*$/.test(V),Q=(y.test(V)||!V)&&!$;if(Y&&Q){if(j)K.push(j);J=(J+1)%2;j={start:z.start,segments:[{start:z.start,text:Z}],speakerChange:!0,speaker:J}}else{if(!j)j={start:z.start,segments:[],speakerChange:!1};j.segments.push({start:z.start,text:Z})}V=Z}if(j)K.push(j);C(K);const L=[];for(const z of K){const Y=z.speaker===void 0?B(z.segments):l(B(z.segments));for(let Z=0;Z<Y.length;Z++)L.push({...Y[Z],speakerChange:Z===0&&z.speakerChange,speaker:z.speaker})}return L}function C(q){const K=/^(mhm|yeah|yes|yep|right|okay|ok|absolutely|sure|exactly|uh-huh|mm-hmm)[.!,]?\s+/i;for(let j=0;j<q.length;j++){const J=q[j];if(J.speaker===void 0||J.segments.length===0)continue;const V=J.segments[0],L=K.exec(V.text);if(!L)continue;if(/,\s*$/.test(L[0]))continue;const z=V.text.slice(L[0].length).trim(),Y=J.segments.slice(1);if(H(z)+Y.reduce((X,w)=>X+H(w.text),0)<30)continue;const $=L[0].trimEnd(),Q=z?[{start:V.start,text:z},...Y]:Y;q.splice(j,1,{start:J.start,segments:[{start:V.start,text:$}],speakerChange:J.speakerChange,speaker:J.speaker},{start:Q[0].start,segments:Q,speakerChange:!0,speaker:J.speaker===0?1:0});j++}}function l(q){if(q.length<=1)return q;const K=[];let j={...q[0]},J=!0;for(let V=1;V<q.length;V++){const L=q[V];if(W(j,L,J)){j.text=`${j.text} ${L.text}`;continue}K.push(j);j={...L};J=!1}K.push(j);return K}function W(q,K,j){const J=H(q.text),V=H(K.text);if(v(q.text,J)||v(K.text,V))return!1;if(j&&J<G)return!1;if(F.test(q.text)||F.test(K.text))return!1;if(J+V>A)return!1;if(K.start-q.start>U)return!1;return!0}function v(q,K){const j=K??H(q);return j>0&&j<=D&&y.test(q)}
1
+ const h=/[.!?\u3002\uFF01\uFF1F\uFF0E]["'\u2019\u201D)]*\s*$/,S=/[?\uFF1F]["'\u2019\u201D)]*\s*$/,d=20,_=80,C=45,E=3,T=8;function f(e){return e.split(/\s+/).filter(Boolean).length}export function groupTranscriptSegments(e){if(e.length===0)return[];return e.some((t)=>/^>>/.test(t.text))?N(e):l(e)}export function formatGroupedTranscript(e,n=[]){const t=[...n].sort((s,i)=>s.start-i.start);let r=0;const o=[],a=[];for(const s of e){while(r<t.length&&t[r].start<=s.start){const c=t[r].title;o.push({timestamp:m(t[r].start),speaker:"",text:`[Chapter] ${c}`});if(a.length>0)a.push("");a.push(`### ${c}`);a.push("");r++}const i=m(s.start),u=s.speaker!==void 0?`Speaker ${s.speaker+1}`:"";o.push({timestamp:i,speaker:u,text:s.text});if(s.speakerChange&&a.length>0)a.push("");a.push(`${i} ${s.text}`)}return{rows:o,plainText:a.join(`
2
+ `)}}function m(e){const n=Math.floor(e/3600),t=Math.floor(e%3600/60),r=Math.floor(e%60);if(n>0)return`${n}:${String(t).padStart(2,"0")}:${String(r).padStart(2,"0")}`;return`${t}:${String(r).padStart(2,"0")}`}const R=30;function l(e){const n=[];let t="",r=0,o=0;const a=()=>{if(t.trim()){n.push({start:r,text:t.trim(),speakerChange:!1});t=""}};for(const s of e){if(t&&s.start-o>d)a();if(t&&s.start-r>R)a();if(!t)r=s.start;t+=(t?" ":"")+s.text;o=s.start;if(h.test(s.text))a()}a();return n}function N(e){const n=[];let t=null,r=-1,o="";for(const s of e){const i=/^>>/.test(s.text),u=s.text.replace(/^>>\s*/,"").replace(/^-\s+/,""),c=/,\s*$/.test(o),p=(h.test(o)||!o)&&!c;if(i&&p){if(t)n.push(t);r=(r+1)%2;t={start:s.start,segments:[{start:s.start,text:u}],speakerChange:!0,speaker:r}}else{if(!t)t={start:s.start,segments:[],speakerChange:!1};t.segments.push({start:s.start,text:u})}o=u}if(t)n.push(t);M(n);const a=[];for(const s of n){const i=s.speaker===void 0?l(s.segments):F(l(s.segments));for(let u=0;u<i.length;u++)a.push({...i[u],speakerChange:u===0&&s.speakerChange,speaker:s.speaker})}return a}function M(e){const n=/^(mhm|yeah|yes|yep|right|okay|ok|absolutely|sure|exactly|uh-huh|mm-hmm)[.!,]?\s+/i;for(let t=0;t<e.length;t++){const r=e[t];if(r.speaker===void 0||r.segments.length===0)continue;const o=r.segments[0],a=n.exec(o.text);if(!a)continue;if(/,\s*$/.test(a[0]))continue;const s=o.text.slice(a[0].length).trim(),i=r.segments.slice(1);if(f(s)+i.reduce((g,k)=>g+f(k.text),0)<30)continue;const c=a[0].trimEnd(),p=s?[{start:o.start,text:s},...i]:i;e.splice(t,1,{start:r.start,segments:[{start:o.start,text:c}],speakerChange:r.speakerChange,speaker:r.speaker},{start:p[0].start,segments:p,speakerChange:!0,speaker:r.speaker===0?1:0});t++}}function F(e){if(e.length<=1)return e;const n=[];let t={...e[0]},r=!0;for(let o=1;o<e.length;o++){const a=e[o];if(G(t,a,r)){t.text=`${t.text} ${a.text}`;continue}n.push(t);t={...a};r=!1}n.push(t);return n}function G(e,n,t){const r=f(e.text),o=f(n.text);if(x(e.text,r)||x(n.text,o))return!1;if(t&&r<T)return!1;if(S.test(e.text)||S.test(n.text))return!1;if(r+o>_)return!1;if(n.start-e.start>C)return!1;return!0}function x(e,n){const t=n??f(e);return t>0&&t<=E&&h.test(e)}