@zenalexa/unicli 0.215.1 → 0.216.2

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 (407) hide show
  1. package/AGENTS.md +15 -15
  2. package/README.md +233 -389
  3. package/README.zh-CN.md +235 -362
  4. package/dist/adapters/1688/assets.d.ts +2 -0
  5. package/dist/adapters/1688/assets.d.ts.map +1 -0
  6. package/dist/adapters/1688/assets.js +102 -0
  7. package/dist/adapters/1688/assets.js.map +1 -0
  8. package/dist/adapters/51job/jobs.d.ts +2 -0
  9. package/dist/adapters/51job/jobs.d.ts.map +1 -0
  10. package/dist/adapters/51job/jobs.js +292 -0
  11. package/dist/adapters/51job/jobs.js.map +1 -0
  12. package/dist/adapters/_shared/browser-tools.d.ts +10 -0
  13. package/dist/adapters/_shared/browser-tools.d.ts.map +1 -0
  14. package/dist/adapters/_shared/browser-tools.js +42 -0
  15. package/dist/adapters/_shared/browser-tools.js.map +1 -0
  16. package/dist/adapters/antigravity/extra.d.ts +2 -0
  17. package/dist/adapters/antigravity/extra.d.ts.map +1 -0
  18. package/dist/adapters/antigravity/extra.js +52 -0
  19. package/dist/adapters/antigravity/extra.js.map +1 -0
  20. package/dist/adapters/baidu-scholar/search.d.ts +2 -0
  21. package/dist/adapters/baidu-scholar/search.d.ts.map +1 -0
  22. package/dist/adapters/baidu-scholar/search.js +34 -0
  23. package/dist/adapters/baidu-scholar/search.js.map +1 -0
  24. package/dist/adapters/bilibili/compat.d.ts +2 -0
  25. package/dist/adapters/bilibili/compat.d.ts.map +1 -0
  26. package/dist/adapters/bilibili/compat.js +114 -0
  27. package/dist/adapters/bilibili/compat.js.map +1 -0
  28. package/dist/adapters/chatgpt/image.d.ts +2 -0
  29. package/dist/adapters/chatgpt/image.d.ts.map +1 -0
  30. package/dist/adapters/chatgpt/image.js +81 -0
  31. package/dist/adapters/chatgpt/image.js.map +1 -0
  32. package/dist/adapters/chatgpt-app/chatgpt-app.d.ts +2 -0
  33. package/dist/adapters/chatgpt-app/chatgpt-app.d.ts.map +1 -0
  34. package/dist/adapters/chatgpt-app/chatgpt-app.js +9 -0
  35. package/dist/adapters/chatgpt-app/chatgpt-app.js.map +1 -0
  36. package/dist/adapters/chatwise/extra.d.ts +2 -0
  37. package/dist/adapters/chatwise/extra.d.ts.map +1 -0
  38. package/dist/adapters/chatwise/extra.js +35 -0
  39. package/dist/adapters/chatwise/extra.js.map +1 -0
  40. package/dist/adapters/codex/extra.d.ts +2 -0
  41. package/dist/adapters/codex/extra.d.ts.map +1 -0
  42. package/dist/adapters/codex/extra.js +35 -0
  43. package/dist/adapters/codex/extra.js.map +1 -0
  44. package/dist/adapters/deepseek/web.d.ts +2 -0
  45. package/dist/adapters/deepseek/web.d.ts.map +1 -0
  46. package/dist/adapters/deepseek/web.js +187 -0
  47. package/dist/adapters/deepseek/web.js.map +1 -0
  48. package/dist/adapters/doubao/web.d.ts +2 -0
  49. package/dist/adapters/doubao/web.d.ts.map +1 -0
  50. package/dist/adapters/doubao/web.js +138 -0
  51. package/dist/adapters/doubao/web.js.map +1 -0
  52. package/dist/adapters/eastmoney/market-data.d.ts +2 -0
  53. package/dist/adapters/eastmoney/market-data.d.ts.map +1 -0
  54. package/dist/adapters/eastmoney/market-data.js +753 -0
  55. package/dist/adapters/eastmoney/market-data.js.map +1 -0
  56. package/dist/adapters/gitee/user.d.ts +2 -0
  57. package/dist/adapters/gitee/user.d.ts.map +1 -0
  58. package/dist/adapters/gitee/user.js +54 -0
  59. package/dist/adapters/gitee/user.js.map +1 -0
  60. package/dist/adapters/google-scholar/cite.d.ts +2 -0
  61. package/dist/adapters/google-scholar/cite.d.ts.map +1 -0
  62. package/dist/adapters/google-scholar/cite.js +82 -0
  63. package/dist/adapters/google-scholar/cite.js.map +1 -0
  64. package/dist/adapters/google-scholar/profile.d.ts +2 -0
  65. package/dist/adapters/google-scholar/profile.d.ts.map +1 -0
  66. package/dist/adapters/google-scholar/profile.js +80 -0
  67. package/dist/adapters/google-scholar/profile.js.map +1 -0
  68. package/dist/adapters/google-scholar/search.d.ts +2 -0
  69. package/dist/adapters/google-scholar/search.d.ts.map +1 -0
  70. package/dist/adapters/google-scholar/search.js +54 -0
  71. package/dist/adapters/google-scholar/search.js.map +1 -0
  72. package/dist/adapters/gov-law/laws.d.ts +2 -0
  73. package/dist/adapters/gov-law/laws.d.ts.map +1 -0
  74. package/dist/adapters/gov-law/laws.js +58 -0
  75. package/dist/adapters/gov-law/laws.js.map +1 -0
  76. package/dist/adapters/gov-policy/policy.d.ts +2 -0
  77. package/dist/adapters/gov-policy/policy.d.ts.map +1 -0
  78. package/dist/adapters/gov-policy/policy.js +58 -0
  79. package/dist/adapters/gov-policy/policy.js.map +1 -0
  80. package/dist/adapters/jd/commerce.d.ts +2 -0
  81. package/dist/adapters/jd/commerce.d.ts.map +1 -0
  82. package/dist/adapters/jd/commerce.js +133 -0
  83. package/dist/adapters/jd/commerce.js.map +1 -0
  84. package/dist/adapters/jianyu/detail.d.ts +2 -0
  85. package/dist/adapters/jianyu/detail.d.ts.map +1 -0
  86. package/dist/adapters/jianyu/detail.js +27 -0
  87. package/dist/adapters/jianyu/detail.js.map +1 -0
  88. package/dist/adapters/jimeng/workspace.d.ts +2 -0
  89. package/dist/adapters/jimeng/workspace.d.ts.map +1 -0
  90. package/dist/adapters/jimeng/workspace.js +49 -0
  91. package/dist/adapters/jimeng/workspace.js.map +1 -0
  92. package/dist/adapters/ke/rent-transaction.d.ts +2 -0
  93. package/dist/adapters/ke/rent-transaction.d.ts.map +1 -0
  94. package/dist/adapters/ke/rent-transaction.js +63 -0
  95. package/dist/adapters/ke/rent-transaction.js.map +1 -0
  96. package/dist/adapters/linux-do/search.d.ts +2 -0
  97. package/dist/adapters/linux-do/search.d.ts.map +1 -0
  98. package/dist/adapters/linux-do/search.js +75 -0
  99. package/dist/adapters/linux-do/search.js.map +1 -0
  100. package/dist/adapters/linux-do/topic-content.d.ts +2 -0
  101. package/dist/adapters/linux-do/topic-content.d.ts.map +1 -0
  102. package/dist/adapters/linux-do/topic-content.js +32 -0
  103. package/dist/adapters/linux-do/topic-content.js.map +1 -0
  104. package/dist/adapters/maimai/talents.d.ts +2 -0
  105. package/dist/adapters/maimai/talents.d.ts.map +1 -0
  106. package/dist/adapters/maimai/talents.js +64 -0
  107. package/dist/adapters/maimai/talents.js.map +1 -0
  108. package/dist/adapters/mubu/docs.d.ts +2 -0
  109. package/dist/adapters/mubu/docs.d.ts.map +1 -0
  110. package/dist/adapters/mubu/docs.js +96 -0
  111. package/dist/adapters/mubu/docs.js.map +1 -0
  112. package/dist/adapters/nowcoder/nowcoder.d.ts +2 -0
  113. package/dist/adapters/nowcoder/nowcoder.d.ts.map +1 -0
  114. package/dist/adapters/nowcoder/nowcoder.js +480 -0
  115. package/dist/adapters/nowcoder/nowcoder.js.map +1 -0
  116. package/dist/adapters/powerchina/search.d.ts +2 -0
  117. package/dist/adapters/powerchina/search.d.ts.map +1 -0
  118. package/dist/adapters/powerchina/search.js +41 -0
  119. package/dist/adapters/powerchina/search.js.map +1 -0
  120. package/dist/adapters/quark/actions.d.ts +2 -0
  121. package/dist/adapters/quark/actions.d.ts.map +1 -0
  122. package/dist/adapters/quark/actions.js +151 -0
  123. package/dist/adapters/quark/actions.js.map +1 -0
  124. package/dist/adapters/reddit/browser-utils.d.ts +7 -0
  125. package/dist/adapters/reddit/browser-utils.d.ts.map +1 -0
  126. package/dist/adapters/reddit/browser-utils.js +68 -0
  127. package/dist/adapters/reddit/browser-utils.js.map +1 -0
  128. package/dist/adapters/reddit/listings.d.ts +2 -0
  129. package/dist/adapters/reddit/listings.d.ts.map +1 -0
  130. package/dist/adapters/reddit/listings.js +193 -0
  131. package/dist/adapters/reddit/listings.js.map +1 -0
  132. package/dist/adapters/reddit/search.d.ts +2 -0
  133. package/dist/adapters/reddit/search.d.ts.map +1 -0
  134. package/dist/adapters/reddit/search.js +66 -0
  135. package/dist/adapters/reddit/search.js.map +1 -0
  136. package/dist/adapters/spotify/api.d.ts +2 -0
  137. package/dist/adapters/spotify/api.d.ts.map +1 -0
  138. package/dist/adapters/spotify/api.js +252 -0
  139. package/dist/adapters/spotify/api.js.map +1 -0
  140. package/dist/adapters/taobao/commerce.d.ts +2 -0
  141. package/dist/adapters/taobao/commerce.d.ts.map +1 -0
  142. package/dist/adapters/taobao/commerce.js +130 -0
  143. package/dist/adapters/taobao/commerce.js.map +1 -0
  144. package/dist/adapters/tdx/hot-rank.d.ts +2 -0
  145. package/dist/adapters/tdx/hot-rank.d.ts.map +1 -0
  146. package/dist/adapters/tdx/hot-rank.js +34 -0
  147. package/dist/adapters/tdx/hot-rank.js.map +1 -0
  148. package/dist/adapters/ths/hot-rank.d.ts +2 -0
  149. package/dist/adapters/ths/hot-rank.d.ts.map +1 -0
  150. package/dist/adapters/ths/hot-rank.js +34 -0
  151. package/dist/adapters/ths/hot-rank.js.map +1 -0
  152. package/dist/adapters/toutiao/articles.d.ts +2 -0
  153. package/dist/adapters/toutiao/articles.d.ts.map +1 -0
  154. package/dist/adapters/toutiao/articles.js +41 -0
  155. package/dist/adapters/toutiao/articles.js.map +1 -0
  156. package/dist/adapters/twitter/lists-extra.d.ts +2 -0
  157. package/dist/adapters/twitter/lists-extra.d.ts.map +1 -0
  158. package/dist/adapters/twitter/lists-extra.js +125 -0
  159. package/dist/adapters/twitter/lists-extra.js.map +1 -0
  160. package/dist/adapters/uiverse/components.d.ts +2 -0
  161. package/dist/adapters/uiverse/components.d.ts.map +1 -0
  162. package/dist/adapters/uiverse/components.js +138 -0
  163. package/dist/adapters/uiverse/components.js.map +1 -0
  164. package/dist/adapters/wanfang/search.d.ts +2 -0
  165. package/dist/adapters/wanfang/search.d.ts.map +1 -0
  166. package/dist/adapters/wanfang/search.js +34 -0
  167. package/dist/adapters/wanfang/search.js.map +1 -0
  168. package/dist/adapters/weixin/drafts.d.ts +2 -0
  169. package/dist/adapters/weixin/drafts.d.ts.map +1 -0
  170. package/dist/adapters/weixin/drafts.js +69 -0
  171. package/dist/adapters/weixin/drafts.js.map +1 -0
  172. package/dist/adapters/weread/ai-outline.d.ts +2 -0
  173. package/dist/adapters/weread/ai-outline.d.ts.map +1 -0
  174. package/dist/adapters/weread/ai-outline.js +28 -0
  175. package/dist/adapters/weread/ai-outline.js.map +1 -0
  176. package/dist/adapters/xiaoyuzhou/media.d.ts +2 -0
  177. package/dist/adapters/xiaoyuzhou/media.d.ts.map +1 -0
  178. package/dist/adapters/xiaoyuzhou/media.js +105 -0
  179. package/dist/adapters/xiaoyuzhou/media.js.map +1 -0
  180. package/dist/adapters/xueqiu/extra.d.ts +2 -0
  181. package/dist/adapters/xueqiu/extra.d.ts.map +1 -0
  182. package/dist/adapters/xueqiu/extra.js +74 -0
  183. package/dist/adapters/xueqiu/extra.js.map +1 -0
  184. package/dist/adapters/youtube/personal.d.ts +2 -0
  185. package/dist/adapters/youtube/personal.d.ts.map +1 -0
  186. package/dist/adapters/youtube/personal.js +183 -0
  187. package/dist/adapters/youtube/personal.js.map +1 -0
  188. package/dist/adapters/zhihu/actions.d.ts +2 -0
  189. package/dist/adapters/zhihu/actions.d.ts.map +1 -0
  190. package/dist/adapters/zhihu/actions.js +110 -0
  191. package/dist/adapters/zhihu/actions.js.map +1 -0
  192. package/dist/browser/adapter-authoring.d.ts.map +1 -1
  193. package/dist/browser/adapter-authoring.js +3 -3
  194. package/dist/browser/adapter-authoring.js.map +1 -1
  195. package/dist/browser/bridge.d.ts.map +1 -1
  196. package/dist/browser/bridge.js +2 -3
  197. package/dist/browser/bridge.js.map +1 -1
  198. package/dist/browser/daemon-client.d.ts.map +1 -1
  199. package/dist/browser/daemon-client.js +17 -5
  200. package/dist/browser/daemon-client.js.map +1 -1
  201. package/dist/browser/network-cache.js +2 -2
  202. package/dist/browser/network-cache.js.map +1 -1
  203. package/dist/browser/site-memory.d.ts.map +1 -1
  204. package/dist/browser/site-memory.js +11 -8
  205. package/dist/browser/site-memory.js.map +1 -1
  206. package/dist/browser/target-errors.d.ts +2 -2
  207. package/dist/browser/target-errors.js +2 -2
  208. package/dist/browser/verify-fixture.d.ts.map +1 -1
  209. package/dist/browser/verify-fixture.js +2 -2
  210. package/dist/browser/verify-fixture.js.map +1 -1
  211. package/dist/cli.d.ts.map +1 -1
  212. package/dist/cli.js +9 -4
  213. package/dist/cli.js.map +1 -1
  214. package/dist/commands/agents.d.ts.map +1 -1
  215. package/dist/commands/agents.js +5 -2
  216. package/dist/commands/agents.js.map +1 -1
  217. package/dist/commands/auth.d.ts.map +1 -1
  218. package/dist/commands/auth.js +8 -2
  219. package/dist/commands/auth.js.map +1 -1
  220. package/dist/commands/browser-operator-runtime.d.ts.map +1 -1
  221. package/dist/commands/browser-operator-runtime.js +2 -2
  222. package/dist/commands/browser-operator-runtime.js.map +1 -1
  223. package/dist/commands/browser-operator.d.ts.map +1 -1
  224. package/dist/commands/browser-operator.js +2 -2
  225. package/dist/commands/browser-operator.js.map +1 -1
  226. package/dist/commands/describe.d.ts +2 -2
  227. package/dist/commands/describe.d.ts.map +1 -1
  228. package/dist/commands/describe.js +14 -3
  229. package/dist/commands/describe.js.map +1 -1
  230. package/dist/commands/dispatch.d.ts.map +1 -1
  231. package/dist/commands/dispatch.js +7 -6
  232. package/dist/commands/dispatch.js.map +1 -1
  233. package/dist/commands/explore.js +2 -2
  234. package/dist/commands/explore.js.map +1 -1
  235. package/dist/commands/generate.js +3 -3
  236. package/dist/commands/generate.js.map +1 -1
  237. package/dist/commands/health.d.ts.map +1 -1
  238. package/dist/commands/health.js +4 -10
  239. package/dist/commands/health.js.map +1 -1
  240. package/dist/commands/migrate.d.ts +9 -9
  241. package/dist/commands/migrate.d.ts.map +1 -1
  242. package/dist/commands/migrate.js +22 -22
  243. package/dist/commands/migrate.js.map +1 -1
  244. package/dist/commands/repair.d.ts.map +1 -1
  245. package/dist/commands/repair.js +9 -4
  246. package/dist/commands/repair.js.map +1 -1
  247. package/dist/commands/search.d.ts +3 -3
  248. package/dist/commands/search.js +4 -4
  249. package/dist/commands/skills.d.ts +3 -0
  250. package/dist/commands/skills.d.ts.map +1 -1
  251. package/dist/commands/skills.js +8 -4
  252. package/dist/commands/skills.js.map +1 -1
  253. package/dist/commands/synthesize.js +2 -2
  254. package/dist/commands/synthesize.js.map +1 -1
  255. package/dist/discovery/aliases.d.ts.map +1 -1
  256. package/dist/discovery/aliases.js +69 -0
  257. package/dist/discovery/aliases.js.map +1 -1
  258. package/dist/discovery/loader.d.ts.map +1 -1
  259. package/dist/discovery/loader.js +130 -0
  260. package/dist/discovery/loader.js.map +1 -1
  261. package/dist/engine/kernel/execute.d.ts.map +1 -1
  262. package/dist/engine/kernel/execute.js +27 -4
  263. package/dist/engine/kernel/execute.js.map +1 -1
  264. package/dist/engine/user-home.d.ts +9 -0
  265. package/dist/engine/user-home.d.ts.map +1 -0
  266. package/dist/engine/user-home.js +12 -0
  267. package/dist/engine/user-home.js.map +1 -0
  268. package/dist/fast-path.d.ts +14 -0
  269. package/dist/fast-path.d.ts.map +1 -0
  270. package/dist/fast-path.js +565 -0
  271. package/dist/fast-path.js.map +1 -0
  272. package/dist/hub/index.d.ts +1 -1
  273. package/dist/hub/index.d.ts.map +1 -1
  274. package/dist/hub/index.js +28 -17
  275. package/dist/hub/index.js.map +1 -1
  276. package/dist/main.js +6 -3
  277. package/dist/main.js.map +1 -1
  278. package/dist/manifest-compact.txt +11 -11
  279. package/dist/manifest-search.json +1 -1
  280. package/dist/manifest.json +27600 -1016
  281. package/dist/mcp/tools.js +1 -1
  282. package/dist/mcp/tools.js.map +1 -1
  283. package/dist/output/error-map.d.ts.map +1 -1
  284. package/dist/output/error-map.js +16 -5
  285. package/dist/output/error-map.js.map +1 -1
  286. package/dist/protocol/acp.js +1 -1
  287. package/dist/protocol/acp.js.map +1 -1
  288. package/dist/registry.d.ts +3 -0
  289. package/dist/registry.d.ts.map +1 -1
  290. package/dist/registry.js +34 -1
  291. package/dist/registry.js.map +1 -1
  292. package/dist/runtime/usage-ledger.d.ts +6 -7
  293. package/dist/runtime/usage-ledger.d.ts.map +1 -1
  294. package/dist/runtime/usage-ledger.js +6 -7
  295. package/dist/runtime/usage-ledger.js.map +1 -1
  296. package/dist/types.d.ts +2 -0
  297. package/dist/types.d.ts.map +1 -1
  298. package/dist/types.js.map +1 -1
  299. package/package.json +12 -6
  300. package/src/adapters/1688/assets.ts +114 -0
  301. package/src/adapters/51job/jobs.ts +327 -0
  302. package/src/adapters/_shared/browser-tools.ts +59 -0
  303. package/src/adapters/antigravity/extra.ts +53 -0
  304. package/src/adapters/baidu-scholar/search.ts +38 -0
  305. package/src/adapters/bilibili/compat.ts +132 -0
  306. package/src/adapters/binance/asks.yaml +41 -0
  307. package/src/adapters/binance/depth.yaml +41 -0
  308. package/src/adapters/binance/gainers.yaml +42 -0
  309. package/src/adapters/binance/hot.yaml +1 -1
  310. package/src/adapters/binance/kline.yaml +1 -1
  311. package/src/adapters/binance/klines.yaml +46 -0
  312. package/src/adapters/binance/losers.yaml +42 -0
  313. package/src/adapters/binance/pairs.yaml +38 -0
  314. package/src/adapters/binance/price.yaml +32 -0
  315. package/src/adapters/binance/prices.yaml +30 -0
  316. package/src/adapters/binance/ticker.yaml +2 -2
  317. package/src/adapters/binance/top.yaml +46 -0
  318. package/src/adapters/binance/trades.yaml +42 -0
  319. package/src/adapters/chatgpt/image.ts +84 -0
  320. package/src/adapters/chatgpt-app/chatgpt-app.ts +11 -0
  321. package/src/adapters/chatwise/extra.ts +36 -0
  322. package/src/adapters/codex/extra.ts +36 -0
  323. package/src/adapters/deepseek/web.ts +203 -0
  324. package/src/adapters/doubao/web.ts +154 -0
  325. package/src/adapters/eastmoney/market-data.ts +829 -0
  326. package/src/adapters/excel/insert-image.yaml +80 -0
  327. package/src/adapters/excel/insert-link.yaml +90 -0
  328. package/src/adapters/excel/list.yaml +63 -0
  329. package/src/adapters/excel/read.yaml +74 -0
  330. package/src/adapters/excel/set-cell.yaml +77 -0
  331. package/src/adapters/excel/set-font.yaml +87 -0
  332. package/src/adapters/excel/status.yaml +29 -0
  333. package/src/adapters/gh/search-repos.yaml +62 -0
  334. package/src/adapters/gitee/user.ts +59 -0
  335. package/src/adapters/google-scholar/cite.ts +95 -0
  336. package/src/adapters/google-scholar/profile.ts +91 -0
  337. package/src/adapters/google-scholar/search.ts +58 -0
  338. package/src/adapters/gov-law/laws.ts +61 -0
  339. package/src/adapters/gov-policy/policy.ts +61 -0
  340. package/src/adapters/imessage/contact.yaml +7 -2
  341. package/src/adapters/imessage/recent.yaml +7 -2
  342. package/src/adapters/imessage/search.yaml +7 -2
  343. package/src/adapters/jd/commerce.ts +142 -0
  344. package/src/adapters/jianyu/detail.ts +28 -0
  345. package/src/adapters/jimeng/workspace.ts +53 -0
  346. package/src/adapters/ke/rent-transaction.ts +70 -0
  347. package/src/adapters/linux-do/search.ts +92 -0
  348. package/src/adapters/linux-do/topic-content.ts +45 -0
  349. package/src/adapters/maimai/talents.ts +65 -0
  350. package/src/adapters/mubu/docs.ts +107 -0
  351. package/src/adapters/nowcoder/nowcoder.ts +570 -0
  352. package/src/adapters/powerchina/search.ts +45 -0
  353. package/src/adapters/powerpoint/add-slide.yaml +93 -0
  354. package/src/adapters/powerpoint/insert-image.yaml +71 -0
  355. package/src/adapters/powerpoint/insert-link.yaml +94 -0
  356. package/src/adapters/powerpoint/list.yaml +58 -0
  357. package/src/adapters/powerpoint/set-font.yaml +101 -0
  358. package/src/adapters/powerpoint/slides.yaml +73 -0
  359. package/src/adapters/powerpoint/status.yaml +29 -0
  360. package/src/adapters/quark/actions.ts +169 -0
  361. package/src/adapters/reddit/browser-utils.ts +93 -0
  362. package/src/adapters/reddit/listings.ts +223 -0
  363. package/src/adapters/reddit/search.ts +74 -0
  364. package/src/adapters/spotify/api.ts +292 -0
  365. package/src/adapters/taobao/commerce.ts +134 -0
  366. package/src/adapters/tdx/hot-rank.ts +35 -0
  367. package/src/adapters/ths/hot-rank.ts +35 -0
  368. package/src/adapters/toutiao/articles.ts +45 -0
  369. package/src/adapters/twitter/lists-extra.ts +139 -0
  370. package/src/adapters/uiverse/components.ts +154 -0
  371. package/src/adapters/vercel/list.yaml +2 -1
  372. package/src/adapters/wanfang/search.ts +38 -0
  373. package/src/adapters/weixin/drafts.ts +74 -0
  374. package/src/adapters/weread/ai-outline.ts +32 -0
  375. package/src/adapters/word/insert-image.yaml +73 -0
  376. package/src/adapters/word/insert-link.yaml +82 -0
  377. package/src/adapters/word/insert-text.yaml +72 -0
  378. package/src/adapters/word/list.yaml +63 -0
  379. package/src/adapters/word/read.yaml +63 -0
  380. package/src/adapters/word/set-font.yaml +97 -0
  381. package/src/adapters/word/status.yaml +29 -0
  382. package/src/adapters/xiaoyuzhou/media.ts +139 -0
  383. package/src/adapters/xueqiu/extra.ts +78 -0
  384. package/src/adapters/youtube/personal.ts +215 -0
  385. package/src/adapters/zhihu/actions.ts +111 -0
  386. package/src/hub/external-clis-harness.yaml +211 -0
  387. package/src/hub/index.ts +29 -25
  388. package/src/adapters/linux-do/search.yaml +0 -44
  389. package/src/adapters/meituan/hot.yaml +0 -34
  390. package/src/adapters/reddit/frontpage.test.ts +0 -15
  391. package/src/adapters/reddit/frontpage.yaml +0 -41
  392. package/src/adapters/reddit/hot.test.ts +0 -15
  393. package/src/adapters/reddit/hot.yaml +0 -41
  394. package/src/adapters/reddit/new.test.ts +0 -15
  395. package/src/adapters/reddit/new.yaml +0 -42
  396. package/src/adapters/reddit/popular.test.ts +0 -15
  397. package/src/adapters/reddit/popular.yaml +0 -41
  398. package/src/adapters/reddit/rising.test.ts +0 -15
  399. package/src/adapters/reddit/rising.yaml +0 -41
  400. package/src/adapters/reddit/search.test.ts +0 -15
  401. package/src/adapters/reddit/search.yaml +0 -52
  402. package/src/adapters/reddit/subreddit.test.ts +0 -15
  403. package/src/adapters/reddit/subreddit.yaml +0 -50
  404. package/src/adapters/reddit/top.test.ts +0 -15
  405. package/src/adapters/reddit/top.yaml +0 -48
  406. package/src/adapters/reddit/trending.test.ts +0 -15
  407. package/src/adapters/reddit/trending.yaml +0 -33
