@zenalexa/unicli 0.219.0 → 0.220.0

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 (430) hide show
  1. package/AGENTS.md +9 -9
  2. package/README.md +55 -249
  3. package/README.zh-CN.md +55 -249
  4. package/dist/adapters/1point3acres/forum.d.ts +58 -0
  5. package/dist/adapters/1point3acres/forum.d.ts.map +1 -0
  6. package/dist/adapters/1point3acres/forum.js +708 -0
  7. package/dist/adapters/1point3acres/forum.js.map +1 -0
  8. package/dist/adapters/aibase/news.d.ts +21 -0
  9. package/dist/adapters/aibase/news.d.ts.map +1 -0
  10. package/dist/adapters/aibase/news.js +96 -0
  11. package/dist/adapters/aibase/news.js.map +1 -0
  12. package/dist/adapters/arxiv/papers.d.ts +27 -0
  13. package/dist/adapters/arxiv/papers.d.ts.map +1 -0
  14. package/dist/adapters/arxiv/papers.js +193 -0
  15. package/dist/adapters/arxiv/papers.js.map +1 -0
  16. package/dist/adapters/bbc/topic.d.ts +24 -0
  17. package/dist/adapters/bbc/topic.d.ts.map +1 -0
  18. package/dist/adapters/bbc/topic.js +122 -0
  19. package/dist/adapters/bbc/topic.js.map +1 -0
  20. package/dist/adapters/chatgpt/web.d.ts +24 -0
  21. package/dist/adapters/chatgpt/web.d.ts.map +1 -0
  22. package/dist/adapters/chatgpt/web.js +242 -0
  23. package/dist/adapters/chatgpt/web.js.map +1 -0
  24. package/dist/adapters/claude/web.d.ts +24 -0
  25. package/dist/adapters/claude/web.d.ts.map +1 -0
  26. package/dist/adapters/claude/web.js +575 -0
  27. package/dist/adapters/claude/web.js.map +1 -0
  28. package/dist/adapters/codex/projects.d.ts +27 -0
  29. package/dist/adapters/codex/projects.d.ts.map +1 -0
  30. package/dist/adapters/codex/projects.js +147 -0
  31. package/dist/adapters/codex/projects.js.map +1 -0
  32. package/dist/adapters/coingecko/markets.d.ts +19 -0
  33. package/dist/adapters/coingecko/markets.d.ts.map +1 -0
  34. package/dist/adapters/coingecko/markets.js +474 -0
  35. package/dist/adapters/coingecko/markets.js.map +1 -0
  36. package/dist/adapters/coupang/product.d.ts +27 -0
  37. package/dist/adapters/coupang/product.d.ts.map +1 -0
  38. package/dist/adapters/coupang/product.js +211 -0
  39. package/dist/adapters/coupang/product.js.map +1 -0
  40. package/dist/adapters/crates/registry.d.ts +44 -0
  41. package/dist/adapters/crates/registry.d.ts.map +1 -0
  42. package/dist/adapters/crates/registry.js +186 -0
  43. package/dist/adapters/crates/registry.js.map +1 -0
  44. package/dist/adapters/ctrip/travel.d.ts +83 -0
  45. package/dist/adapters/ctrip/travel.d.ts.map +1 -0
  46. package/dist/adapters/ctrip/travel.js +630 -0
  47. package/dist/adapters/ctrip/travel.js.map +1 -0
  48. package/dist/adapters/dblp/publications.d.ts +41 -0
  49. package/dist/adapters/dblp/publications.d.ts.map +1 -0
  50. package/dist/adapters/dblp/publications.js +409 -0
  51. package/dist/adapters/dblp/publications.js.map +1 -0
  52. package/dist/adapters/deepseek/web.d.ts +1 -1
  53. package/dist/adapters/deepseek/web.d.ts.map +1 -1
  54. package/dist/adapters/deepseek/web.js +66 -1
  55. package/dist/adapters/deepseek/web.js.map +1 -1
  56. package/dist/adapters/defillama/protocols.d.ts +13 -0
  57. package/dist/adapters/defillama/protocols.d.ts.map +1 -0
  58. package/dist/adapters/defillama/protocols.js +218 -0
  59. package/dist/adapters/defillama/protocols.js.map +1 -0
  60. package/dist/adapters/devto/read.d.ts +26 -0
  61. package/dist/adapters/devto/read.d.ts.map +1 -0
  62. package/dist/adapters/devto/read.js +110 -0
  63. package/dist/adapters/devto/read.js.map +1 -0
  64. package/dist/adapters/dianping/shop.d.ts +38 -0
  65. package/dist/adapters/dianping/shop.d.ts.map +1 -0
  66. package/dist/adapters/dianping/shop.js +194 -0
  67. package/dist/adapters/dianping/shop.js.map +1 -0
  68. package/dist/adapters/dockerhub/registry.d.ts +36 -0
  69. package/dist/adapters/dockerhub/registry.d.ts.map +1 -0
  70. package/dist/adapters/dockerhub/registry.js +172 -0
  71. package/dist/adapters/dockerhub/registry.js.map +1 -0
  72. package/dist/adapters/endoflife/product.d.ts +11 -0
  73. package/dist/adapters/endoflife/product.d.ts.map +1 -0
  74. package/dist/adapters/endoflife/product.js +113 -0
  75. package/dist/adapters/endoflife/product.js.map +1 -0
  76. package/dist/adapters/facebook/marketplace-extra.d.ts +9 -0
  77. package/dist/adapters/facebook/marketplace-extra.d.ts.map +1 -0
  78. package/dist/adapters/facebook/marketplace-extra.js +170 -0
  79. package/dist/adapters/facebook/marketplace-extra.js.map +1 -0
  80. package/dist/adapters/flathub/apps.d.ts +17 -0
  81. package/dist/adapters/flathub/apps.d.ts.map +1 -0
  82. package/dist/adapters/flathub/apps.js +220 -0
  83. package/dist/adapters/flathub/apps.js.map +1 -0
  84. package/dist/adapters/goproxy/module.d.ts +24 -0
  85. package/dist/adapters/goproxy/module.d.ts.map +1 -0
  86. package/dist/adapters/goproxy/module.js +221 -0
  87. package/dist/adapters/goproxy/module.js.map +1 -0
  88. package/dist/adapters/grok/web.d.ts +29 -0
  89. package/dist/adapters/grok/web.d.ts.map +1 -0
  90. package/dist/adapters/grok/web.js +553 -0
  91. package/dist/adapters/grok/web.js.map +1 -0
  92. package/dist/adapters/hackernews/read.d.ts +31 -0
  93. package/dist/adapters/hackernews/read.d.ts.map +1 -0
  94. package/dist/adapters/hackernews/read.js +201 -0
  95. package/dist/adapters/hackernews/read.js.map +1 -0
  96. package/dist/adapters/hf/paper.d.ts +22 -0
  97. package/dist/adapters/hf/paper.d.ts.map +1 -0
  98. package/dist/adapters/hf/paper.js +112 -0
  99. package/dist/adapters/hf/paper.js.map +1 -0
  100. package/dist/adapters/homebrew/packages.d.ts +52 -0
  101. package/dist/adapters/homebrew/packages.d.ts.map +1 -0
  102. package/dist/adapters/homebrew/packages.js +240 -0
  103. package/dist/adapters/homebrew/packages.js.map +1 -0
  104. package/dist/adapters/indeed/jobs.d.ts +38 -0
  105. package/dist/adapters/indeed/jobs.d.ts.map +1 -0
  106. package/dist/adapters/indeed/jobs.js +300 -0
  107. package/dist/adapters/indeed/jobs.js.map +1 -0
  108. package/dist/adapters/instagram/collections.d.ts +9 -0
  109. package/dist/adapters/instagram/collections.d.ts.map +1 -0
  110. package/dist/adapters/instagram/collections.js +174 -0
  111. package/dist/adapters/instagram/collections.js.map +1 -0
  112. package/dist/adapters/lichess/players.d.ts +46 -0
  113. package/dist/adapters/lichess/players.d.ts.map +1 -0
  114. package/dist/adapters/lichess/players.js +221 -0
  115. package/dist/adapters/lichess/players.js.map +1 -0
  116. package/dist/adapters/lobsters/read-domain.d.ts +35 -0
  117. package/dist/adapters/lobsters/read-domain.d.ts.map +1 -0
  118. package/dist/adapters/lobsters/read-domain.js +306 -0
  119. package/dist/adapters/lobsters/read-domain.js.map +1 -0
  120. package/dist/adapters/maven/artifact.d.ts +30 -0
  121. package/dist/adapters/maven/artifact.d.ts.map +1 -0
  122. package/dist/adapters/maven/artifact.js +121 -0
  123. package/dist/adapters/maven/artifact.js.map +1 -0
  124. package/dist/adapters/mdn/search.d.ts +11 -0
  125. package/dist/adapters/mdn/search.d.ts.map +1 -0
  126. package/dist/adapters/mdn/search.js +115 -0
  127. package/dist/adapters/mdn/search.js.map +1 -0
  128. package/dist/adapters/medium/tag.d.ts +15 -0
  129. package/dist/adapters/medium/tag.d.ts.map +1 -0
  130. package/dist/adapters/medium/tag.js +148 -0
  131. package/dist/adapters/medium/tag.js.map +1 -0
  132. package/dist/adapters/npm/package.d.ts +32 -0
  133. package/dist/adapters/npm/package.d.ts.map +1 -0
  134. package/dist/adapters/npm/package.js +141 -0
  135. package/dist/adapters/npm/package.js.map +1 -0
  136. package/dist/adapters/nuget/package.d.ts +34 -0
  137. package/dist/adapters/nuget/package.d.ts.map +1 -0
  138. package/dist/adapters/nuget/package.js +135 -0
  139. package/dist/adapters/nuget/package.js.map +1 -0
  140. package/dist/adapters/nvd/cve.d.ts +42 -0
  141. package/dist/adapters/nvd/cve.d.ts.map +1 -0
  142. package/dist/adapters/nvd/cve.js +132 -0
  143. package/dist/adapters/nvd/cve.js.map +1 -0
  144. package/dist/adapters/oeis/sequences.d.ts +14 -0
  145. package/dist/adapters/oeis/sequences.d.ts.map +1 -0
  146. package/dist/adapters/oeis/sequences.js +219 -0
  147. package/dist/adapters/oeis/sequences.js.map +1 -0
  148. package/dist/adapters/openalex/works.d.ts +43 -0
  149. package/dist/adapters/openalex/works.d.ts.map +1 -0
  150. package/dist/adapters/openalex/works.js +267 -0
  151. package/dist/adapters/openalex/works.js.map +1 -0
  152. package/dist/adapters/openfda/records.d.ts +18 -0
  153. package/dist/adapters/openfda/records.d.ts.map +1 -0
  154. package/dist/adapters/openfda/records.js +209 -0
  155. package/dist/adapters/openfda/records.js.map +1 -0
  156. package/dist/adapters/openreview/papers.d.ts +34 -0
  157. package/dist/adapters/openreview/papers.d.ts.map +1 -0
  158. package/dist/adapters/openreview/papers.js +463 -0
  159. package/dist/adapters/openreview/papers.js.map +1 -0
  160. package/dist/adapters/osv/security.d.ts +36 -0
  161. package/dist/adapters/osv/security.d.ts.map +1 -0
  162. package/dist/adapters/osv/security.js +247 -0
  163. package/dist/adapters/osv/security.js.map +1 -0
  164. package/dist/adapters/packagist/package.d.ts +31 -0
  165. package/dist/adapters/packagist/package.d.ts.map +1 -0
  166. package/dist/adapters/packagist/package.js +108 -0
  167. package/dist/adapters/packagist/package.js.map +1 -0
  168. package/dist/adapters/pubmed/articles.d.ts +31 -0
  169. package/dist/adapters/pubmed/articles.d.ts.map +1 -0
  170. package/dist/adapters/pubmed/articles.js +385 -0
  171. package/dist/adapters/pubmed/articles.js.map +1 -0
  172. package/dist/adapters/pypi/package.d.ts +38 -0
  173. package/dist/adapters/pypi/package.d.ts.map +1 -0
  174. package/dist/adapters/pypi/package.js +235 -0
  175. package/dist/adapters/pypi/package.js.map +1 -0
  176. package/dist/adapters/qwen/web.d.ts +26 -0
  177. package/dist/adapters/qwen/web.d.ts.map +1 -0
  178. package/dist/adapters/qwen/web.js +672 -0
  179. package/dist/adapters/qwen/web.js.map +1 -0
  180. package/dist/adapters/reddit/account.d.ts +12 -0
  181. package/dist/adapters/reddit/account.d.ts.map +1 -0
  182. package/dist/adapters/reddit/account.js +409 -0
  183. package/dist/adapters/reddit/account.js.map +1 -0
  184. package/dist/adapters/rednote/web.d.ts +30 -0
  185. package/dist/adapters/rednote/web.d.ts.map +1 -0
  186. package/dist/adapters/rednote/web.js +858 -0
  187. package/dist/adapters/rednote/web.js.map +1 -0
  188. package/dist/adapters/rest-countries/countries.d.ts +14 -0
  189. package/dist/adapters/rest-countries/countries.d.ts.map +1 -0
  190. package/dist/adapters/rest-countries/countries.js +231 -0
  191. package/dist/adapters/rest-countries/countries.js.map +1 -0
  192. package/dist/adapters/reuters/article-detail.d.ts +37 -0
  193. package/dist/adapters/reuters/article-detail.d.ts.map +1 -0
  194. package/dist/adapters/reuters/article-detail.js +139 -0
  195. package/dist/adapters/reuters/article-detail.js.map +1 -0
  196. package/dist/adapters/rfc/rfc.d.ts +11 -0
  197. package/dist/adapters/rfc/rfc.d.ts.map +1 -0
  198. package/dist/adapters/rfc/rfc.js +121 -0
  199. package/dist/adapters/rfc/rfc.js.map +1 -0
  200. package/dist/adapters/rubygems/gem.d.ts +26 -0
  201. package/dist/adapters/rubygems/gem.d.ts.map +1 -0
  202. package/dist/adapters/rubygems/gem.js +96 -0
  203. package/dist/adapters/rubygems/gem.js.map +1 -0
  204. package/dist/adapters/stackoverflow/questions.d.ts +79 -0
  205. package/dist/adapters/stackoverflow/questions.d.ts.map +1 -0
  206. package/dist/adapters/stackoverflow/questions.js +504 -0
  207. package/dist/adapters/stackoverflow/questions.js.map +1 -0
  208. package/dist/adapters/steam/app.d.ts +39 -0
  209. package/dist/adapters/steam/app.d.ts.map +1 -0
  210. package/dist/adapters/steam/app.js +165 -0
  211. package/dist/adapters/steam/app.js.map +1 -0
  212. package/dist/adapters/tiktok/creator-videos.d.ts +52 -0
  213. package/dist/adapters/tiktok/creator-videos.d.ts.map +1 -0
  214. package/dist/adapters/tiktok/creator-videos.js +267 -0
  215. package/dist/adapters/tiktok/creator-videos.js.map +1 -0
  216. package/dist/adapters/tvmaze/shows.d.ts +13 -0
  217. package/dist/adapters/tvmaze/shows.d.ts.map +1 -0
  218. package/dist/adapters/tvmaze/shows.js +240 -0
  219. package/dist/adapters/tvmaze/shows.js.map +1 -0
  220. package/dist/adapters/twitter/bookmark-folders.d.ts +33 -0
  221. package/dist/adapters/twitter/bookmark-folders.d.ts.map +1 -0
  222. package/dist/adapters/twitter/bookmark-folders.js +290 -0
  223. package/dist/adapters/twitter/bookmark-folders.js.map +1 -0
  224. package/dist/adapters/twitter/quote.d.ts +18 -0
  225. package/dist/adapters/twitter/quote.d.ts.map +1 -0
  226. package/dist/adapters/twitter/quote.js +285 -0
  227. package/dist/adapters/twitter/quote.js.map +1 -0
  228. package/dist/adapters/twitter/tweet-actions.d.ts +12 -0
  229. package/dist/adapters/twitter/tweet-actions.d.ts.map +1 -0
  230. package/dist/adapters/twitter/tweet-actions.js +145 -0
  231. package/dist/adapters/twitter/tweet-actions.js.map +1 -0
  232. package/dist/adapters/twitter/tweet-url.d.ts +15 -0
  233. package/dist/adapters/twitter/tweet-url.d.ts.map +1 -0
  234. package/dist/adapters/twitter/tweet-url.js +57 -0
  235. package/dist/adapters/twitter/tweet-url.js.map +1 -0
  236. package/dist/adapters/uisdc/news.d.ts +22 -0
  237. package/dist/adapters/uisdc/news.d.ts.map +1 -0
  238. package/dist/adapters/uisdc/news.js +91 -0
  239. package/dist/adapters/uisdc/news.js.map +1 -0
  240. package/dist/adapters/weibo/favorites-publish.d.ts +28 -0
  241. package/dist/adapters/weibo/favorites-publish.d.ts.map +1 -0
  242. package/dist/adapters/weibo/favorites-publish.js +356 -0
  243. package/dist/adapters/weibo/favorites-publish.js.map +1 -0
  244. package/dist/adapters/wikidata/entities.d.ts +15 -0
  245. package/dist/adapters/wikidata/entities.d.ts.map +1 -0
  246. package/dist/adapters/wikidata/entities.js +219 -0
  247. package/dist/adapters/wikidata/entities.js.map +1 -0
  248. package/dist/adapters/wikipedia/page.d.ts +21 -0
  249. package/dist/adapters/wikipedia/page.d.ts.map +1 -0
  250. package/dist/adapters/wikipedia/page.js +116 -0
  251. package/dist/adapters/wikipedia/page.js.map +1 -0
  252. package/dist/adapters/wttr/weather.d.ts +12 -0
  253. package/dist/adapters/wttr/weather.d.ts.map +1 -0
  254. package/dist/adapters/wttr/weather.js +207 -0
  255. package/dist/adapters/wttr/weather.js.map +1 -0
  256. package/dist/adapters/xianyu/publish.d.ts +31 -0
  257. package/dist/adapters/xianyu/publish.d.ts.map +1 -0
  258. package/dist/adapters/xianyu/publish.js +349 -0
  259. package/dist/adapters/xianyu/publish.js.map +1 -0
  260. package/dist/adapters/xiaohongshu/user-helpers.d.ts +2 -2
  261. package/dist/adapters/xiaohongshu/user-helpers.d.ts.map +1 -1
  262. package/dist/adapters/xiaohongshu/user-helpers.js +5 -4
  263. package/dist/adapters/xiaohongshu/user-helpers.js.map +1 -1
  264. package/dist/adapters/yuanbao/web.d.ts +27 -0
  265. package/dist/adapters/yuanbao/web.d.ts.map +1 -0
  266. package/dist/adapters/yuanbao/web.js +365 -0
  267. package/dist/adapters/yuanbao/web.js.map +1 -0
  268. package/dist/adapters/zhihu/collection.d.ts +33 -0
  269. package/dist/adapters/zhihu/collection.d.ts.map +1 -0
  270. package/dist/adapters/zhihu/collection.js +185 -0
  271. package/dist/adapters/zhihu/collection.js.map +1 -0
  272. package/dist/adapters/zlibrary/web.d.ts +19 -0
  273. package/dist/adapters/zlibrary/web.d.ts.map +1 -0
  274. package/dist/adapters/zlibrary/web.js +153 -0
  275. package/dist/adapters/zlibrary/web.js.map +1 -0
  276. package/dist/browser/daemon-client.js +2 -2
  277. package/dist/browser/daemon-client.js.map +1 -1
  278. package/dist/discovery/macos-dynamic.d.ts.map +1 -1
  279. package/dist/discovery/macos-dynamic.js +17 -3
  280. package/dist/discovery/macos-dynamic.js.map +1 -1
  281. package/dist/manifest-compact.txt +10 -10
  282. package/dist/manifest-search.json +1 -1
  283. package/dist/manifest.json +5130 -112
  284. package/dist/transport/refs.d.ts +5 -3
  285. package/dist/transport/refs.d.ts.map +1 -1
  286. package/dist/transport/refs.js +8 -1
  287. package/dist/transport/refs.js.map +1 -1
  288. package/dist/transport/sidecar-binary.d.ts +7 -0
  289. package/dist/transport/sidecar-binary.d.ts.map +1 -1
  290. package/dist/transport/sidecar-binary.js +28 -8
  291. package/dist/transport/sidecar-binary.js.map +1 -1
  292. package/package.json +4 -3
  293. package/server.json +3 -3
  294. package/skills/unicli/SKILL.md +1 -1
  295. package/skills/unicli-claude-code/SKILL.md +1 -1
  296. package/skills/unicli-hermes/SKILL.md +1 -1
  297. package/src/adapters/1point3acres/forum.test.ts +300 -0
  298. package/src/adapters/1point3acres/forum.ts +852 -0
  299. package/src/adapters/aibase/news.test.ts +42 -0
  300. package/src/adapters/aibase/news.ts +118 -0
  301. package/src/adapters/arxiv/papers.test.ts +59 -0
  302. package/src/adapters/arxiv/papers.ts +226 -0
  303. package/src/adapters/bbc/topic.test.ts +52 -0
  304. package/src/adapters/bbc/topic.ts +149 -0
  305. package/src/adapters/chatgpt/web.test.ts +121 -0
  306. package/src/adapters/chatgpt/web.ts +286 -0
  307. package/src/adapters/claude/web.test.ts +206 -0
  308. package/src/adapters/claude/web.ts +684 -0
  309. package/src/adapters/codex/projects.test.ts +77 -0
  310. package/src/adapters/codex/projects.ts +178 -0
  311. package/src/adapters/coingecko/markets.test.ts +156 -0
  312. package/src/adapters/coingecko/markets.ts +574 -0
  313. package/src/adapters/coupang/product.test.ts +111 -0
  314. package/src/adapters/coupang/product.ts +256 -0
  315. package/src/adapters/crates/registry.test.ts +89 -0
  316. package/src/adapters/crates/registry.ts +247 -0
  317. package/src/adapters/ctrip/travel.test.ts +359 -0
  318. package/src/adapters/ctrip/travel.ts +792 -0
  319. package/src/adapters/dblp/publications.test.ts +123 -0
  320. package/src/adapters/dblp/publications.ts +494 -0
  321. package/src/adapters/deepseek/web.test.ts +69 -0
  322. package/src/adapters/deepseek/web.ts +78 -1
  323. package/src/adapters/defillama/protocols.test.ts +75 -0
  324. package/src/adapters/defillama/protocols.ts +253 -0
  325. package/src/adapters/devto/read.test.ts +49 -0
  326. package/src/adapters/devto/read.ts +145 -0
  327. package/src/adapters/dianping/shop.test.ts +134 -0
  328. package/src/adapters/dianping/shop.ts +261 -0
  329. package/src/adapters/dockerhub/registry.test.ts +97 -0
  330. package/src/adapters/dockerhub/registry.ts +223 -0
  331. package/src/adapters/endoflife/product.test.ts +50 -0
  332. package/src/adapters/endoflife/product.ts +128 -0
  333. package/src/adapters/facebook/marketplace-extra.test.ts +132 -0
  334. package/src/adapters/facebook/marketplace-extra.ts +213 -0
  335. package/src/adapters/flathub/apps.test.ts +85 -0
  336. package/src/adapters/flathub/apps.ts +254 -0
  337. package/src/adapters/goproxy/module.test.ts +72 -0
  338. package/src/adapters/goproxy/module.ts +258 -0
  339. package/src/adapters/grok/web.test.ts +181 -0
  340. package/src/adapters/grok/web.ts +640 -0
  341. package/src/adapters/hackernews/read.test.ts +68 -0
  342. package/src/adapters/hackernews/read.ts +265 -0
  343. package/src/adapters/hf/paper.test.ts +48 -0
  344. package/src/adapters/hf/paper.ts +138 -0
  345. package/src/adapters/homebrew/packages.test.ts +109 -0
  346. package/src/adapters/homebrew/packages.ts +304 -0
  347. package/src/adapters/indeed/jobs.test.ts +230 -0
  348. package/src/adapters/indeed/jobs.ts +375 -0
  349. package/src/adapters/instagram/collections.test.ts +94 -0
  350. package/src/adapters/instagram/collections.ts +206 -0
  351. package/src/adapters/lichess/players.test.ts +99 -0
  352. package/src/adapters/lichess/players.ts +277 -0
  353. package/src/adapters/lobsters/read-domain.test.ts +121 -0
  354. package/src/adapters/lobsters/read-domain.ts +400 -0
  355. package/src/adapters/maven/artifact.test.ts +67 -0
  356. package/src/adapters/maven/artifact.ts +155 -0
  357. package/src/adapters/mdn/search.test.ts +39 -0
  358. package/src/adapters/mdn/search.ts +133 -0
  359. package/src/adapters/medium/tag.test.ts +64 -0
  360. package/src/adapters/medium/tag.ts +164 -0
  361. package/src/adapters/npm/package.test.ts +53 -0
  362. package/src/adapters/npm/package.ts +177 -0
  363. package/src/adapters/nuget/package.test.ts +102 -0
  364. package/src/adapters/nuget/package.ts +193 -0
  365. package/src/adapters/nvd/cve.test.ts +66 -0
  366. package/src/adapters/nvd/cve.ts +182 -0
  367. package/src/adapters/oeis/sequences.test.ts +71 -0
  368. package/src/adapters/oeis/sequences.ts +234 -0
  369. package/src/adapters/openalex/works.test.ts +99 -0
  370. package/src/adapters/openalex/works.ts +319 -0
  371. package/src/adapters/openfda/records.test.ts +90 -0
  372. package/src/adapters/openfda/records.ts +239 -0
  373. package/src/adapters/openreview/papers.test.ts +139 -0
  374. package/src/adapters/openreview/papers.ts +560 -0
  375. package/src/adapters/osv/security.test.ts +91 -0
  376. package/src/adapters/osv/security.ts +298 -0
  377. package/src/adapters/packagist/package.test.ts +62 -0
  378. package/src/adapters/packagist/package.ts +146 -0
  379. package/src/adapters/pubmed/articles.test.ts +96 -0
  380. package/src/adapters/pubmed/articles.ts +497 -0
  381. package/src/adapters/pypi/package.test.ts +131 -0
  382. package/src/adapters/pypi/package.ts +297 -0
  383. package/src/adapters/qwen/web.test.ts +176 -0
  384. package/src/adapters/qwen/web.ts +758 -0
  385. package/src/adapters/reddit/account.test.ts +56 -0
  386. package/src/adapters/reddit/account.ts +493 -0
  387. package/src/adapters/rednote/web.test.ts +354 -0
  388. package/src/adapters/rednote/web.ts +968 -0
  389. package/src/adapters/rest-countries/countries.test.ts +80 -0
  390. package/src/adapters/rest-countries/countries.ts +271 -0
  391. package/src/adapters/reuters/article-detail.test.ts +65 -0
  392. package/src/adapters/reuters/article-detail.ts +186 -0
  393. package/src/adapters/rfc/rfc.test.ts +37 -0
  394. package/src/adapters/rfc/rfc.ts +133 -0
  395. package/src/adapters/rubygems/gem.test.ts +43 -0
  396. package/src/adapters/rubygems/gem.ts +126 -0
  397. package/src/adapters/stackoverflow/questions.test.ts +207 -0
  398. package/src/adapters/stackoverflow/questions.ts +765 -0
  399. package/src/adapters/steam/app.test.ts +68 -0
  400. package/src/adapters/steam/app.ts +218 -0
  401. package/src/adapters/tiktok/creator-videos.test.ts +158 -0
  402. package/src/adapters/tiktok/creator-videos.ts +370 -0
  403. package/src/adapters/tvmaze/shows.test.ts +93 -0
  404. package/src/adapters/tvmaze/shows.ts +271 -0
  405. package/src/adapters/twitter/bookmark-folders.test.ts +164 -0
  406. package/src/adapters/twitter/bookmark-folders.ts +366 -0
  407. package/src/adapters/twitter/quote.test.ts +157 -0
  408. package/src/adapters/twitter/quote.ts +332 -0
  409. package/src/adapters/twitter/tweet-actions.test.ts +51 -0
  410. package/src/adapters/twitter/tweet-actions.ts +187 -0
  411. package/src/adapters/twitter/tweet-url.ts +65 -0
  412. package/src/adapters/uisdc/news.test.ts +46 -0
  413. package/src/adapters/uisdc/news.ts +111 -0
  414. package/src/adapters/weibo/favorites-publish.test.ts +177 -0
  415. package/src/adapters/weibo/favorites-publish.ts +426 -0
  416. package/src/adapters/wikidata/entities.test.ts +103 -0
  417. package/src/adapters/wikidata/entities.ts +253 -0
  418. package/src/adapters/wikipedia/page.test.ts +49 -0
  419. package/src/adapters/wikipedia/page.ts +158 -0
  420. package/src/adapters/wttr/weather.test.ts +99 -0
  421. package/src/adapters/wttr/weather.ts +239 -0
  422. package/src/adapters/xianyu/publish.test.ts +210 -0
  423. package/src/adapters/xianyu/publish.ts +420 -0
  424. package/src/adapters/xiaohongshu/user-helpers.ts +5 -2
  425. package/src/adapters/yuanbao/web.test.ts +144 -0
  426. package/src/adapters/yuanbao/web.ts +435 -0
  427. package/src/adapters/zhihu/collection.test.ts +96 -0
  428. package/src/adapters/zhihu/collection.ts +239 -0
  429. package/src/adapters/zlibrary/web.test.ts +104 -0
  430. package/src/adapters/zlibrary/web.ts +192 -0
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @owner src/adapters/hackernews/read.ts
3
+ * @does Register agent-facing Hacker News story reader with threaded comments.
4
+ * @needs Public Firebase item API, bounded tree traversal, HTML-to-text conversion.
5
+ * @feeds surface coverage ledger, HN story reading workflow, comment thread inspection.
6
+ * @breaks HN item shape drift, weak traversal bounds, or HTML entity loss degrades story reads.
7
+ */
8
+ import { cli, Strategy } from "../../registry.js";
9
+ const HN_ITEM_BASE = "https://hacker-news.firebaseio.com/v0/item";
10
+ function stringField(value) {
11
+ return typeof value === "string" ? value : "";
12
+ }
13
+ function numberField(value) {
14
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
15
+ }
16
+ export function requireHnItemId(value) {
17
+ const id = String(value ?? "").trim();
18
+ if (!/^\d+$/.test(id))
19
+ throw new Error(`Invalid HN item id: ${String(value)}.`);
20
+ return id;
21
+ }
22
+ export function requirePositiveInt(value, fallback, label) {
23
+ if (value === undefined || value === null || value === "")
24
+ return fallback;
25
+ const n = Number(value);
26
+ if (!Number.isInteger(n) || n <= 0) {
27
+ throw new Error(`${label} must be a positive integer.`);
28
+ }
29
+ return n;
30
+ }
31
+ export function requireMinInt(value, fallback, min, label) {
32
+ if (value === undefined || value === null || value === "")
33
+ return fallback;
34
+ const n = Number(value);
35
+ if (!Number.isInteger(n) || n < min) {
36
+ throw new Error(`${label} must be an integer >= ${min}.`);
37
+ }
38
+ return n;
39
+ }
40
+ export function hnHtmlToText(html) {
41
+ return String(html ?? "")
42
+ .replace(/<p>/gi, "\n\n")
43
+ .replace(/<\/p>/gi, "")
44
+ .replace(/<br\s*\/?>/gi, "\n")
45
+ .replace(/<i>(.*?)<\/i>/gi, "$1")
46
+ .replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, "$2 ($1)")
47
+ .replace(/<pre><code>([\s\S]*?)<\/code><\/pre>/gi, "\n$1\n")
48
+ .replace(/<[^>]+>/g, "")
49
+ .replace(/&#x27;/g, "'")
50
+ .replace(/&quot;/g, '"')
51
+ .replace(/&lt;/g, "<")
52
+ .replace(/&gt;/g, ">")
53
+ .replace(/&amp;/g, "&")
54
+ .replace(/&nbsp;/g, " ")
55
+ .replace(/&#x2F;/g, "/")
56
+ .trim();
57
+ }
58
+ function indentLines(text, depth) {
59
+ if (depth === 0)
60
+ return text;
61
+ const prefix = `${" ".repeat(depth)}> `;
62
+ return text
63
+ .split("\n")
64
+ .map((line) => `${prefix}${line}`)
65
+ .join("\n");
66
+ }
67
+ function childIds(item) {
68
+ return Array.isArray(item.kids)
69
+ ? item.kids.filter((id) => Number.isInteger(id))
70
+ : [];
71
+ }
72
+ function truncate(text, maxLength, suffix) {
73
+ return text.length > maxLength
74
+ ? `${text.slice(0, maxLength)}${suffix}`
75
+ : text;
76
+ }
77
+ export async function buildHnReadRows(story, fetchItem, options) {
78
+ if (!story || story.deleted || story.dead) {
79
+ throw new Error("HN story not found, deleted, or dead.");
80
+ }
81
+ const rows = [];
82
+ const storyBody = truncate(hnHtmlToText(story.text), options.maxLength, "\n... [truncated]");
83
+ const storyParts = [stringField(story.title)];
84
+ if (storyBody)
85
+ storyParts.push(`\n${storyBody}`);
86
+ if (story.url)
87
+ storyParts.push(`\n${stringField(story.url)}`);
88
+ rows.push({
89
+ type: "POST",
90
+ author: stringField(story.by) || "[deleted]",
91
+ score: numberField(story.score),
92
+ text: storyParts.join("").trim(),
93
+ });
94
+ async function walkComment(item, depth) {
95
+ if (!item || item.deleted || item.dead || item.type !== "comment")
96
+ return;
97
+ rows.push({
98
+ type: depth === 0 ? "L0" : `L${depth}`,
99
+ author: stringField(item.by) || "[deleted]",
100
+ score: "",
101
+ text: indentLines(truncate(hnHtmlToText(item.text), options.maxLength, "..."), depth),
102
+ });
103
+ const kids = childIds(item);
104
+ if (depth + 1 >= options.maxDepth) {
105
+ if (kids.length > 0) {
106
+ rows.push({
107
+ type: `L${depth + 1}`,
108
+ author: "",
109
+ score: "",
110
+ text: `${" ".repeat(depth + 1)}[+${kids.length} more replies]`,
111
+ });
112
+ }
113
+ return;
114
+ }
115
+ const visible = kids.slice(0, options.maxReplies);
116
+ for (const reply of await Promise.all(visible.map((id) => fetchItem(id)))) {
117
+ await walkComment(reply, depth + 1);
118
+ }
119
+ const hidden = kids.length - visible.length;
120
+ if (hidden > 0) {
121
+ rows.push({
122
+ type: `L${depth + 1}`,
123
+ author: "",
124
+ score: "",
125
+ text: `${" ".repeat(depth + 1)}[+${hidden} more replies]`,
126
+ });
127
+ }
128
+ }
129
+ const topKids = childIds(story);
130
+ const visibleTop = topKids.slice(0, options.limit);
131
+ for (const comment of await Promise.all(visibleTop.map((id) => fetchItem(id)))) {
132
+ await walkComment(comment, 0);
133
+ }
134
+ const hiddenTop = topKids.length - visibleTop.length;
135
+ if (hiddenTop > 0) {
136
+ rows.push({
137
+ type: "",
138
+ author: "",
139
+ score: "",
140
+ text: `[+${hiddenTop} more top-level comments]`,
141
+ });
142
+ }
143
+ return rows;
144
+ }
145
+ async function fetchHnItem(id) {
146
+ const response = await fetch(`${HN_ITEM_BASE}/${id}.json`, {
147
+ headers: {
148
+ "User-Agent": "unicli-hackernews/1.0 (https://github.com/olo-dot-io/Uni-CLI)",
149
+ Accept: "application/json",
150
+ },
151
+ });
152
+ if (!response.ok)
153
+ throw new Error(`HN API returned HTTP ${response.status} for item ${id}.`);
154
+ return (await response.json());
155
+ }
156
+ cli({
157
+ site: "hackernews",
158
+ name: "read",
159
+ description: "Read a Hacker News story and comment tree",
160
+ domain: "news.ycombinator.com",
161
+ strategy: Strategy.PUBLIC,
162
+ args: [
163
+ {
164
+ name: "id",
165
+ type: "str",
166
+ required: true,
167
+ positional: true,
168
+ description: "HN item id",
169
+ },
170
+ {
171
+ name: "limit",
172
+ type: "int",
173
+ default: 25,
174
+ description: "Max top-level comments",
175
+ },
176
+ { name: "depth", type: "int", default: 2, description: "Max reply depth" },
177
+ {
178
+ name: "replies",
179
+ type: "int",
180
+ default: 5,
181
+ description: "Max replies per comment",
182
+ },
183
+ {
184
+ name: "max-length",
185
+ type: "int",
186
+ default: 2000,
187
+ description: "Max chars per body",
188
+ },
189
+ ],
190
+ columns: ["type", "author", "score", "text"],
191
+ func: async (_page, kwargs) => {
192
+ const id = Number(requireHnItemId(kwargs.id));
193
+ return buildHnReadRows(await fetchHnItem(id), fetchHnItem, {
194
+ limit: requirePositiveInt(kwargs.limit, 25, "hackernews read limit"),
195
+ maxDepth: requirePositiveInt(kwargs.depth, 2, "hackernews read depth"),
196
+ maxReplies: requirePositiveInt(kwargs.replies, 5, "hackernews read replies"),
197
+ maxLength: requireMinInt(kwargs["max-length"] ?? kwargs.maxLength, 2000, 100, "hackernews read max-length"),
198
+ });
199
+ },
200
+ });
201
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/adapters/hackernews/read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @owner src/adapters/hf/paper.ts
3
+ * @does Register agent-facing Hugging Face paper detail command.
4
+ * @needs Hugging Face public papers API, modern arXiv ids, paper metadata normalization.
5
+ * @feeds surface coverage ledger, HF daily paper detail workflows, scholarly metadata readers.
6
+ * @breaks HF papers API shape drift or invalid arXiv id handling can hide paper details.
7
+ */
8
+ interface HfPaper {
9
+ id?: unknown;
10
+ title?: unknown;
11
+ authors?: unknown;
12
+ publishedAt?: unknown;
13
+ upvotes?: unknown;
14
+ ai_keywords?: unknown;
15
+ summary?: unknown;
16
+ ai_summary?: unknown;
17
+ }
18
+ export declare function requireHfPaperId(value: unknown): string;
19
+ export declare function hfEndpoint(value?: string | undefined): string;
20
+ export declare function mapHfPaperRow(paper: HfPaper, endpoint?: string): Record<string, unknown>;
21
+ export {};
22
+ //# sourceMappingURL=paper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper.d.ts","sourceRoot":"","sources":["../../../src/adapters/hf/paper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,UAAU,OAAO;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAYD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOvD;AAED,wBAAgB,UAAU,CAAC,KAAK,qBAA0B,GAAG,MAAM,CAElE;AAaD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,QAAQ,SAAsB,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBzB"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @owner src/adapters/hf/paper.ts
3
+ * @does Register agent-facing Hugging Face paper detail command.
4
+ * @needs Hugging Face public papers API, modern arXiv ids, paper metadata normalization.
5
+ * @feeds surface coverage ledger, HF daily paper detail workflows, scholarly metadata readers.
6
+ * @breaks HF papers API shape drift or invalid arXiv id handling can hide paper details.
7
+ */
8
+ import { cli, Strategy } from "../../registry.js";
9
+ const HF_DEFAULT_ENDPOINT = "https://huggingface.co";
10
+ const ARXIV_ID_PATTERN = /^\d{4}\.\d{4,5}(?:v\d+)?$/;
11
+ function stringField(value) {
12
+ return value === undefined || value === null ? "" : String(value);
13
+ }
14
+ function numberOrNull(value) {
15
+ if (value === undefined || value === null || value === "")
16
+ return null;
17
+ const n = Number(value);
18
+ return Number.isFinite(n) ? n : null;
19
+ }
20
+ export function requireHfPaperId(value) {
21
+ const id = String(value ?? "").trim();
22
+ if (!id)
23
+ throw new Error("hf paper id cannot be empty.");
24
+ if (!ARXIV_ID_PATTERN.test(id)) {
25
+ throw new Error(`hf paper id "${String(value)}" is not a valid arXiv id.`);
26
+ }
27
+ return id;
28
+ }
29
+ export function hfEndpoint(value = process.env.HF_ENDPOINT) {
30
+ return (value || HF_DEFAULT_ENDPOINT).replace(/\/+$/, "");
31
+ }
32
+ function hfAuthorNames(value) {
33
+ if (!Array.isArray(value))
34
+ return "";
35
+ return value
36
+ .map((author) => {
37
+ if (typeof author === "string")
38
+ return author;
39
+ return stringField(author.name || author.fullname);
40
+ })
41
+ .filter(Boolean)
42
+ .join(", ");
43
+ }
44
+ export function mapHfPaperRow(paper, endpoint = HF_DEFAULT_ENDPOINT) {
45
+ const id = stringField(paper.id);
46
+ if (!id)
47
+ throw new Error("Hugging Face returned no paper data.");
48
+ return {
49
+ id,
50
+ title: stringField(paper.title),
51
+ authors: hfAuthorNames(paper.authors),
52
+ publishedAt: stringField(paper.publishedAt).slice(0, 10),
53
+ upvotes: numberOrNull(paper.upvotes),
54
+ aiKeywords: Array.isArray(paper.ai_keywords)
55
+ ? paper.ai_keywords.map(String).join(", ")
56
+ : "",
57
+ summary: stringField(paper.summary),
58
+ aiSummary: stringField(paper.ai_summary),
59
+ url: `${hfEndpoint(endpoint)}/papers/${id}`,
60
+ };
61
+ }
62
+ async function fetchHfPaper(id) {
63
+ const endpoint = hfEndpoint();
64
+ const response = await fetch(`${endpoint}/api/papers/${encodeURIComponent(id)}`, {
65
+ headers: {
66
+ Accept: "application/json",
67
+ "User-Agent": "unicli-hf/1.0 (https://github.com/olo-dot-io/Uni-CLI)",
68
+ },
69
+ });
70
+ if (response.status === 404) {
71
+ throw new Error(`Hugging Face has no paper page for "${id}".`);
72
+ }
73
+ if (response.status === 429) {
74
+ throw new Error("Hugging Face paper API returned HTTP 429.");
75
+ }
76
+ if (!response.ok)
77
+ throw new Error(`Hugging Face paper API returned HTTP ${response.status}.`);
78
+ return (await response.json());
79
+ }
80
+ cli({
81
+ site: "hf",
82
+ name: "paper",
83
+ description: "Hugging Face paper detail by arXiv id",
84
+ domain: "huggingface.co",
85
+ strategy: Strategy.PUBLIC,
86
+ browser: false,
87
+ args: [
88
+ {
89
+ name: "id",
90
+ type: "str",
91
+ required: true,
92
+ positional: true,
93
+ description: "arXiv id",
94
+ },
95
+ ],
96
+ columns: [
97
+ "id",
98
+ "title",
99
+ "authors",
100
+ "publishedAt",
101
+ "upvotes",
102
+ "aiKeywords",
103
+ "summary",
104
+ "aiSummary",
105
+ "url",
106
+ ],
107
+ func: async (_page, kwargs) => {
108
+ const id = requireHfPaperId(kwargs.id);
109
+ return [mapHfPaperRow(await fetchHfPaper(id), hfEndpoint())];
110
+ },
111
+ });
112
+ //# sourceMappingURL=paper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper.js","sourceRoot":"","sources":["../../../src/adapters/hf/paper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @owner src/adapters/homebrew/packages.ts
3
+ * @does Register agent-facing Homebrew formula, cask, and popularity commands.
4
+ * @needs formulae.brew.sh public JSON APIs and bounded argument parsing.
5
+ * @feeds surface coverage ledger, package registry command surface, Homebrew package inspection.
6
+ * @breaks Homebrew API drift, weak token validation, or silent analytics empties hide package lookup failures.
7
+ */
8
+ declare const POPULAR_TYPES: readonly ["formula", "cask"];
9
+ declare const POPULAR_WINDOWS: readonly ["30d", "90d", "365d"];
10
+ type PopularType = (typeof POPULAR_TYPES)[number];
11
+ type PopularWindow = (typeof POPULAR_WINDOWS)[number];
12
+ interface HomebrewFormulaBody {
13
+ name?: unknown;
14
+ tap?: unknown;
15
+ versions?: {
16
+ stable?: unknown;
17
+ };
18
+ license?: unknown;
19
+ desc?: unknown;
20
+ homepage?: unknown;
21
+ dependencies?: unknown;
22
+ deprecated?: unknown;
23
+ disabled?: unknown;
24
+ urls?: {
25
+ stable?: {
26
+ url?: unknown;
27
+ };
28
+ };
29
+ }
30
+ interface HomebrewCaskBody {
31
+ token?: unknown;
32
+ tap?: unknown;
33
+ name?: unknown;
34
+ version?: unknown;
35
+ desc?: unknown;
36
+ homepage?: unknown;
37
+ deprecated?: unknown;
38
+ disabled?: unknown;
39
+ url?: unknown;
40
+ }
41
+ interface HomebrewAnalyticsBody {
42
+ items?: Array<Record<string, unknown>>;
43
+ }
44
+ export declare function requireHomebrewToken(value: unknown, label: string): string;
45
+ export declare function requireHomebrewLimit(value: unknown, fallback: number): number;
46
+ export declare function requirePopularType(value: unknown): PopularType;
47
+ export declare function requirePopularWindow(value: unknown): PopularWindow;
48
+ export declare function mapFormulaRow(body: HomebrewFormulaBody, requested: string): Record<string, unknown>;
49
+ export declare function mapCaskRow(body: HomebrewCaskBody, requested: string): Record<string, unknown>;
50
+ export declare function mapPopularRows(body: HomebrewAnalyticsBody, type: PopularType, window: PopularWindow, limit: number): Array<Record<string, unknown>>;
51
+ export {};
52
+ //# sourceMappingURL=packages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packages.d.ts","sourceRoot":"","sources":["../../../src/adapters/homebrew/packages.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,QAAA,MAAM,aAAa,8BAA+B,CAAC;AACnD,QAAA,MAAM,eAAe,iCAAkC,CAAC;AAExD,KAAK,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAClD,KAAK,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;CACvC;AAED,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACxC;AAiBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO1E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAQ9D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAMlE;AAeD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmBzB;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,qBAAqB,EAC3B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAsBhC"}
@@ -0,0 +1,240 @@
1
+ /**
2
+ * @owner src/adapters/homebrew/packages.ts
3
+ * @does Register agent-facing Homebrew formula, cask, and popularity commands.
4
+ * @needs formulae.brew.sh public JSON APIs and bounded argument parsing.
5
+ * @feeds surface coverage ledger, package registry command surface, Homebrew package inspection.
6
+ * @breaks Homebrew API drift, weak token validation, or silent analytics empties hide package lookup failures.
7
+ */
8
+ import { cli, Strategy } from "../../registry.js";
9
+ const BREW_BASE = "https://formulae.brew.sh/api";
10
+ const POPULAR_TYPES = ["formula", "cask"];
11
+ const POPULAR_WINDOWS = ["30d", "90d", "365d"];
12
+ function stringField(value) {
13
+ return typeof value === "string" ? value.trim() : "";
14
+ }
15
+ function boolField(value) {
16
+ return value === true;
17
+ }
18
+ function numberField(value) {
19
+ if (typeof value === "number" && Number.isFinite(value))
20
+ return value;
21
+ if (typeof value !== "string")
22
+ return null;
23
+ const n = Number(value.replace(/,/g, ""));
24
+ return Number.isFinite(n) ? n : null;
25
+ }
26
+ export function requireHomebrewToken(value, label) {
27
+ const token = String(value ?? "").trim();
28
+ if (!token)
29
+ throw new Error(`homebrew ${label} is required.`);
30
+ if (!/^[A-Za-z0-9][A-Za-z0-9._@+-]*$/.test(token)) {
31
+ throw new Error(`homebrew ${label} "${String(value)}" is not valid.`);
32
+ }
33
+ return token;
34
+ }
35
+ export function requireHomebrewLimit(value, fallback) {
36
+ if (value === undefined || value === null || value === "")
37
+ return fallback;
38
+ const n = Number(value);
39
+ if (!Number.isInteger(n) || n < 1 || n > 500) {
40
+ throw new Error(`limit must be an integer in [1, 500]. Got: ${String(value)}`);
41
+ }
42
+ return n;
43
+ }
44
+ export function requirePopularType(value) {
45
+ const type = String(value ?? "formula")
46
+ .trim()
47
+ .toLowerCase();
48
+ if (type !== "formula" && type !== "cask") {
49
+ throw new Error("type must be formula or cask.");
50
+ }
51
+ return type;
52
+ }
53
+ export function requirePopularWindow(value) {
54
+ const window = String(value ?? "30d").trim();
55
+ if (window !== "30d" && window !== "90d" && window !== "365d") {
56
+ throw new Error("window must be 30d, 90d, or 365d.");
57
+ }
58
+ return window;
59
+ }
60
+ async function fetchHomebrewJson(url, label) {
61
+ const response = await fetch(url, {
62
+ headers: {
63
+ "User-Agent": "unicli (https://github.com/olo-dot-io/Uni-CLI)",
64
+ Accept: "application/json",
65
+ },
66
+ });
67
+ if (response.status === 404)
68
+ throw new Error(`${label} returned no result.`);
69
+ if (!response.ok)
70
+ throw new Error(`${label} returned HTTP ${response.status}.`);
71
+ return response.json();
72
+ }
73
+ export function mapFormulaRow(body, requested) {
74
+ const formula = stringField(body.name) || requested;
75
+ const dependencies = Array.isArray(body.dependencies)
76
+ ? body.dependencies.map(stringField).filter(Boolean).join(", ")
77
+ : "";
78
+ if (!formula)
79
+ throw new Error(`Homebrew returned no formula metadata.`);
80
+ return {
81
+ formula,
82
+ tap: stringField(body.tap),
83
+ version: stringField(body.versions?.stable),
84
+ license: stringField(body.license),
85
+ description: stringField(body.desc),
86
+ homepage: stringField(body.homepage),
87
+ dependencies,
88
+ deprecated: boolField(body.deprecated),
89
+ disabled: boolField(body.disabled),
90
+ source: stringField(body.urls?.stable?.url),
91
+ url: `https://formulae.brew.sh/formula/${encodeURIComponent(formula)}`,
92
+ };
93
+ }
94
+ export function mapCaskRow(body, requested) {
95
+ const cask = stringField(body.token) || requested;
96
+ const name = Array.isArray(body.name)
97
+ ? body.name.map(stringField).filter(Boolean).join(", ")
98
+ : stringField(body.name);
99
+ if (!cask)
100
+ throw new Error(`Homebrew returned no cask metadata.`);
101
+ return {
102
+ cask,
103
+ tap: stringField(body.tap),
104
+ name,
105
+ version: stringField(body.version),
106
+ description: stringField(body.desc),
107
+ homepage: stringField(body.homepage),
108
+ deprecated: boolField(body.deprecated),
109
+ disabled: boolField(body.disabled),
110
+ download: stringField(body.url),
111
+ url: `https://formulae.brew.sh/cask/${encodeURIComponent(cask)}`,
112
+ };
113
+ }
114
+ export function mapPopularRows(body, type, window, limit) {
115
+ const items = Array.isArray(body.items) ? body.items : [];
116
+ if (items.length === 0) {
117
+ throw new Error(`Homebrew analytics returned no rows for ${type}/${window}.`);
118
+ }
119
+ return items.slice(0, limit).map((row, index) => {
120
+ const token = stringField(type === "cask" ? row.cask : row.formula);
121
+ const detailPath = type === "cask" ? "cask" : "formula";
122
+ return {
123
+ rank: numberField(row.number) ?? index + 1,
124
+ token,
125
+ type,
126
+ installs: numberField(row.count),
127
+ percent: numberField(row.percent),
128
+ window,
129
+ url: token
130
+ ? `https://formulae.brew.sh/${detailPath}/${encodeURIComponent(token)}`
131
+ : "",
132
+ };
133
+ });
134
+ }
135
+ cli({
136
+ site: "homebrew",
137
+ name: "formula",
138
+ description: "Fetch Homebrew formula metadata",
139
+ domain: "formulae.brew.sh",
140
+ strategy: Strategy.PUBLIC,
141
+ args: [
142
+ {
143
+ name: "name",
144
+ type: "str",
145
+ required: true,
146
+ positional: true,
147
+ description: "Formula name",
148
+ },
149
+ ],
150
+ columns: [
151
+ "formula",
152
+ "tap",
153
+ "version",
154
+ "license",
155
+ "description",
156
+ "homepage",
157
+ "dependencies",
158
+ "deprecated",
159
+ "disabled",
160
+ "source",
161
+ "url",
162
+ ],
163
+ func: async (_page, kwargs) => {
164
+ const name = requireHomebrewToken(kwargs.name, "formula");
165
+ const body = (await fetchHomebrewJson(`${BREW_BASE}/formula/${encodeURIComponent(name)}.json`, `homebrew formula ${name}`));
166
+ return [mapFormulaRow(body, name)];
167
+ },
168
+ });
169
+ cli({
170
+ site: "homebrew",
171
+ name: "cask",
172
+ description: "Fetch Homebrew cask metadata",
173
+ domain: "formulae.brew.sh",
174
+ strategy: Strategy.PUBLIC,
175
+ args: [
176
+ {
177
+ name: "token",
178
+ type: "str",
179
+ required: true,
180
+ positional: true,
181
+ description: "Cask token",
182
+ },
183
+ ],
184
+ columns: [
185
+ "cask",
186
+ "tap",
187
+ "name",
188
+ "version",
189
+ "description",
190
+ "homepage",
191
+ "deprecated",
192
+ "disabled",
193
+ "download",
194
+ "url",
195
+ ],
196
+ func: async (_page, kwargs) => {
197
+ const token = requireHomebrewToken(kwargs.token, "cask");
198
+ const body = (await fetchHomebrewJson(`${BREW_BASE}/cask/${encodeURIComponent(token)}.json`, `homebrew cask ${token}`));
199
+ return [mapCaskRow(body, token)];
200
+ },
201
+ });
202
+ cli({
203
+ site: "homebrew",
204
+ name: "popular",
205
+ description: "List most-installed Homebrew formulae or casks",
206
+ domain: "formulae.brew.sh",
207
+ strategy: Strategy.PUBLIC,
208
+ args: [
209
+ {
210
+ name: "type",
211
+ type: "str",
212
+ default: "formula",
213
+ choices: ["formula", "cask"],
214
+ description: "Package type",
215
+ },
216
+ {
217
+ name: "window",
218
+ type: "str",
219
+ default: "30d",
220
+ choices: ["30d", "90d", "365d"],
221
+ description: "Homebrew analytics window",
222
+ },
223
+ {
224
+ name: "limit",
225
+ type: "int",
226
+ default: 30,
227
+ description: "Max rows",
228
+ },
229
+ ],
230
+ columns: ["rank", "token", "type", "installs", "percent", "window", "url"],
231
+ func: async (_page, kwargs) => {
232
+ const type = requirePopularType(kwargs.type);
233
+ const window = requirePopularWindow(kwargs.window);
234
+ const limit = requireHomebrewLimit(kwargs.limit, 30);
235
+ const path = type === "cask" ? "cask-install" : "install";
236
+ const body = (await fetchHomebrewJson(`${BREW_BASE}/analytics/${path}/${window}.json`, `homebrew popular ${type}/${window}`));
237
+ return mapPopularRows(body, type, window, limit);
238
+ },
239
+ });
240
+ //# sourceMappingURL=packages.js.map