@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,829 @@
1
+ import { cli, Strategy } from "../../registry.js";
2
+
3
+ type JsonRecord = Record<string, unknown>;
4
+
5
+ const A_MARKET = "m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048";
6
+ const QUOTE_FIELDS =
7
+ "f12,f13,f14,f2,f3,f4,f5,f6,f7,f8,f9,f10,f15,f16,f17,f18,f20,f21,f23";
8
+
9
+ function clampInt(value: unknown, fallback: number, max: number): number {
10
+ const n = Number(value);
11
+ if (!Number.isFinite(n)) return fallback;
12
+ return Math.max(1, Math.min(Math.trunc(n), max));
13
+ }
14
+
15
+ async function fetchJson(url: URL | string): Promise<JsonRecord> {
16
+ const resp = await fetch(url, {
17
+ headers: {
18
+ Accept: "application/json,text/plain,*/*",
19
+ "User-Agent": "Mozilla/5.0 (compatible; Uni-CLI)",
20
+ },
21
+ });
22
+ if (!resp.ok) throw new Error(`HTTP ${resp.status}: ${String(url)}`);
23
+ return (await resp.json()) as JsonRecord;
24
+ }
25
+
26
+ function at(obj: unknown, key: string): unknown {
27
+ return obj && typeof obj === "object" ? (obj as JsonRecord)[key] : undefined;
28
+ }
29
+
30
+ function rowsAt(data: unknown, path: string[]): JsonRecord[] {
31
+ let cur = data;
32
+ for (const key of path) cur = at(cur, key);
33
+ return Array.isArray(cur) ? (cur as JsonRecord[]) : [];
34
+ }
35
+
36
+ function str(value: unknown): string {
37
+ return value === undefined || value === null ? "" : String(value);
38
+ }
39
+
40
+ function sortSpec(
41
+ key: string,
42
+ specs: Record<string, { fid: string; order: "asc" | "desc" }>,
43
+ fallback: string,
44
+ ): { fid: string; order: "asc" | "desc" } {
45
+ return specs[key] ?? specs[fallback]!;
46
+ }
47
+
48
+ function marketFs(key: string): string {
49
+ const markets: Record<string, string> = {
50
+ "hs-a": A_MARKET,
51
+ "sh-a": "m:1+t:2,m:1+t:23",
52
+ "sz-a": "m:0+t:6,m:0+t:80",
53
+ "bj-a": "m:0+t:81+s:2048",
54
+ cyb: "m:0+t:80",
55
+ kcb: "m:1+t:23",
56
+ hk: "m:116+t:3,m:116+t:4,m:116+t:1,m:116+t:2",
57
+ us: "m:105,m:106,m:107",
58
+ };
59
+ return markets[key] ?? markets["hs-a"]!;
60
+ }
61
+
62
+ function clistUrl(config: {
63
+ fs: string;
64
+ fid: string;
65
+ order: "asc" | "desc";
66
+ limit: number;
67
+ fields: string;
68
+ ut?: string;
69
+ }): URL {
70
+ const url = new URL("https://push2.eastmoney.com/api/qt/clist/get");
71
+ url.searchParams.set("pn", "1");
72
+ url.searchParams.set("pz", String(config.limit));
73
+ url.searchParams.set("po", config.order === "desc" ? "1" : "0");
74
+ url.searchParams.set("np", "1");
75
+ url.searchParams.set("fltt", "2");
76
+ url.searchParams.set("invt", "2");
77
+ url.searchParams.set("fid", config.fid);
78
+ url.searchParams.set("fs", config.fs);
79
+ url.searchParams.set("fields", config.fields);
80
+ url.searchParams.set("ut", config.ut ?? "bd1d9ddb04089700cf9c27f6f7426281");
81
+ return url;
82
+ }
83
+
84
+ function resolveSecid(input: unknown): string {
85
+ const raw = str(input).trim();
86
+ if (!raw) throw new Error("symbol is required");
87
+ const secid = raw.match(/^(\d{1,3})\.([A-Za-z0-9]+)$/);
88
+ if (secid) return raw;
89
+ const lower = raw.toLowerCase();
90
+ const pref = lower.match(/^(sh|sz|bj)(\d{6})$/);
91
+ if (pref) return `${pref[1] === "sh" ? "1" : "0"}.${pref[2]}`;
92
+ const hk = lower.match(/^hk(\d{4,5})$/) ?? lower.match(/^(\d{4,5})\.hk$/);
93
+ if (hk) return `116.${hk[1]!.padStart(5, "0")}`;
94
+ const usPref = lower.match(/^us\.([a-z.-]+)$/);
95
+ if (usPref) return `105.${usPref[1]!.toUpperCase()}`;
96
+ if (/^\d{6}$/.test(raw)) {
97
+ return /^(60|68|90|113|900)/.test(raw) ? `1.${raw}` : `0.${raw}`;
98
+ }
99
+ if (/^[A-Z.-]{1,8}$/.test(raw)) return `105.${raw}`;
100
+ throw new Error(`unrecognized symbol: ${raw}`);
101
+ }
102
+
103
+ function secucode(input: unknown): string {
104
+ const raw = str(input).trim().toUpperCase();
105
+ if (/^\d{6}\.(SH|SZ|BJ)$/.test(raw)) return raw;
106
+ const pref = raw.match(/^(SH|SZ|BJ)(\d{6})$/);
107
+ if (pref) return `${pref[2]}.${pref[1]}`;
108
+ if (/^\d{6}$/.test(raw)) {
109
+ if (/^(60|68|90|113|900)/.test(raw)) return `${raw}.SH`;
110
+ if (/^(4|8|920|83|87)/.test(raw)) return `${raw}.BJ`;
111
+ return `${raw}.SZ`;
112
+ }
113
+ throw new Error(`unrecognized A-share symbol: ${raw}`);
114
+ }
115
+
116
+ function marketLabel(value: unknown): string {
117
+ if (value === 1) return "SH";
118
+ if (value === 0) return "SZ/BJ";
119
+ if (value === 116) return "HK";
120
+ if (value === 105 || value === 106 || value === 107) return "US";
121
+ return str(value);
122
+ }
123
+
124
+ cli({
125
+ site: "eastmoney",
126
+ name: "quote",
127
+ description: "东方财富个股实时行情(A股 / 港股 / 美股)",
128
+ domain: "push2.eastmoney.com",
129
+ strategy: Strategy.PUBLIC,
130
+ args: [
131
+ {
132
+ name: "symbols",
133
+ type: "str",
134
+ required: true,
135
+ positional: true,
136
+ description: "股票代码,支持逗号或空格分隔多个",
137
+ },
138
+ ],
139
+ columns: ["code", "name", "market", "price", "changePercent", "turnover"],
140
+ func: async (_page, kwargs) => {
141
+ const raw = str(kwargs.symbols)
142
+ .split(/[,,\s]+/)
143
+ .filter(Boolean);
144
+ const url = new URL("https://push2.eastmoney.com/api/qt/ulist.np/get");
145
+ url.searchParams.set("secids", raw.map(resolveSecid).join(","));
146
+ url.searchParams.set("fltt", "2");
147
+ url.searchParams.set("fields", QUOTE_FIELDS);
148
+ url.searchParams.set("ut", "bd1d9ddb04089700cf9c27f6f7426281");
149
+ const diff = rowsAt(await fetchJson(url), ["data", "diff"]);
150
+ return diff.map((it) => ({
151
+ code: it.f12,
152
+ name: it.f14,
153
+ market: marketLabel(it.f13),
154
+ price: it.f2,
155
+ changePercent: it.f3,
156
+ change: it.f4,
157
+ open: it.f17,
158
+ high: it.f15,
159
+ low: it.f16,
160
+ prevClose: it.f18,
161
+ volume: it.f5,
162
+ turnover: it.f6,
163
+ turnoverRate: it.f8,
164
+ amplitude: it.f7,
165
+ peDynamic: it.f9,
166
+ priceBook: it.f23,
167
+ marketCap: it.f20,
168
+ floatMarketCap: it.f21,
169
+ }));
170
+ },
171
+ });
172
+
173
+ cli({
174
+ site: "eastmoney",
175
+ name: "rank",
176
+ description: "东方财富市场涨跌/成交排行(沪深/北证/港/美)",
177
+ domain: "push2.eastmoney.com",
178
+ strategy: Strategy.PUBLIC,
179
+ args: [
180
+ {
181
+ name: "market",
182
+ type: "str",
183
+ default: "hs-a",
184
+ description: "hs-a/sh-a/sz-a/bj-a/cyb/kcb/hk/us",
185
+ },
186
+ {
187
+ name: "sort",
188
+ type: "str",
189
+ default: "change",
190
+ description: "change/drop/turnover/volume/amplitude/rate",
191
+ },
192
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
193
+ ],
194
+ columns: ["rank", "code", "name", "price", "changePercent", "turnover"],
195
+ func: async (_page, kwargs) => {
196
+ const sorts = {
197
+ change: { fid: "f3", order: "desc" },
198
+ drop: { fid: "f3", order: "asc" },
199
+ turnover: { fid: "f6", order: "desc" },
200
+ volume: { fid: "f5", order: "desc" },
201
+ amplitude: { fid: "f7", order: "desc" },
202
+ rate: { fid: "f8", order: "desc" },
203
+ } as const;
204
+ const sort = sortSpec(str(kwargs.sort).toLowerCase(), sorts, "change");
205
+ const rows = rowsAt(
206
+ await fetchJson(
207
+ clistUrl({
208
+ fs: marketFs(str(kwargs.market).toLowerCase()),
209
+ fid: sort.fid,
210
+ order: sort.order,
211
+ limit: clampInt(kwargs.limit, 20, 100),
212
+ fields: QUOTE_FIELDS,
213
+ }),
214
+ ),
215
+ ["data", "diff"],
216
+ );
217
+ return rows.map((it, i) => ({
218
+ rank: i + 1,
219
+ code: it.f12,
220
+ name: it.f14,
221
+ price: it.f2,
222
+ changePercent: it.f3,
223
+ change: it.f4,
224
+ turnover: it.f6,
225
+ volume: it.f5,
226
+ turnoverRate: it.f8,
227
+ peDynamic: it.f9,
228
+ marketCap: it.f20,
229
+ }));
230
+ },
231
+ });
232
+
233
+ cli({
234
+ site: "eastmoney",
235
+ name: "etf",
236
+ description: "东方财富 ETF 列表按成交额/涨跌幅排行",
237
+ domain: "push2.eastmoney.com",
238
+ strategy: Strategy.PUBLIC,
239
+ args: [
240
+ {
241
+ name: "sort",
242
+ type: "str",
243
+ default: "turnover",
244
+ description: "turnover/change/drop/volume/rate",
245
+ },
246
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
247
+ ],
248
+ columns: ["rank", "code", "name", "price", "changePercent", "turnover"],
249
+ func: async (_page, kwargs) => {
250
+ const sorts = {
251
+ turnover: { fid: "f6", order: "desc" },
252
+ change: { fid: "f3", order: "desc" },
253
+ drop: { fid: "f3", order: "asc" },
254
+ volume: { fid: "f5", order: "desc" },
255
+ rate: { fid: "f8", order: "desc" },
256
+ } as const;
257
+ const sort = sortSpec(str(kwargs.sort).toLowerCase(), sorts, "turnover");
258
+ const rows = rowsAt(
259
+ await fetchJson(
260
+ clistUrl({
261
+ fs: "b:MK0021",
262
+ fid: sort.fid,
263
+ order: sort.order,
264
+ limit: clampInt(kwargs.limit, 20, 100),
265
+ fields: "f12,f14,f2,f3,f4,f5,f6,f8",
266
+ }),
267
+ ),
268
+ ["data", "diff"],
269
+ );
270
+ return rows.map((it, i) => ({
271
+ rank: i + 1,
272
+ code: it.f12,
273
+ name: it.f14,
274
+ price: it.f2,
275
+ changePercent: it.f3,
276
+ change: it.f4,
277
+ turnover: it.f6,
278
+ volume: it.f5,
279
+ turnoverRate: it.f8,
280
+ }));
281
+ },
282
+ });
283
+
284
+ cli({
285
+ site: "eastmoney",
286
+ name: "convertible",
287
+ description: "东方财富可转债行情列表",
288
+ domain: "push2.eastmoney.com",
289
+ strategy: Strategy.PUBLIC,
290
+ args: [
291
+ {
292
+ name: "sort",
293
+ type: "str",
294
+ default: "turnover",
295
+ description: "turnover/change/drop/price/premium/value/ytm",
296
+ },
297
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
298
+ ],
299
+ columns: [
300
+ "rank",
301
+ "bondCode",
302
+ "bondName",
303
+ "bondPrice",
304
+ "bondChangePct",
305
+ "convPremiumPct",
306
+ ],
307
+ func: async (_page, kwargs) => {
308
+ const sorts = {
309
+ change: { fid: "f3", order: "desc" },
310
+ drop: { fid: "f3", order: "asc" },
311
+ turnover: { fid: "f6", order: "desc" },
312
+ price: { fid: "f2", order: "desc" },
313
+ premium: { fid: "f237", order: "desc" },
314
+ value: { fid: "f236", order: "desc" },
315
+ ytm: { fid: "f239", order: "desc" },
316
+ } as const;
317
+ const sort = sortSpec(str(kwargs.sort).toLowerCase(), sorts, "turnover");
318
+ const rows = rowsAt(
319
+ await fetchJson(
320
+ clistUrl({
321
+ fs: "b:MK0354",
322
+ fid: sort.fid,
323
+ order: sort.order,
324
+ limit: clampInt(kwargs.limit, 20, 100),
325
+ fields:
326
+ "f12,f14,f2,f3,f6,f229,f230,f232,f234,f235,f236,f237,f238,f239,f243",
327
+ }),
328
+ ),
329
+ ["data", "diff"],
330
+ );
331
+ return rows.map((it, i) => ({
332
+ rank: i + 1,
333
+ bondCode: it.f12,
334
+ bondName: it.f14,
335
+ bondPrice: it.f2,
336
+ bondChangePct: it.f3,
337
+ stockCode: it.f232,
338
+ stockName: it.f234,
339
+ convPrice: it.f235,
340
+ convValue: it.f236,
341
+ convPremiumPct: it.f237,
342
+ remainingYears: it.f238,
343
+ ytm: it.f239,
344
+ listDate: str(it.f243),
345
+ }));
346
+ },
347
+ });
348
+
349
+ cli({
350
+ site: "eastmoney",
351
+ name: "sectors",
352
+ description: "东方财富板块排行(行业/概念/地域)",
353
+ domain: "push2.eastmoney.com",
354
+ strategy: Strategy.PUBLIC,
355
+ args: [
356
+ {
357
+ name: "type",
358
+ type: "str",
359
+ default: "industry",
360
+ description: "industry/concept/region",
361
+ },
362
+ {
363
+ name: "sort",
364
+ type: "str",
365
+ default: "change",
366
+ description: "change/drop/money-flow/out-flow/turnover",
367
+ },
368
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
369
+ ],
370
+ columns: ["rank", "code", "name", "changePercent", "mainNet", "leadStock"],
371
+ func: async (_page, kwargs) => {
372
+ const sectorTypes: Record<string, string> = {
373
+ industry: "m:90+t:2",
374
+ concept: "m:90+t:3",
375
+ region: "m:90+t:1",
376
+ };
377
+ const sorts = {
378
+ change: { fid: "f3", order: "desc" },
379
+ drop: { fid: "f3", order: "asc" },
380
+ "money-flow": { fid: "f62", order: "desc" },
381
+ "out-flow": { fid: "f62", order: "asc" },
382
+ turnover: { fid: "f6", order: "desc" },
383
+ } as const;
384
+ const sort = sortSpec(str(kwargs.sort).toLowerCase(), sorts, "change");
385
+ const rows = rowsAt(
386
+ await fetchJson(
387
+ clistUrl({
388
+ fs:
389
+ sectorTypes[str(kwargs.type).toLowerCase()] ??
390
+ sectorTypes.industry!,
391
+ fid: sort.fid,
392
+ order: sort.order,
393
+ limit: clampInt(kwargs.limit, 20, 100),
394
+ fields: "f12,f14,f2,f3,f62,f104,f105,f128,f136,f140,f141",
395
+ ut: "b2884a393a59ad64002292a3e90d46a5",
396
+ }),
397
+ ),
398
+ ["data", "diff"],
399
+ );
400
+ return rows.map((it, i) => ({
401
+ rank: i + 1,
402
+ code: it.f12,
403
+ name: it.f14,
404
+ price: it.f2,
405
+ changePercent: it.f3,
406
+ mainNet: it.f62,
407
+ leadStock: it.f128,
408
+ leadChangePercent: it.f136,
409
+ upCount: it.f104,
410
+ downCount: it.f105,
411
+ }));
412
+ },
413
+ });
414
+
415
+ cli({
416
+ site: "eastmoney",
417
+ name: "index-board",
418
+ description: "东方财富主要市场指数行情(A股 / 港股 / 美股)",
419
+ domain: "push2.eastmoney.com",
420
+ strategy: Strategy.PUBLIC,
421
+ args: [
422
+ {
423
+ name: "group",
424
+ type: "str",
425
+ default: "main",
426
+ description: "main/hk/us/all",
427
+ },
428
+ ],
429
+ columns: ["code", "name", "price", "changePercent", "change"],
430
+ func: async (_page, kwargs) => {
431
+ const groups: Record<string, string[]> = {
432
+ main: [
433
+ "1.000001",
434
+ "0.399001",
435
+ "0.399006",
436
+ "1.000688",
437
+ "1.000300",
438
+ "1.000905",
439
+ ],
440
+ hk: ["100.HSI", "100.HSCEI", "100.HSTECH"],
441
+ us: ["100.DJIA", "100.SPX", "100.NDX", "100.IXIC"],
442
+ };
443
+ const key = str(kwargs.group).toLowerCase();
444
+ const secids =
445
+ key === "all"
446
+ ? Object.values(groups).flat()
447
+ : (groups[key] ?? groups.main!);
448
+ const url = new URL("https://push2.eastmoney.com/api/qt/ulist.np/get");
449
+ url.searchParams.set("secids", secids.join(","));
450
+ url.searchParams.set("fltt", "2");
451
+ url.searchParams.set("fields", "f2,f3,f4,f12,f13,f14,f15,f16,f17,f18");
452
+ url.searchParams.set("ut", "bd1d9ddb04089700cf9c27f6f7426281");
453
+ return rowsAt(await fetchJson(url), ["data", "diff"]).map((it) => ({
454
+ code: it.f12,
455
+ name: it.f14,
456
+ price: it.f2,
457
+ changePercent: it.f3,
458
+ change: it.f4,
459
+ high: it.f15,
460
+ low: it.f16,
461
+ open: it.f17,
462
+ prevClose: it.f18,
463
+ }));
464
+ },
465
+ });
466
+
467
+ cli({
468
+ site: "eastmoney",
469
+ name: "money-flow",
470
+ description: "东方财富主力资金净流入排行",
471
+ domain: "push2.eastmoney.com",
472
+ strategy: Strategy.PUBLIC,
473
+ args: [
474
+ {
475
+ name: "range",
476
+ type: "str",
477
+ default: "today",
478
+ description: "today/5d/10d",
479
+ },
480
+ { name: "order", type: "str", default: "desc", description: "desc/asc" },
481
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
482
+ ],
483
+ columns: ["rank", "code", "name", "price", "changePercent", "mainNet"],
484
+ func: async (_page, kwargs) => {
485
+ const ranges: Record<string, { fid: string; net: string; netPct: string }> =
486
+ {
487
+ today: { fid: "f62", net: "f62", netPct: "f184" },
488
+ "5d": { fid: "f164", net: "f164", netPct: "f165" },
489
+ "10d": { fid: "f174", net: "f174", netPct: "f175" },
490
+ };
491
+ const range = ranges[str(kwargs.range).toLowerCase()] ?? ranges.today!;
492
+ const rows = rowsAt(
493
+ await fetchJson(
494
+ clistUrl({
495
+ fs: A_MARKET,
496
+ fid: range.fid,
497
+ order: str(kwargs.order).toLowerCase() === "asc" ? "asc" : "desc",
498
+ limit: clampInt(kwargs.limit, 20, 100),
499
+ fields: [
500
+ "f12",
501
+ "f14",
502
+ "f2",
503
+ "f3",
504
+ range.net,
505
+ range.netPct,
506
+ "f66",
507
+ "f72",
508
+ "f78",
509
+ "f84",
510
+ ].join(","),
511
+ ut: "b2884a393a59ad64002292a3e90d46a5",
512
+ }),
513
+ ),
514
+ ["data", "diff"],
515
+ );
516
+ return rows.map((it, i) => ({
517
+ rank: i + 1,
518
+ code: it.f12,
519
+ name: it.f14,
520
+ price: it.f2,
521
+ changePercent: it.f3,
522
+ mainNet: it[range.net],
523
+ mainNetRatio: it[range.netPct],
524
+ superNet: it.f66,
525
+ bigNet: it.f72,
526
+ mediumNet: it.f78,
527
+ smallNet: it.f84,
528
+ }));
529
+ },
530
+ });
531
+
532
+ cli({
533
+ site: "eastmoney",
534
+ name: "northbound",
535
+ description: "东方财富沪深港通北向/南向资金分时净流入",
536
+ domain: "push2.eastmoney.com",
537
+ strategy: Strategy.PUBLIC,
538
+ args: [
539
+ {
540
+ name: "direction",
541
+ type: "str",
542
+ default: "north",
543
+ description: "north/south",
544
+ },
545
+ { name: "limit", type: "int", default: 10, description: "返回最近 N 分钟" },
546
+ ],
547
+ columns: ["time", "cumulativeNetYi", "minuteNetYi", "totalNetYi"],
548
+ func: async (_page, kwargs) => {
549
+ const url = new URL("https://push2.eastmoney.com/api/qt/kamtbs.rtmin/get");
550
+ url.searchParams.set("fields1", "f1,f2,f3,f4");
551
+ url.searchParams.set("fields2", "f51,f52,f54,f56");
552
+ url.searchParams.set("ut", "b2884a393a59ad64002292a3e90d46a5");
553
+ const key = ["south", "s"].includes(str(kwargs.direction).toLowerCase())
554
+ ? "s2n"
555
+ : "n2s";
556
+ const rows = at(at(await fetchJson(url), "data"), key);
557
+ const parsed = Array.isArray(rows)
558
+ ? rows
559
+ .map((r) => str(r).split(","))
560
+ .filter((cols) => cols.length >= 4 && cols[1] !== "-")
561
+ : [];
562
+ return parsed
563
+ .slice(-clampInt(kwargs.limit, 10, 240))
564
+ .map(([time, cum, minute, total]) => ({
565
+ time,
566
+ cumulativeNetYi: +(Number(cum) / 10000).toFixed(4),
567
+ minuteNetYi: +(Number(minute) / 10000).toFixed(4),
568
+ totalNetYi: +(Number(total) / 10000).toFixed(4),
569
+ }));
570
+ },
571
+ });
572
+
573
+ cli({
574
+ site: "eastmoney",
575
+ name: "announcement",
576
+ description: "东方财富上市公司公告",
577
+ domain: "np-anotice-stock.eastmoney.com",
578
+ strategy: Strategy.PUBLIC,
579
+ args: [
580
+ {
581
+ name: "market",
582
+ type: "str",
583
+ default: "SHA,SZA,BJA",
584
+ description: "SHA/SZA/BJA,可逗号分隔",
585
+ },
586
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
587
+ ],
588
+ columns: ["time", "code", "name", "title", "category", "url"],
589
+ func: async (_page, kwargs) => {
590
+ const url = new URL(
591
+ "https://np-anotice-stock.eastmoney.com/api/security/ann",
592
+ );
593
+ url.searchParams.set("page_size", String(clampInt(kwargs.limit, 20, 100)));
594
+ url.searchParams.set("page_index", "1");
595
+ url.searchParams.set("ann_type", str(kwargs.market) || "SHA,SZA,BJA");
596
+ url.searchParams.set("client_source", "web");
597
+ url.searchParams.set("f_node", "0");
598
+ url.searchParams.set("s_node", "0");
599
+ return rowsAt(await fetchJson(url), ["data", "list"]).map((it) => {
600
+ const codes = Array.isArray(it.codes) ? (it.codes as JsonRecord[]) : [];
601
+ const columns = Array.isArray(it.columns)
602
+ ? (it.columns as JsonRecord[])
603
+ : [];
604
+ const primary = codes[0] ?? {};
605
+ return {
606
+ time: str(it.notice_date ?? it.display_time).slice(0, 19),
607
+ code: primary.stock_code ?? "",
608
+ name: primary.short_name ?? "",
609
+ title: it.title ?? it.title_ch ?? "",
610
+ category: columns[0]?.column_name ?? "",
611
+ url: `https://data.eastmoney.com/notices/detail/${str(primary.stock_code)}/${str(it.art_code)}.html`,
612
+ };
613
+ });
614
+ },
615
+ });
616
+
617
+ cli({
618
+ site: "eastmoney",
619
+ name: "holders",
620
+ description: "东方财富十大流通股东(A股 F10)",
621
+ domain: "datacenter-web.eastmoney.com",
622
+ strategy: Strategy.PUBLIC,
623
+ args: [
624
+ {
625
+ name: "symbol",
626
+ type: "str",
627
+ required: true,
628
+ positional: true,
629
+ description: "A股代码",
630
+ },
631
+ { name: "limit", type: "int", default: 10, description: "返回股东数" },
632
+ ],
633
+ columns: ["rank", "reportDate", "name", "holdNum", "floatRatio", "change"],
634
+ func: async (_page, kwargs) => {
635
+ const url = new URL("https://datacenter-web.eastmoney.com/api/data/v1/get");
636
+ url.searchParams.set("sortColumns", "END_DATE,HOLDER_RANK");
637
+ url.searchParams.set("sortTypes", "-1,1");
638
+ url.searchParams.set(
639
+ "pageSize",
640
+ String(Math.max(clampInt(kwargs.limit, 10, 50), 10)),
641
+ );
642
+ url.searchParams.set("pageNumber", "1");
643
+ url.searchParams.set("reportName", "RPT_F10_EH_FREEHOLDERS");
644
+ url.searchParams.set(
645
+ "columns",
646
+ "SECUCODE,SECURITY_CODE,END_DATE,HOLDER_RANK,HOLDER_NAME,HOLD_NUM,FREE_HOLDNUM_RATIO,HOLD_NUM_CHANGE",
647
+ );
648
+ url.searchParams.set("source", "HSF10");
649
+ url.searchParams.set("client", "PC");
650
+ url.searchParams.set("filter", `(SECUCODE="${secucode(kwargs.symbol)}")`);
651
+ const rows = rowsAt(await fetchJson(url), ["result", "data"]);
652
+ const latest = str(rows[0]?.END_DATE).slice(0, 10);
653
+ return rows
654
+ .filter((it) => str(it.END_DATE).slice(0, 10) === latest)
655
+ .slice(0, clampInt(kwargs.limit, 10, 50))
656
+ .map((it) => ({
657
+ rank: it.HOLDER_RANK,
658
+ reportDate: latest,
659
+ name: it.HOLDER_NAME,
660
+ holdNum: it.HOLD_NUM,
661
+ floatRatio: it.FREE_HOLDNUM_RATIO,
662
+ change: it.HOLD_NUM_CHANGE,
663
+ }));
664
+ },
665
+ });
666
+
667
+ cli({
668
+ site: "eastmoney",
669
+ name: "longhu",
670
+ description: "东方财富龙虎榜明细",
671
+ domain: "datacenter-web.eastmoney.com",
672
+ strategy: Strategy.PUBLIC,
673
+ args: [
674
+ {
675
+ name: "date",
676
+ type: "str",
677
+ default: "",
678
+ description: "开始交易日 YYYY-MM-DD",
679
+ },
680
+ { name: "limit", type: "int", default: 20, description: "返回数量" },
681
+ ],
682
+ columns: [
683
+ "tradeDate",
684
+ "code",
685
+ "name",
686
+ "closePrice",
687
+ "changeRate",
688
+ "netAmt",
689
+ "reason",
690
+ ],
691
+ func: async (_page, kwargs) => {
692
+ const date =
693
+ str(kwargs.date) ||
694
+ new Date(Date.now() - 30 * 86400_000).toISOString().slice(0, 10);
695
+ const url = new URL("https://datacenter-web.eastmoney.com/api/data/v1/get");
696
+ url.searchParams.set("sortColumns", "TRADE_DATE,SECURITY_CODE");
697
+ url.searchParams.set("sortTypes", "-1,1");
698
+ url.searchParams.set("pageSize", String(clampInt(kwargs.limit, 20, 100)));
699
+ url.searchParams.set("pageNumber", "1");
700
+ url.searchParams.set("reportName", "RPT_DAILYBILLBOARD_DETAILS");
701
+ url.searchParams.set("columns", "ALL");
702
+ url.searchParams.set("source", "WEB");
703
+ url.searchParams.set("client", "WEB");
704
+ url.searchParams.set("filter", `(TRADE_DATE>='${date}')`);
705
+ return rowsAt(await fetchJson(url), ["result", "data"]).map((it) => ({
706
+ tradeDate: str(it.TRADE_DATE).slice(0, 10),
707
+ code: it.SECURITY_CODE,
708
+ name: it.SECURITY_NAME_ABBR,
709
+ closePrice: it.CLOSE_PRICE,
710
+ changeRate: it.CHANGE_RATE,
711
+ boardAmt: it.BILLBOARD_DEAL_AMT,
712
+ buyAmt: it.BILLBOARD_BUY_AMT,
713
+ sellAmt: it.BILLBOARD_SELL_AMT,
714
+ netAmt: it.BILLBOARD_NET_AMT,
715
+ reason: it.EXPLANATION,
716
+ }));
717
+ },
718
+ });
719
+
720
+ cli({
721
+ site: "eastmoney",
722
+ name: "kuaixun",
723
+ description: "东方财富财经快讯",
724
+ domain: "kuaixun.eastmoney.com",
725
+ strategy: Strategy.PUBLIC,
726
+ args: [{ name: "limit", type: "int", default: 20, description: "返回数量" }],
727
+ columns: ["time", "title", "summary", "url"],
728
+ func: async (_page, kwargs) => {
729
+ const url = new URL(
730
+ "https://np-weblist.eastmoney.com/comm/web/getFastNewsList",
731
+ );
732
+ url.searchParams.set("client", "web");
733
+ url.searchParams.set("page_index", "1");
734
+ url.searchParams.set("page_size", String(clampInt(kwargs.limit, 20, 100)));
735
+ return rowsAt(await fetchJson(url), ["data", "fastNewsList"]).map((it) => ({
736
+ time: str(it.showTime ?? it.createTime).slice(0, 19),
737
+ title: it.title ?? "",
738
+ summary: it.summary ?? it.digest ?? "",
739
+ url: it.url ?? "",
740
+ }));
741
+ },
742
+ });
743
+
744
+ cli({
745
+ site: "eastmoney",
746
+ name: "kline",
747
+ description: "东方财富个股 K 线行情",
748
+ domain: "push2his.eastmoney.com",
749
+ strategy: Strategy.PUBLIC,
750
+ args: [
751
+ {
752
+ name: "symbol",
753
+ type: "str",
754
+ required: true,
755
+ positional: true,
756
+ description: "股票代码",
757
+ },
758
+ {
759
+ name: "period",
760
+ type: "str",
761
+ default: "daily",
762
+ description: "daily/weekly/monthly",
763
+ },
764
+ { name: "limit", type: "int", default: 20, description: "返回 K 线数" },
765
+ ],
766
+ columns: ["date", "open", "close", "high", "low", "volume", "amount"],
767
+ func: async (_page, kwargs) => {
768
+ const periods: Record<string, string> = {
769
+ daily: "101",
770
+ weekly: "102",
771
+ monthly: "103",
772
+ };
773
+ const url = new URL(
774
+ "https://push2his.eastmoney.com/api/qt/stock/kline/get",
775
+ );
776
+ url.searchParams.set("secid", resolveSecid(kwargs.symbol));
777
+ url.searchParams.set("fields1", "f1,f2,f3,f4,f5,f6");
778
+ url.searchParams.set(
779
+ "fields2",
780
+ "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",
781
+ );
782
+ url.searchParams.set(
783
+ "klt",
784
+ periods[str(kwargs.period).toLowerCase()] ?? "101",
785
+ );
786
+ url.searchParams.set("fqt", "1");
787
+ url.searchParams.set("end", "20500101");
788
+ url.searchParams.set("lmt", String(clampInt(kwargs.limit, 20, 500)));
789
+ const rows = at(at(await fetchJson(url), "data"), "klines");
790
+ return (Array.isArray(rows) ? rows : []).map((row) => {
791
+ const [date, open, close, high, low, volume, amount] =
792
+ str(row).split(",");
793
+ return { date, open, close, high, low, volume, amount };
794
+ });
795
+ },
796
+ });
797
+
798
+ cli({
799
+ site: "eastmoney",
800
+ name: "hot-rank",
801
+ description: "东方财富热股榜(按成交额近似排序)",
802
+ domain: "push2.eastmoney.com",
803
+ strategy: Strategy.PUBLIC,
804
+ args: [{ name: "limit", type: "int", default: 20, description: "返回数量" }],
805
+ columns: ["rank", "symbol", "name", "price", "changePercent", "heat", "url"],
806
+ func: async (_page, kwargs) => {
807
+ const rows = rowsAt(
808
+ await fetchJson(
809
+ clistUrl({
810
+ fs: A_MARKET,
811
+ fid: "f6",
812
+ order: "desc",
813
+ limit: clampInt(kwargs.limit, 20, 100),
814
+ fields: "f12,f14,f2,f3,f6",
815
+ }),
816
+ ),
817
+ ["data", "diff"],
818
+ );
819
+ return rows.map((it, i) => ({
820
+ rank: i + 1,
821
+ symbol: it.f12,
822
+ name: it.f14,
823
+ price: it.f2,
824
+ changePercent: it.f3,
825
+ heat: it.f6,
826
+ url: `https://guba.eastmoney.com/list,${str(it.f12)}.html`,
827
+ }));
828
+ },
829
+ });