@@ -0,0 +1,78 @@
1
+ import { cli, Strategy } from "../../registry.js";
2
+ import type { IPage } from "../../types.js";
3
+ import { loadCookies, formatCookieHeader } from "../../engine/cookies.js";
4
+ import { USER_AGENT } from "../../constants.js";
5
+ import { intArg, js, str } from "../_shared/browser-tools.js";
6
+
7
+ async function xueqiuJson(url: string): Promise<Record<string, unknown>> {
8
+ const cookies = loadCookies("xueqiu");
9
+ const headers: Record<string, string> = {
10
+ "user-agent": USER_AGENT,
11
+ referer: "https://xueqiu.com",
12
+ accept: "application/json",
13
+ };
14
+ if (cookies) headers.cookie = formatCookieHeader(cookies);
15
+ const response = await fetch(url, { headers });
16
+ if (!response.ok) {
17
+ throw new Error(`Xueqiu request failed: HTTP ${response.status}`);
18
+ }
19
+ return (await response.json()) as Record<string, unknown>;
20
+ }
21
+
22
+ cli({
23
+ site: "xueqiu",
24
+ name: "kline",
25
+ description: "Fetch Xueqiu stock candlestick data",
26
+ domain: "xueqiu.com",
27
+ strategy: Strategy.COOKIE,
28
+ args: [
29
+ { name: "symbol", type: "str", required: true, positional: true },
30
+ { name: "period", type: "str", default: "day" },
31
+ { name: "count", type: "int", default: 120 },
32
+ ],
33
+ columns: ["timestamp", "open", "close", "high", "low", "volume"],
34
+ func: async (_page, kwargs) => {
35
+ const symbol = str(kwargs.symbol).toUpperCase();
36
+ const count = intArg(kwargs.count, 120, 1000);
37
+ const url = new URL("https://stock.xueqiu.com/v5/stock/chart/kline.json");
38
+ url.searchParams.set("symbol", symbol);
39
+ url.searchParams.set("begin", String(Date.now()));
40
+ url.searchParams.set("period", str(kwargs.period, "day"));
41
+ url.searchParams.set("type", "before");
42
+ url.searchParams.set("count", `-${count}`);
43
+ const data = await xueqiuJson(url.href);
44
+ const item = (data.data ?? {}) as Record<string, unknown>;
45
+ const columns = Array.isArray(item.column) ? (item.column as string[]) : [];
46
+ const rows = Array.isArray(item.item) ? (item.item as unknown[][]) : [];
47
+ return rows.map((row) =>
48
+ Object.fromEntries(columns.map((name, i) => [name, row[i]])),
49
+ );
50
+ },
51
+ });
52
+
53
+ cli({
54
+ site: "xueqiu",
55
+ name: "groups",
56
+ description: "Read visible Xueqiu portfolio or group lists",
57
+ domain: "xueqiu.com",
58
+ strategy: Strategy.COOKIE,
59
+ browser: true,
60
+ args: [{ name: "limit", type: "int", default: 20 }],
61
+ columns: ["name", "url"],
62
+ func: async (page, kwargs) => {
63
+ const p = page as IPage;
64
+ const limit = intArg(kwargs.limit, 20, 100);
65
+ await p.goto("https://xueqiu.com/portfolio", { settleMs: 2500 });
66
+ const rows = await p.evaluate(`(() => {
67
+ const links = [...document.querySelectorAll('a[href*="/P/"], a[href*="portfolio"], a[href]')];
68
+ const seen = new Set();
69
+ return links.map((a) => {
70
+ const url = new URL(a.getAttribute('href') || '', location.href).href;
71
+ if (seen.has(url)) return null;
72
+ seen.add(url);
73
+ return { name: (a.textContent || '').replace(/\\s+/g, ' ').trim(), url };
74
+ }).filter((row) => row && row.name).slice(0, ${js(limit)});
75
+ })()`);
76
+ return Array.isArray(rows) ? (rows as Record<string, unknown>[]) : [];
77
+ },
78
+ });
@@ -0,0 +1,215 @@
1
+ import { cli, Strategy } from "../../registry.js";
2
+ import type { IPage } from "../../types.js";
3
+ import { clickFirst, intArg, str } from "../_shared/browser-tools.js";
4
+
5
+ const HOME = "https://www.youtube.com";
6
+
7
+ async function extractVideos(
8
+ page: IPage,
9
+ url: string,
10
+ limit: number,
11
+ ): Promise<Record<string, unknown>[]> {
12
+ await page.goto(url, { settleMs: 2200 });
13
+ const rows = (await page.evaluate(`(() => {
14
+ const anchors = [...document.querySelectorAll('a#video-title, a.yt-simple-endpoint[href*="/watch"], ytd-rich-item-renderer a[href*="/watch"]')];
15
+ const seen = new Set();
16
+ return anchors.map((a) => {
17
+ const href = a.getAttribute('href') || '';
18
+ const url = new URL(href, location.href).href;
19
+ if (!url.includes('/watch') || seen.has(url)) return null;
20
+ seen.add(url);
21
+ const root = a.closest('ytd-video-renderer, ytd-rich-item-renderer, ytd-grid-video-renderer, ytd-playlist-video-renderer') || a.parentElement;
22
+ return {
23
+ title: (a.getAttribute('title') || a.textContent || '').trim(),
24
+ channel: (root?.querySelector('#channel-name, ytd-channel-name')?.textContent || '').trim(),
25
+ meta: (root?.textContent || '').replace(/\\s+/g, ' ').trim().slice(0, 300),
26
+ url
27
+ };
28
+ }).filter(Boolean);
29
+ })()`)) as Record<string, unknown>[];
30
+ return rows.slice(0, limit);
31
+ }
32
+
33
+ async function toggleVideoAction(
34
+ page: IPage,
35
+ target: string,
36
+ selectors: readonly string[],
37
+ ): Promise<Record<string, unknown>[]> {
38
+ const url = target.startsWith("http")
39
+ ? target
40
+ : `${HOME}/watch?v=${encodeURIComponent(target)}`;
41
+ await page.goto(url, { settleMs: 2200 });
42
+ const selector = await clickFirst(page, selectors);
43
+ return [{ ok: selector !== null, selector, url: await page.url() }];
44
+ }
45
+
46
+ cli({
47
+ site: "youtube",
48
+ name: "feed",
49
+ description: "Read YouTube homepage recommended videos",
50
+ domain: "www.youtube.com",
51
+ strategy: Strategy.COOKIE,
52
+ browser: true,
53
+ args: [{ name: "limit", type: "int", default: 20 }],
54
+ columns: ["title", "channel", "url"],
55
+ func: async (page, kwargs) =>
56
+ extractVideos(page as IPage, HOME, intArg(kwargs.limit, 20, 100)),
57
+ });
58
+
59
+ cli({
60
+ site: "youtube",
61
+ name: "history",
62
+ description: "Read YouTube watch history",
63
+ domain: "www.youtube.com",
64
+ strategy: Strategy.COOKIE,
65
+ browser: true,
66
+ args: [{ name: "limit", type: "int", default: 20 }],
67
+ columns: ["title", "channel", "url"],
68
+ func: async (page, kwargs) =>
69
+ extractVideos(
70
+ page as IPage,
71
+ `${HOME}/feed/history`,
72
+ intArg(kwargs.limit, 20, 100),
73
+ ),
74
+ });
75
+
76
+ cli({
77
+ site: "youtube",
78
+ name: "watch-later",
79
+ description: "Read YouTube Watch Later queue",
80
+ domain: "www.youtube.com",
81
+ strategy: Strategy.COOKIE,
82
+ browser: true,
83
+ args: [{ name: "limit", type: "int", default: 20 }],
84
+ columns: ["title", "channel", "url"],
85
+ func: async (page, kwargs) =>
86
+ extractVideos(
87
+ page as IPage,
88
+ `${HOME}/playlist?list=WL`,
89
+ intArg(kwargs.limit, 20, 100),
90
+ ),
91
+ });
92
+
93
+ cli({
94
+ site: "youtube",
95
+ name: "subscriptions",
96
+ description: "List YouTube subscribed channels",
97
+ domain: "www.youtube.com",
98
+ strategy: Strategy.COOKIE,
99
+ browser: true,
100
+ args: [{ name: "limit", type: "int", default: 50 }],
101
+ columns: ["title", "url"],
102
+ func: async (page, kwargs) => {
103
+ const p = page as IPage;
104
+ await p.goto(`${HOME}/feed/channels`, { settleMs: 2200 });
105
+ const limit = intArg(kwargs.limit, 50, 200);
106
+ const rows = (await p.evaluate(`(() => {
107
+ const links = [...document.querySelectorAll('a[href^="/channel/"], a[href^="/@"]')];
108
+ const seen = new Set();
109
+ return links.map((a) => {
110
+ const url = new URL(a.getAttribute('href') || '', location.href).href;
111
+ if (seen.has(url)) return null;
112
+ seen.add(url);
113
+ return { title: (a.textContent || a.getAttribute('title') || '').trim(), url };
114
+ }).filter((row) => row && row.title);
115
+ })()`)) as Record<string, unknown>[];
116
+ return rows.slice(0, limit);
117
+ },
118
+ });
119
+
120
+ cli({
121
+ site: "youtube",
122
+ name: "like",
123
+ description: "Like a YouTube video in the active browser session",
124
+ domain: "www.youtube.com",
125
+ strategy: Strategy.COOKIE,
126
+ browser: true,
127
+ args: [{ name: "video", type: "str", required: true, positional: true }],
128
+ columns: ["ok", "selector", "url"],
129
+ func: async (page, kwargs) =>
130
+ toggleVideoAction(page as IPage, str(kwargs.video), [
131
+ "like-button-view-model button",
132
+ "ytd-toggle-button-renderer:first-of-type button",
133
+ "button[aria-label*='like']",
134
+ "button[aria-label*='喜欢']",
135
+ ]),
136
+ });
137
+
138
+ cli({
139
+ site: "youtube",
140
+ name: "unlike",
141
+ description: "Remove a YouTube video like in the active browser session",
142
+ domain: "www.youtube.com",
143
+ strategy: Strategy.COOKIE,
144
+ browser: true,
145
+ args: [{ name: "video", type: "str", required: true, positional: true }],
146
+ columns: ["ok", "selector", "url"],
147
+ func: async (page, kwargs) =>
148
+ toggleVideoAction(page as IPage, str(kwargs.video), [
149
+ "like-button-view-model button",
150
+ "ytd-toggle-button-renderer:first-of-type button",
151
+ "button[aria-pressed='true'][aria-label*='like']",
152
+ "button[aria-label*='不喜欢']",
153
+ ]),
154
+ });
155
+
156
+ cli({
157
+ site: "youtube",
158
+ name: "subscribe",
159
+ description: "Subscribe to a YouTube channel",
160
+ domain: "www.youtube.com",
161
+ strategy: Strategy.COOKIE,
162
+ browser: true,
163
+ args: [{ name: "channel", type: "str", required: true, positional: true }],
164
+ columns: ["ok", "selector", "url"],
165
+ func: async (page, kwargs) => {
166
+ const p = page as IPage;
167
+ const channel = str(kwargs.channel);
168
+ const url = channel.startsWith("http")
169
+ ? channel
170
+ : channel.startsWith("@")
171
+ ? `${HOME}/${channel}`
172
+ : `${HOME}/channel/${encodeURIComponent(channel)}`;
173
+ await p.goto(url, { settleMs: 2200 });
174
+ const selector = await clickFirst(p, [
175
+ "ytd-subscribe-button-renderer button",
176
+ "button[aria-label*='Subscribe']",
177
+ "button[aria-label*='订阅']",
178
+ ]);
179
+ return [{ ok: selector !== null, selector, url: await p.url() }];
180
+ },
181
+ });
182
+
183
+ cli({
184
+ site: "youtube",
185
+ name: "unsubscribe",
186
+ description: "Unsubscribe from a YouTube channel",
187
+ domain: "www.youtube.com",
188
+ strategy: Strategy.COOKIE,
189
+ browser: true,
190
+ args: [{ name: "channel", type: "str", required: true, positional: true }],
191
+ columns: ["ok", "selector", "url"],
192
+ func: async (page, kwargs) => {
193
+ const p = page as IPage;
194
+ const channel = str(kwargs.channel);
195
+ const url = channel.startsWith("http")
196
+ ? channel
197
+ : channel.startsWith("@")
198
+ ? `${HOME}/${channel}`
199
+ : `${HOME}/channel/${encodeURIComponent(channel)}`;
200
+ await p.goto(url, { settleMs: 2200 });
201
+ const first = await clickFirst(p, [
202
+ "ytd-subscribe-button-renderer button",
203
+ "button[aria-label*='Subscribed']",
204
+ "button[aria-label*='已订阅']",
205
+ ]);
206
+ const confirm = await clickFirst(p, [
207
+ "yt-confirm-dialog-renderer #confirm-button button",
208
+ "tp-yt-paper-dialog button[aria-label*='Unsubscribe']",
209
+ "button[aria-label*='取消订阅']",
210
+ ]);
211
+ return [
212
+ { ok: first !== null, selector: confirm ?? first, url: await p.url() },
213
+ ];
214
+ },
215
+ });
@@ -0,0 +1,111 @@
1
+ import { cli, Strategy } from "../../registry.js";
2
+ import type { IPage } from "../../types.js";
3
+ import { boolArg, clickFirst, js, str } from "../_shared/browser-tools.js";
4
+
5
+ function targetUrl(target: string): string {
6
+ if (target.startsWith("http")) return target;
7
+ const [kind, a, b] = target.split(":");
8
+ if (kind === "question") return `https://www.zhihu.com/question/${a}`;
9
+ if (kind === "answer")
10
+ return `https://www.zhihu.com/question/${a}/answer/${b}`;
11
+ if (kind === "article") return `https://zhuanlan.zhihu.com/p/${a}`;
12
+ if (kind === "user") return `https://www.zhihu.com/people/${a}`;
13
+ return `https://www.zhihu.com/search?type=content&q=${encodeURIComponent(target)}`;
14
+ }
15
+
16
+ function requireExecute(kwargs: Record<string, unknown>): void {
17
+ if (!boolArg(kwargs.execute)) {
18
+ throw new Error("Pass --execute to perform this Zhihu write action");
19
+ }
20
+ }
21
+
22
+ cli({
23
+ site: "zhihu",
24
+ name: "follow",
25
+ description: "Follow a Zhihu user or question",
26
+ domain: "zhihu.com",
27
+ strategy: Strategy.COOKIE,
28
+ browser: true,
29
+ args: [
30
+ { name: "target", type: "str", required: true, positional: true },
31
+ { name: "execute", type: "bool", default: false },
32
+ ],
33
+ columns: ["ok", "selector", "url"],
34
+ func: async (page, kwargs) => {
35
+ requireExecute(kwargs);
36
+ const p = page as IPage;
37
+ await p.goto(targetUrl(str(kwargs.target)), { settleMs: 2500 });
38
+ const selector = await clickFirst(p, [
39
+ "button.FollowButton",
40
+ "button[aria-label*='关注']",
41
+ "button:has(.Zi--Follow)",
42
+ ]);
43
+ return [{ ok: selector !== null, selector, url: await p.url() }];
44
+ },
45
+ });
46
+
47
+ cli({
48
+ site: "zhihu",
49
+ name: "like",
50
+ description: "Like a Zhihu answer or article",
51
+ domain: "zhihu.com",
52
+ strategy: Strategy.COOKIE,
53
+ browser: true,
54
+ args: [
55
+ { name: "target", type: "str", required: true, positional: true },
56
+ { name: "execute", type: "bool", default: false },
57
+ ],
58
+ columns: ["ok", "selector", "url"],
59
+ func: async (page, kwargs) => {
60
+ requireExecute(kwargs);
61
+ const p = page as IPage;
62
+ await p.goto(targetUrl(str(kwargs.target)), { settleMs: 2500 });
63
+ const selector = await clickFirst(p, [
64
+ "button.VoteButton--up",
65
+ "button[aria-label*='赞同']",
66
+ "button[aria-label*='喜欢']",
67
+ ]);
68
+ return [{ ok: selector !== null, selector, url: await p.url() }];
69
+ },
70
+ });
71
+
72
+ cli({
73
+ site: "zhihu",
74
+ name: "favorite",
75
+ description: "Favorite a Zhihu answer or article into an existing collection",
76
+ domain: "zhihu.com",
77
+ strategy: Strategy.COOKIE,
78
+ browser: true,
79
+ args: [
80
+ { name: "target", type: "str", required: true, positional: true },
81
+ { name: "collection", type: "str", required: false },
82
+ { name: "collection_id", type: "str", required: false },
83
+ { name: "execute", type: "bool", default: false },
84
+ ],
85
+ columns: ["ok", "selector", "url"],
86
+ func: async (page, kwargs) => {
87
+ requireExecute(kwargs);
88
+ const p = page as IPage;
89
+ await p.goto(targetUrl(str(kwargs.target)), { settleMs: 2500 });
90
+ await clickFirst(p, [
91
+ "button[aria-label*='收藏']",
92
+ "button:has(.Zi--Star)",
93
+ ".ContentItem-actions button",
94
+ ]);
95
+ await p.wait(0.8);
96
+ if (kwargs.collection) {
97
+ await p.evaluate(`(() => {
98
+ const name = ${js(str(kwargs.collection))};
99
+ const nodes = [...document.querySelectorAll('button, label, div')];
100
+ const node = nodes.find((el) => (el.textContent || '').includes(name));
101
+ if (node) node.click();
102
+ })()`);
103
+ }
104
+ const selector = await clickFirst(p, [
105
+ "button.Button--primary",
106
+ "button[aria-label*='确认']",
107
+ "button[aria-label*='完成']",
108
+ ]);
109
+ return [{ ok: selector !== null, selector, url: await p.url() }];
110
+ },
111
+ });
@@ -0,0 +1,211 @@
1
+ # External CLI Harness Registry — app/tool-specific passthrough CLIs.
2
+ #
3
+ # Loaded after external-clis.yaml. Kept separate so the core registry
4
+ # remains stable while app-level harness coverage can expand quickly.
5
+
6
+ # ── Application and specialist harnesses ────────────────────────────────
7
+
8
+ - name: 1password-cli
9
+ binary: op
10
+ description: "1Password CLI — vault items, secrets, documents, and service accounts"
11
+ homepage: "https://developer.1password.com/docs/cli"
12
+ tags: [passwords, secrets, security]
13
+ json_flag: "--format json"
14
+ install:
15
+ mac: "brew install 1password-cli"
16
+ linux: "https://developer.1password.com/docs/cli/get-started/"
17
+ default: "https://developer.1password.com/docs/cli/get-started/"
18
+
19
+ - name: android-cli
20
+ binary: adb
21
+ description: "Android platform tools — devices, packages, logs, files, and shell automation"
22
+ homepage: "https://developer.android.com/tools/adb"
23
+ tags: [android, mobile, device, automation]
24
+ install:
25
+ mac: "brew install android-platform-tools"
26
+ default: "https://developer.android.com/tools/releases/platform-tools"
27
+
28
+ - name: anygen
29
+ binary: anygen
30
+ description: "AnyGen — generation workflow harness for local creative automation"
31
+ tags: [generation, creative, automation]
32
+
33
+ - name: chromadb
34
+ binary: chroma
35
+ description: "ChromaDB — local vector database server and collection tooling"
36
+ homepage: "https://docs.trychroma.com"
37
+ tags: [vector-db, embeddings, rag]
38
+ install:
39
+ default: "pip install chromadb"
40
+
41
+ - name: cloudanalyzer
42
+ binary: cloudanalyzer
43
+ description: "CloudAnalyzer — cloud inventory and cost/security analysis harness"
44
+ tags: [cloud, analysis, security, cost]
45
+
46
+ - name: contentful
47
+ binary: contentful
48
+ description: "Contentful CLI — spaces, content types, entries, migrations, and releases"
49
+ homepage: "https://www.contentful.com/developers/docs/tutorials/cli/"
50
+ tags: [cms, content, headless]
51
+ json_flag: "--json"
52
+ install:
53
+ default: "npm install -g contentful-cli"
54
+
55
+ - name: dify-workflow
56
+ binary: dify-workflow
57
+ description: "Dify workflow CLI — workflow export, import, testing, and deployment automation"
58
+ homepage: "https://docs.dify.ai"
59
+ tags: [ai, workflow, dify]
60
+
61
+ - name: elevenlabs
62
+ binary: elevenlabs
63
+ description: "ElevenLabs CLI — text-to-speech, voices, dubbing, and audio generation"
64
+ homepage: "https://elevenlabs.io/docs"
65
+ tags: [audio, tts, generation]
66
+
67
+ - name: eth2-quickstart
68
+ binary: eth2-quickstart
69
+ description: "Ethereum validator quickstart tooling"
70
+ homepage: "https://github.com/ethereum/staking-deposit-cli"
71
+ tags: [ethereum, validator, blockchain]
72
+
73
+ - name: exa
74
+ binary: exa
75
+ description: "Exa search CLI — neural web search and answer retrieval"
76
+ homepage: "https://exa.ai"
77
+ tags: [search, web, research]
78
+
79
+ - name: generate-veo-video
80
+ binary: generate-veo-video
81
+ description: "Veo video generation harness"
82
+ tags: [video, generation, ai]
83
+
84
+ - name: intelwatch
85
+ binary: intelwatch
86
+ description: "IntelWatch — local monitoring and telemetry harness"
87
+ tags: [monitoring, telemetry, local]
88
+
89
+ - name: iterm2
90
+ binary: iterm2
91
+ description: "iTerm2 automation harness — windows, tabs, sessions, text, and tmux workflows"
92
+ homepage: "https://iterm2.com/python-api"
93
+ tags: [terminal, macos, automation]
94
+
95
+ - name: lldb
96
+ binary: lldb
97
+ description: "LLDB debugger — breakpoints, processes, frames, variables, and expressions"
98
+ homepage: "https://lldb.llvm.org"
99
+ tags: [debugger, native, development]
100
+ install:
101
+ mac: "xcode-select --install"
102
+ linux: "apt install lldb"
103
+ default: "https://lldb.llvm.org/resources/build.html"
104
+
105
+ - name: n8n
106
+ binary: n8n
107
+ description: "n8n workflow automation — import, export, execute, and manage workflows"
108
+ homepage: "https://docs.n8n.io"
109
+ tags: [workflow, automation, integrations]
110
+ install:
111
+ default: "npm install -g n8n"
112
+
113
+ - name: nsight-graphics
114
+ binary: nsys
115
+ description: "NVIDIA Nsight tooling — capture, inspect, and export graphics/performance sessions"
116
+ homepage: "https://developer.nvidia.com/nsight-graphics"
117
+ tags: [nvidia, graphics, profiling]
118
+
119
+ - name: obs-studio
120
+ binary: obs
121
+ description: "OBS Studio automation — scenes, sources, recording, streaming, and screenshots"
122
+ homepage: "https://obsproject.com"
123
+ tags: [video, streaming, recording]
124
+ install:
125
+ mac: "brew install --cask obs"
126
+ default: "https://obsproject.com/download"
127
+
128
+ - name: openscreen
129
+ binary: openscreen
130
+ description: "OpenScreen casting and presentation automation harness"
131
+ tags: [screen, casting, presentation]
132
+
133
+ - name: pm2
134
+ binary: pm2
135
+ description: "PM2 process manager — start, stop, logs, reload, and process status"
136
+ homepage: "https://pm2.keymetrics.io"
137
+ tags: [node, process-manager, ops]
138
+ json_flag: "--json"
139
+ install:
140
+ default: "npm install -g pm2"
141
+
142
+ - name: py4csr
143
+ binary: py4csr
144
+ description: "py4csr research workflow harness"
145
+ tags: [research, python, workflow]
146
+
147
+ - name: qgis
148
+ binary: qgis
149
+ description: "QGIS desktop and processing automation"
150
+ homepage: "https://qgis.org"
151
+ tags: [gis, maps, geospatial]
152
+ install:
153
+ mac: "brew install --cask qgis"
154
+ default: "https://qgis.org/download/"
155
+
156
+ - name: rms
157
+ binary: rms
158
+ description: "RMS automation harness"
159
+ tags: [automation, workflow]
160
+
161
+ - name: safari
162
+ binary: safari
163
+ description: "Safari browser automation harness"
164
+ homepage: "https://support.apple.com/guide/safari"
165
+ tags: [browser, macos, automation]
166
+
167
+ - name: sanity
168
+ binary: sanity
169
+ description: "Sanity CLI — datasets, schemas, content, deploys, and studio workflows"
170
+ homepage: "https://www.sanity.io/docs/cli"
171
+ tags: [cms, content, headless]
172
+ install:
173
+ default: "npm install -g sanity"
174
+
175
+ - name: seaclip
176
+ binary: seaclip
177
+ description: "SeaClip media understanding harness"
178
+ tags: [vision, media, ai]
179
+
180
+ - name: shopify
181
+ binary: shopify
182
+ description: "Shopify CLI — apps, themes, stores, extensions, and deploy workflows"
183
+ homepage: "https://shopify.dev/docs/api/shopify-cli"
184
+ tags: [commerce, shopify, apps]
185
+ json_flag: "--json"
186
+ install:
187
+ default: "npm install -g @shopify/cli"
188
+
189
+ - name: suno
190
+ binary: suno
191
+ description: "Suno music generation harness"
192
+ tags: [music, audio, generation]
193
+
194
+ - name: unimol_tools
195
+ binary: unimol_tools
196
+ description: "Uni-Mol molecular modeling toolkit"
197
+ homepage: "https://github.com/deepmodeling/Uni-Mol"
198
+ tags: [chemistry, molecular, ai]
199
+ install:
200
+ default: "pip install unimol-tools"
201
+
202
+ - name: unrealinsights
203
+ binary: UnrealInsights
204
+ description: "Unreal Insights profiling and trace analysis"
205
+ homepage: "https://dev.epicgames.com/documentation/unreal-engine/unreal-insights-in-unreal-engine"
206
+ tags: [unreal, profiling, game-dev]
207
+
208
+ - name: videocaptioner
209
+ binary: videocaptioner
210
+ description: "Video captioning workflow harness"
211
+ tags: [video, captions, transcription]