@agentrhq/webcmd 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (929) hide show
  1. package/README.md +183 -218
  2. package/cli-manifest.json +16247 -34913
  3. package/clis/_atlassian/shared.js +1 -1
  4. package/clis/booking/search.js +4 -4
  5. package/clis/chatgpt/ask.js +2 -2
  6. package/clis/chatgpt/utils.js +41 -42
  7. package/clis/chatgpt/utils.test.js +23 -23
  8. package/clis/chatgpt-app/ax.js +5 -5
  9. package/clis/chatgpt-app/ax.test.js +8 -8
  10. package/clis/chatgpt-app/new.js +2 -2
  11. package/clis/codex/sidebar.js +1 -1
  12. package/clis/codex/sidebar.test.js +12 -12
  13. package/clis/coingecko/top.js +3 -3
  14. package/clis/dblp/dblp.test.js +1 -1
  15. package/clis/discord-app/search.js +1 -1
  16. package/clis/discord-app/utils.js +6 -6
  17. package/clis/facebook/__fixtures__/notifications-page.html +6 -6
  18. package/clis/facebook/add-friend.js +2 -2
  19. package/clis/facebook/feed.js +18 -18
  20. package/clis/facebook/friends.js +4 -4
  21. package/clis/facebook/groups.js +3 -3
  22. package/clis/facebook/join-group.js +2 -2
  23. package/clis/facebook/marketplace-inbox.js +3 -3
  24. package/clis/facebook/marketplace-listings.js +1 -1
  25. package/clis/facebook/notifications.js +14 -15
  26. package/clis/facebook/notifications.test.js +28 -29
  27. package/clis/gemini/ask.test.js +12 -12
  28. package/clis/gemini/deep-research-result.js +2 -2
  29. package/clis/gemini/deep-research-result.test.js +2 -2
  30. package/clis/gemini/deep-research.js +2 -2
  31. package/clis/gemini/deep-research.test.js +1 -1
  32. package/clis/gemini/models.js +11 -11
  33. package/clis/gemini/models.test.js +1 -1
  34. package/clis/gemini/reply-state.test.js +89 -89
  35. package/clis/gemini/utils.js +41 -41
  36. package/clis/gemini/utils.test.js +30 -30
  37. package/clis/geogebra/utils.js +1 -1
  38. package/clis/google-scholar/search.js +3 -3
  39. package/clis/grok/delete.js +1 -1
  40. package/clis/grok/export-all.js +2 -2
  41. package/clis/grok/export.js +2 -2
  42. package/clis/grok/pin.js +3 -3
  43. package/clis/grok/utils.js +12 -12
  44. package/clis/grok/utils.test.js +2 -2
  45. package/clis/indeed/indeed.test.js +3 -3
  46. package/clis/indeed/utils.js +1 -1
  47. package/clis/instagram/post.js +19 -19
  48. package/clis/instagram/post.test.js +2 -2
  49. package/clis/instagram/reel.js +6 -6
  50. package/clis/linkedin/connect.js +3 -3
  51. package/clis/linkedin/people-search.js +4 -4
  52. package/clis/linkedin/profile-experience.js +6 -6
  53. package/clis/linkedin/profile-experience.test.js +10 -10
  54. package/clis/linkedin/profile-read.js +1 -1
  55. package/clis/linkedin/safe-send.js +1 -1
  56. package/clis/linkedin/search.js +1 -1
  57. package/clis/linkedin/shared.js +2 -2
  58. package/clis/linkedin/timeline.js +5 -5
  59. package/clis/manus/manus.test.js +2 -2
  60. package/clis/medium/feed.js +3 -3
  61. package/clis/medium/search.js +3 -3
  62. package/clis/medium/user.js +3 -3
  63. package/clis/notebooklm/auth.js +2 -2
  64. package/clis/notebooklm/note-list.test.js +4 -4
  65. package/clis/notebooklm/notes-get.test.js +8 -8
  66. package/clis/notebooklm/source-fulltext.test.js +11 -11
  67. package/clis/notebooklm/utils.js +28 -28
  68. package/clis/notebooklm/utils.test.js +10 -10
  69. package/clis/pixiv/search.test.js +3 -3
  70. package/clis/qoder/quest.js +2 -2
  71. package/clis/reddit/home.js +2 -2
  72. package/clis/reddit/hot.js +1 -1
  73. package/clis/reddit/read.js +2 -2
  74. package/clis/reddit/read.test.js +1 -1
  75. package/clis/reddit/reply.js +2 -2
  76. package/clis/reddit/whoami.js +2 -2
  77. package/clis/reuters/article-detail.js +1 -1
  78. package/clis/reuters/search.js +1 -1
  79. package/clis/slock/attachment-upload.test.js +1 -1
  80. package/clis/slock/task-convert.js +1 -1
  81. package/clis/substack/feed.js +3 -3
  82. package/clis/substack/publication.js +3 -3
  83. package/clis/substack/search.js +4 -4
  84. package/clis/tiktok/comment.js +2 -2
  85. package/clis/tiktok/follow.js +4 -4
  86. package/clis/tiktok/like.js +1 -1
  87. package/clis/tiktok/save.js +1 -1
  88. package/clis/tiktok/unfollow.js +4 -4
  89. package/clis/tiktok/unlike.js +1 -1
  90. package/clis/tiktok/unsave.js +2 -2
  91. package/clis/tiktok/write-refactor.test.js +5 -5
  92. package/clis/twitter/accept.js +3 -3
  93. package/clis/twitter/followers.js +1 -1
  94. package/clis/twitter/list-remove-core.js +2 -2
  95. package/clis/twitter/list-tweets.test.js +3 -3
  96. package/clis/twitter/lists.js +6 -6
  97. package/clis/twitter/lists.test.js +2 -2
  98. package/clis/twitter/reply-dm.js +1 -1
  99. package/clis/twitter/shared.test.js +4 -5
  100. package/clis/twitter/trending.js +1 -1
  101. package/clis/twitter/utils.js +1 -1
  102. package/clis/web/read.js +1 -1
  103. package/clis/web/read.test.js +2 -2
  104. package/clis/yahoo-finance/quote.js +1 -1
  105. package/clis/youtube/history.js +4 -4
  106. package/clis/youtube/transcript-group.js +1 -1
  107. package/clis/youtube/transcript-group.test.js +5 -5
  108. package/clis/youtube/transcript.js +5 -5
  109. package/clis/youtube/video.js +4 -4
  110. package/clis/youtube/video.test.js +6 -6
  111. package/dist/src/browser/analyze.test.js +13 -13
  112. package/dist/src/browser/bridge-readiness.d.ts +1 -1
  113. package/dist/src/browser/daemon-client.d.ts +1 -0
  114. package/dist/src/browser/daemon-client.js +102 -50
  115. package/dist/src/browser/daemon-client.test.js +104 -19
  116. package/dist/src/browser/errors.js +11 -0
  117. package/dist/src/browser/protocol.d.ts +2 -0
  118. package/dist/src/browser.test.js +2 -2
  119. package/dist/src/cli-argv-preprocess.d.ts +2 -2
  120. package/dist/src/cli-argv-preprocess.js +2 -2
  121. package/dist/src/cli-argv-preprocess.test.js +35 -35
  122. package/dist/src/cli.js +2 -2
  123. package/dist/src/cli.test.js +57 -57
  124. package/dist/src/commanderAdapter.test.js +19 -19
  125. package/dist/src/convention-audit.js +1 -1
  126. package/dist/src/daemon/server.js +28 -23
  127. package/dist/src/daemon/server.test.js +52 -0
  128. package/dist/src/daemon-utils.d.ts +1 -0
  129. package/dist/src/daemon-utils.js +9 -0
  130. package/dist/src/daemon.test.js +10 -1
  131. package/dist/src/doctor.js +7 -1
  132. package/dist/src/doctor.test.js +8 -1
  133. package/dist/src/download/article-download.d.ts +3 -3
  134. package/dist/src/download/article-download.js +7 -7
  135. package/dist/src/download/article-download.test.js +6 -6
  136. package/dist/src/download/index.js +1 -1
  137. package/dist/src/download/index.test.js +1 -2
  138. package/dist/src/download/media-download.d.ts +1 -1
  139. package/dist/src/download/media-download.js +1 -1
  140. package/dist/src/electron-apps.js +0 -8
  141. package/dist/src/electron-apps.test.js +2 -11
  142. package/dist/src/errors.test.js +9 -9
  143. package/dist/src/execution.js +2 -0
  144. package/dist/src/execution.test.js +12 -0
  145. package/dist/src/external-clis.yaml +0 -37
  146. package/dist/src/external.d.ts +1 -1
  147. package/dist/src/external.test.js +2 -17
  148. package/dist/src/generate-release-notes-cli.test.js +140 -0
  149. package/dist/src/help.d.ts +3 -3
  150. package/dist/src/help.test.js +8 -8
  151. package/dist/src/main.js +1 -1
  152. package/dist/src/manifest-types.d.ts +1 -1
  153. package/dist/src/node-network.test.js +2 -2
  154. package/dist/src/output.js +1 -1
  155. package/dist/src/pipeline/steps/download.test.js +3 -3
  156. package/dist/src/registry.test.js +2 -2
  157. package/dist/src/release-notes.d.ts +38 -0
  158. package/dist/src/release-notes.js +99 -0
  159. package/dist/src/release-notes.test.js +61 -0
  160. package/dist/src/serialization.test.js +7 -7
  161. package/dist/src/snapshotFormatter.js +3 -5
  162. package/dist/src/snapshotFormatter.test.d.ts +1 -1
  163. package/dist/src/snapshotFormatter.test.js +50 -50
  164. package/dist/src/tui.js +1 -1
  165. package/package.json +4 -1
  166. package/scripts/generate-release-notes.ts +234 -0
  167. package/scripts/postinstall.js +1 -1
  168. package/scripts/silent-column-drop-baseline.json +0 -498
  169. package/scripts/typed-error-lint-baseline.json +0 -464
  170. package/skills/webcmd-adapter-author/SKILL.md +216 -213
  171. package/skills/webcmd-adapter-author/references/adapter-template.md +206 -399
  172. package/skills/webcmd-adapter-author/references/api-discovery.md +111 -220
  173. package/skills/webcmd-adapter-author/references/coverage-matrix.md +34 -68
  174. package/skills/webcmd-adapter-author/references/field-conventions.md +84 -167
  175. package/skills/webcmd-adapter-author/references/field-decode-playbook.md +60 -146
  176. package/skills/webcmd-adapter-author/references/jsdom-fixture-pattern.md +111 -178
  177. package/skills/webcmd-adapter-author/references/output-design.md +47 -125
  178. package/skills/webcmd-adapter-author/references/site-memory.md +116 -166
  179. package/skills/webcmd-adapter-author/references/site-recon.md +74 -78
  180. package/skills/webcmd-adapter-author/references/strategy-selection.md +80 -124
  181. package/skills/webcmd-adapter-author/references/success-rate-pitfalls.md +80 -105
  182. package/skills/webcmd-adapter-author/references/typed-errors.md +87 -178
  183. package/skills/webcmd-autofix/SKILL.md +136 -143
  184. package/skills/webcmd-sitemap-author/SKILL.md +58 -67
  185. package/skills/webcmd-sitemap-author/references/sitemap-schema.md +354 -494
  186. package/skills/webcmd-usage/SKILL.md +106 -97
  187. package/clis/12306/auth.js +0 -59
  188. package/clis/12306/me.js +0 -73
  189. package/clis/12306/orders.js +0 -96
  190. package/clis/12306/passengers.js +0 -90
  191. package/clis/12306/price.js +0 -166
  192. package/clis/12306/stations.js +0 -66
  193. package/clis/12306/train.js +0 -91
  194. package/clis/12306/trains.js +0 -166
  195. package/clis/12306/utils.js +0 -272
  196. package/clis/12306/utils.test.js +0 -424
  197. package/clis/1688/assets.js +0 -205
  198. package/clis/1688/assets.test.js +0 -39
  199. package/clis/1688/auth.js +0 -46
  200. package/clis/1688/download.js +0 -77
  201. package/clis/1688/download.test.js +0 -31
  202. package/clis/1688/item.js +0 -188
  203. package/clis/1688/item.test.js +0 -67
  204. package/clis/1688/search.js +0 -310
  205. package/clis/1688/search.test.js +0 -75
  206. package/clis/1688/shared.js +0 -557
  207. package/clis/1688/shared.test.js +0 -57
  208. package/clis/1688/store.js +0 -227
  209. package/clis/1688/store.test.js +0 -62
  210. package/clis/1point3acres/auth.js +0 -52
  211. package/clis/1point3acres/digest.js +0 -35
  212. package/clis/1point3acres/forum.js +0 -51
  213. package/clis/1point3acres/forums.js +0 -44
  214. package/clis/1point3acres/hot.js +0 -35
  215. package/clis/1point3acres/latest.js +0 -35
  216. package/clis/1point3acres/notifications.js +0 -64
  217. package/clis/1point3acres/search.js +0 -71
  218. package/clis/1point3acres/thread.js +0 -117
  219. package/clis/1point3acres/user.js +0 -77
  220. package/clis/1point3acres/utils.js +0 -247
  221. package/clis/36kr/article.js +0 -66
  222. package/clis/36kr/article.test.js +0 -46
  223. package/clis/36kr/hot.js +0 -87
  224. package/clis/36kr/hot.test.js +0 -15
  225. package/clis/36kr/news.js +0 -52
  226. package/clis/36kr/news.test.js +0 -85
  227. package/clis/36kr/search.js +0 -79
  228. package/clis/51job/company.js +0 -126
  229. package/clis/51job/detail.js +0 -109
  230. package/clis/51job/hot.js +0 -56
  231. package/clis/51job/search.js +0 -80
  232. package/clis/51job/utils.js +0 -302
  233. package/clis/51job/utils.test.js +0 -69
  234. package/clis/aibase/news.js +0 -110
  235. package/clis/aibase/news.test.js +0 -59
  236. package/clis/autohome/__fixtures__/catalog.html +0 -11
  237. package/clis/autohome/__fixtures__/koubei.json +0 -116
  238. package/clis/autohome/autohome.test.js +0 -115
  239. package/clis/autohome/brand.js +0 -108
  240. package/clis/autohome/score.js +0 -103
  241. package/clis/autohome/utils.js +0 -157
  242. package/clis/baidu-scholar/search.js +0 -87
  243. package/clis/baidu-scholar/search.test.js +0 -23
  244. package/clis/bilibili/auth.js +0 -36
  245. package/clis/bilibili/comment.js +0 -107
  246. package/clis/bilibili/comment.test.js +0 -153
  247. package/clis/bilibili/comments.js +0 -136
  248. package/clis/bilibili/comments.test.js +0 -142
  249. package/clis/bilibili/download.js +0 -178
  250. package/clis/bilibili/download.test.js +0 -173
  251. package/clis/bilibili/dynamic.js +0 -34
  252. package/clis/bilibili/dynamic.test.js +0 -68
  253. package/clis/bilibili/favorite.js +0 -47
  254. package/clis/bilibili/feed.js +0 -220
  255. package/clis/bilibili/follow.js +0 -140
  256. package/clis/bilibili/follow.test.js +0 -203
  257. package/clis/bilibili/following.js +0 -44
  258. package/clis/bilibili/history.js +0 -45
  259. package/clis/bilibili/hot.js +0 -40
  260. package/clis/bilibili/hot.test.js +0 -17
  261. package/clis/bilibili/me.js +0 -13
  262. package/clis/bilibili/ranking.js +0 -25
  263. package/clis/bilibili/search.js +0 -24
  264. package/clis/bilibili/subtitle.js +0 -141
  265. package/clis/bilibili/subtitle.test.js +0 -240
  266. package/clis/bilibili/summary.js +0 -167
  267. package/clis/bilibili/summary.test.js +0 -210
  268. package/clis/bilibili/unfollow.js +0 -121
  269. package/clis/bilibili/user-videos.js +0 -39
  270. package/clis/bilibili/utils.js +0 -273
  271. package/clis/bilibili/utils.test.js +0 -97
  272. package/clis/bilibili/video.js +0 -155
  273. package/clis/bilibili/video.test.js +0 -308
  274. package/clis/boss/auth.js +0 -47
  275. package/clis/boss/batchgreet.js +0 -61
  276. package/clis/boss/chatlist.js +0 -116
  277. package/clis/boss/chatlist.test.js +0 -211
  278. package/clis/boss/chatmsg.js +0 -117
  279. package/clis/boss/chatmsg.test.js +0 -230
  280. package/clis/boss/detail.js +0 -63
  281. package/clis/boss/exchange.js +0 -46
  282. package/clis/boss/greet.js +0 -49
  283. package/clis/boss/invite.js +0 -64
  284. package/clis/boss/joblist.js +0 -31
  285. package/clis/boss/mark.js +0 -70
  286. package/clis/boss/recommend.js +0 -45
  287. package/clis/boss/resume.js +0 -150
  288. package/clis/boss/search.js +0 -197
  289. package/clis/boss/search.test.js +0 -78
  290. package/clis/boss/send.js +0 -44
  291. package/clis/boss/stats.js +0 -66
  292. package/clis/boss/utils.js +0 -468
  293. package/clis/boss/utils.test.js +0 -34
  294. package/clis/chaoxing/assignments.js +0 -76
  295. package/clis/chaoxing/auth.js +0 -54
  296. package/clis/chaoxing/exams.js +0 -75
  297. package/clis/chaoxing/utils.js +0 -223
  298. package/clis/chaoxing/utils.test.js +0 -45
  299. package/clis/cnki/search.js +0 -61
  300. package/clis/cnki/search.test.js +0 -18
  301. package/clis/ctrip/auth.js +0 -50
  302. package/clis/ctrip/ctrip.test.js +0 -719
  303. package/clis/ctrip/flight.js +0 -136
  304. package/clis/ctrip/hotel-search.js +0 -132
  305. package/clis/ctrip/hotel-suggest.js +0 -45
  306. package/clis/ctrip/search.js +0 -41
  307. package/clis/ctrip/utils.js +0 -473
  308. package/clis/deepseek/ask.js +0 -158
  309. package/clis/deepseek/ask.test.js +0 -399
  310. package/clis/deepseek/auth.js +0 -54
  311. package/clis/deepseek/detail.js +0 -46
  312. package/clis/deepseek/detail.test.js +0 -81
  313. package/clis/deepseek/history.js +0 -27
  314. package/clis/deepseek/new.js +0 -33
  315. package/clis/deepseek/read.js +0 -25
  316. package/clis/deepseek/send.js +0 -140
  317. package/clis/deepseek/send.test.js +0 -107
  318. package/clis/deepseek/status.js +0 -26
  319. package/clis/deepseek/utils.js +0 -487
  320. package/clis/deepseek/utils.test.js +0 -370
  321. package/clis/dianping/__fixtures__/search.html +0 -168
  322. package/clis/dianping/__fixtures__/shop.html +0 -6
  323. package/clis/dianping/auth.js +0 -49
  324. package/clis/dianping/cityResolver.js +0 -185
  325. package/clis/dianping/dianping.test.js +0 -578
  326. package/clis/dianping/search.js +0 -157
  327. package/clis/dianping/shop.js +0 -173
  328. package/clis/dianping/utils.js +0 -157
  329. package/clis/dongchedi/__fixtures__/search.json +0 -60
  330. package/clis/dongchedi/__fixtures__/series-detail.json +0 -911
  331. package/clis/dongchedi/__fixtures__/series-score.json +0 -1396
  332. package/clis/dongchedi/dongchedi.test.js +0 -191
  333. package/clis/dongchedi/koubei.js +0 -85
  334. package/clis/dongchedi/models.js +0 -91
  335. package/clis/dongchedi/score.js +0 -83
  336. package/clis/dongchedi/search.js +0 -83
  337. package/clis/dongchedi/series.js +0 -87
  338. package/clis/dongchedi/specs.js +0 -115
  339. package/clis/dongchedi/utils.js +0 -180
  340. package/clis/douban/auth.js +0 -50
  341. package/clis/douban/book-hot.js +0 -15
  342. package/clis/douban/download.js +0 -68
  343. package/clis/douban/download.test.js +0 -170
  344. package/clis/douban/marks.js +0 -116
  345. package/clis/douban/movie-hot.js +0 -15
  346. package/clis/douban/movie-hot.test.js +0 -14
  347. package/clis/douban/photos.js +0 -35
  348. package/clis/douban/reviews.js +0 -107
  349. package/clis/douban/search.js +0 -18
  350. package/clis/douban/search.test.js +0 -11
  351. package/clis/douban/subject.js +0 -46
  352. package/clis/douban/subject.test.js +0 -11
  353. package/clis/douban/top250.js +0 -68
  354. package/clis/douban/utils.js +0 -657
  355. package/clis/douban/utils.test.js +0 -488
  356. package/clis/doubao/ask.js +0 -40
  357. package/clis/doubao/auth.js +0 -66
  358. package/clis/doubao/detail.js +0 -35
  359. package/clis/doubao/detail.test.js +0 -42
  360. package/clis/doubao/history.js +0 -30
  361. package/clis/doubao/history.test.js +0 -37
  362. package/clis/doubao/meeting-summary.js +0 -41
  363. package/clis/doubao/meeting-transcript.js +0 -38
  364. package/clis/doubao/new.js +0 -22
  365. package/clis/doubao/read.js +0 -21
  366. package/clis/doubao/send.js +0 -24
  367. package/clis/doubao/status.js +0 -26
  368. package/clis/doubao/utils.js +0 -1156
  369. package/clis/doubao/utils.test.js +0 -396
  370. package/clis/doubao-app/ask.js +0 -54
  371. package/clis/doubao-app/dump.js +0 -25
  372. package/clis/doubao-app/new.js +0 -21
  373. package/clis/doubao-app/read.js +0 -19
  374. package/clis/doubao-app/screenshot.js +0 -19
  375. package/clis/doubao-app/send.js +0 -28
  376. package/clis/doubao-app/status.js +0 -17
  377. package/clis/doubao-app/utils.js +0 -110
  378. package/clis/douyin/_shared/browser-fetch.js +0 -66
  379. package/clis/douyin/_shared/browser-fetch.test.js +0 -64
  380. package/clis/douyin/_shared/creation-id.js +0 -5
  381. package/clis/douyin/_shared/creation-id.test.js +0 -22
  382. package/clis/douyin/_shared/evaluate-result.js +0 -16
  383. package/clis/douyin/_shared/imagex-upload.js +0 -53
  384. package/clis/douyin/_shared/imagex-upload.test.js +0 -87
  385. package/clis/douyin/_shared/public-api.js +0 -29
  386. package/clis/douyin/_shared/sts2.js +0 -21
  387. package/clis/douyin/_shared/sts2.test.js +0 -27
  388. package/clis/douyin/_shared/text-extra.js +0 -15
  389. package/clis/douyin/_shared/text-extra.test.js +0 -37
  390. package/clis/douyin/_shared/timing.js +0 -22
  391. package/clis/douyin/_shared/timing.test.js +0 -28
  392. package/clis/douyin/_shared/tos-upload-short-read.test.js +0 -83
  393. package/clis/douyin/_shared/tos-upload.js +0 -331
  394. package/clis/douyin/_shared/tos-upload.test.js +0 -229
  395. package/clis/douyin/_shared/transcode.js +0 -45
  396. package/clis/douyin/_shared/transcode.test.js +0 -91
  397. package/clis/douyin/_shared/vod-upload.js +0 -212
  398. package/clis/douyin/_shared/vod-upload.test.js +0 -38
  399. package/clis/douyin/activities.js +0 -23
  400. package/clis/douyin/activities.test.js +0 -55
  401. package/clis/douyin/auth.js +0 -39
  402. package/clis/douyin/collections.js +0 -23
  403. package/clis/douyin/collections.test.js +0 -45
  404. package/clis/douyin/delete.js +0 -152
  405. package/clis/douyin/delete.test.js +0 -100
  406. package/clis/douyin/draft.js +0 -355
  407. package/clis/douyin/draft.test.js +0 -335
  408. package/clis/douyin/drafts.js +0 -24
  409. package/clis/douyin/drafts.test.js +0 -11
  410. package/clis/douyin/hashtag.js +0 -114
  411. package/clis/douyin/hashtag.test.js +0 -171
  412. package/clis/douyin/location.js +0 -25
  413. package/clis/douyin/location.test.js +0 -23
  414. package/clis/douyin/profile.js +0 -29
  415. package/clis/douyin/profile.test.js +0 -46
  416. package/clis/douyin/publish-upload-id.test.js +0 -206
  417. package/clis/douyin/publish.js +0 -341
  418. package/clis/douyin/publish.test.js +0 -38
  419. package/clis/douyin/search.js +0 -308
  420. package/clis/douyin/search.test.js +0 -307
  421. package/clis/douyin/stats.js +0 -28
  422. package/clis/douyin/stats.test.js +0 -22
  423. package/clis/douyin/update.js +0 -32
  424. package/clis/douyin/update.test.js +0 -11
  425. package/clis/douyin/user-videos.js +0 -82
  426. package/clis/douyin/user-videos.test.js +0 -151
  427. package/clis/douyin/videos.js +0 -52
  428. package/clis/douyin/videos.test.js +0 -54
  429. package/clis/eastmoney/_secid.js +0 -78
  430. package/clis/eastmoney/announcement.js +0 -53
  431. package/clis/eastmoney/convertible.js +0 -74
  432. package/clis/eastmoney/etf.js +0 -66
  433. package/clis/eastmoney/holders.js +0 -79
  434. package/clis/eastmoney/hot-rank.js +0 -51
  435. package/clis/eastmoney/hot-rank.test.js +0 -59
  436. package/clis/eastmoney/index-board.js +0 -97
  437. package/clis/eastmoney/kline.js +0 -88
  438. package/clis/eastmoney/kuaixun.js +0 -55
  439. package/clis/eastmoney/longhu.js +0 -68
  440. package/clis/eastmoney/money-flow.js +0 -79
  441. package/clis/eastmoney/northbound.js +0 -58
  442. package/clis/eastmoney/quote.js +0 -108
  443. package/clis/eastmoney/rank.js +0 -95
  444. package/clis/eastmoney/sectors.js +0 -77
  445. package/clis/flomo/auth.js +0 -55
  446. package/clis/flomo/memos.js +0 -228
  447. package/clis/flomo/memos.test.js +0 -144
  448. package/clis/gitee/auth.js +0 -41
  449. package/clis/gitee/index.js +0 -3
  450. package/clis/gitee/search.js +0 -137
  451. package/clis/gitee/search.test.js +0 -65
  452. package/clis/gitee/trending.js +0 -568
  453. package/clis/gitee/user.js +0 -200
  454. package/clis/gitee/user.test.js +0 -63
  455. package/clis/gov-law/commands.test.js +0 -39
  456. package/clis/gov-law/recent.js +0 -22
  457. package/clis/gov-law/search.js +0 -41
  458. package/clis/gov-law/shared.js +0 -51
  459. package/clis/gov-policy/__fixtures__/recent.html +0 -16
  460. package/clis/gov-policy/__fixtures__/search.html +0 -41
  461. package/clis/gov-policy/gov-policy.test.js +0 -224
  462. package/clis/gov-policy/recent.js +0 -90
  463. package/clis/gov-policy/search.js +0 -91
  464. package/clis/gov-policy/utils.js +0 -54
  465. package/clis/guazi/__fixtures__/detail.html +0 -7
  466. package/clis/guazi/__fixtures__/list.html +0 -5
  467. package/clis/guazi/browse.js +0 -95
  468. package/clis/guazi/car.js +0 -110
  469. package/clis/guazi/guazi.test.js +0 -126
  470. package/clis/guazi/utils.js +0 -133
  471. package/clis/huodongxing/events.js +0 -322
  472. package/clis/huodongxing/events.test.js +0 -296
  473. package/clis/hupu/__fixtures__/hot-home.html +0 -64
  474. package/clis/hupu/auth.js +0 -47
  475. package/clis/hupu/detail.js +0 -72
  476. package/clis/hupu/hot.js +0 -163
  477. package/clis/hupu/hot.test.js +0 -224
  478. package/clis/hupu/like.js +0 -76
  479. package/clis/hupu/mentions.js +0 -160
  480. package/clis/hupu/reply.js +0 -72
  481. package/clis/hupu/search.js +0 -60
  482. package/clis/hupu/unlike.js +0 -76
  483. package/clis/hupu/utils.js +0 -319
  484. package/clis/jd/add-cart.js +0 -72
  485. package/clis/jd/auth.js +0 -46
  486. package/clis/jd/cart.js +0 -80
  487. package/clis/jd/commands.test.js +0 -41
  488. package/clis/jd/detail.js +0 -63
  489. package/clis/jd/item.js +0 -730
  490. package/clis/jd/item.test.js +0 -354
  491. package/clis/jd/item.test.ts +0 -517
  492. package/clis/jd/reviews.js +0 -55
  493. package/clis/jd/search.js +0 -66
  494. package/clis/jianyu/auth.js +0 -62
  495. package/clis/jianyu/detail.js +0 -21
  496. package/clis/jianyu/search.js +0 -634
  497. package/clis/jianyu/search.test.js +0 -153
  498. package/clis/jianyu/shared/china-bid-search.js +0 -165
  499. package/clis/jianyu/shared/procurement-contract.js +0 -324
  500. package/clis/jianyu/shared/procurement-contract.test.js +0 -72
  501. package/clis/jianyu/shared/procurement-detail.js +0 -107
  502. package/clis/jianyu/shared/procurement-detail.test.js +0 -84
  503. package/clis/jike/auth.js +0 -48
  504. package/clis/jike/comment.js +0 -107
  505. package/clis/jike/create.js +0 -106
  506. package/clis/jike/feed.js +0 -68
  507. package/clis/jike/like.js +0 -61
  508. package/clis/jike/notifications.js +0 -169
  509. package/clis/jike/post.js +0 -72
  510. package/clis/jike/read.test.js +0 -86
  511. package/clis/jike/repost.js +0 -103
  512. package/clis/jike/search.js +0 -68
  513. package/clis/jike/topic.js +0 -65
  514. package/clis/jike/user.js +0 -65
  515. package/clis/jike/utils.js +0 -25
  516. package/clis/jimeng/auth.js +0 -46
  517. package/clis/jimeng/generate.js +0 -84
  518. package/clis/jimeng/history.js +0 -48
  519. package/clis/jimeng/new.js +0 -44
  520. package/clis/jimeng/workspaces.js +0 -42
  521. package/clis/juejin/hot.js +0 -37
  522. package/clis/juejin/juejin.test.js +0 -241
  523. package/clis/juejin/recommend.js +0 -61
  524. package/clis/juejin/utils.js +0 -199
  525. package/clis/ke/auth.js +0 -46
  526. package/clis/ke/chengjiao.js +0 -78
  527. package/clis/ke/ershoufang.js +0 -101
  528. package/clis/ke/utils.js +0 -104
  529. package/clis/ke/xiaoqu.js +0 -78
  530. package/clis/ke/zufang.js +0 -95
  531. package/clis/kimi/_utils.js +0 -110
  532. package/clis/kimi/audit-extras.js +0 -268
  533. package/clis/kimi/auth.js +0 -57
  534. package/clis/kimi/chat.js +0 -470
  535. package/clis/kimi/kimi.test.js +0 -187
  536. package/clis/kimi/storage.js +0 -169
  537. package/clis/kimi/ui.js +0 -314
  538. package/clis/kimi/usage.js +0 -144
  539. package/clis/linux-do/auth.js +0 -55
  540. package/clis/linux-do/categories.js +0 -50
  541. package/clis/linux-do/feed.js +0 -395
  542. package/clis/linux-do/feed.test.js +0 -153
  543. package/clis/linux-do/search.js +0 -29
  544. package/clis/linux-do/tags.js +0 -28
  545. package/clis/linux-do/topic-content.js +0 -155
  546. package/clis/linux-do/topic-content.test.js +0 -59
  547. package/clis/linux-do/topic.js +0 -53
  548. package/clis/linux-do/user-posts.js +0 -57
  549. package/clis/linux-do/user-topics.js +0 -37
  550. package/clis/maimai/auth.js +0 -47
  551. package/clis/maimai/search-talents.js +0 -192
  552. package/clis/maimai/search-talents.test.js +0 -29
  553. package/clis/mubu/doc.js +0 -41
  554. package/clis/mubu/docs.js +0 -44
  555. package/clis/mubu/notes.js +0 -245
  556. package/clis/mubu/recent.js +0 -28
  557. package/clis/mubu/search.js +0 -63
  558. package/clis/mubu/utils.js +0 -304
  559. package/clis/nowcoder/auth.js +0 -65
  560. package/clis/nowcoder/companies.js +0 -24
  561. package/clis/nowcoder/creators.js +0 -28
  562. package/clis/nowcoder/detail.js +0 -62
  563. package/clis/nowcoder/experience.js +0 -37
  564. package/clis/nowcoder/hot.js +0 -25
  565. package/clis/nowcoder/jobs.js +0 -22
  566. package/clis/nowcoder/notifications.js +0 -30
  567. package/clis/nowcoder/papers.js +0 -41
  568. package/clis/nowcoder/practice.js +0 -38
  569. package/clis/nowcoder/recommend.js +0 -31
  570. package/clis/nowcoder/referral.js +0 -40
  571. package/clis/nowcoder/salary.js +0 -41
  572. package/clis/nowcoder/search.js +0 -50
  573. package/clis/nowcoder/suggest.js +0 -34
  574. package/clis/nowcoder/topics.js +0 -28
  575. package/clis/nowcoder/trending.js +0 -26
  576. package/clis/ones/common.js +0 -144
  577. package/clis/ones/enrich-tasks.js +0 -37
  578. package/clis/ones/login.js +0 -81
  579. package/clis/ones/logout.js +0 -18
  580. package/clis/ones/me.js +0 -31
  581. package/clis/ones/my-tasks.js +0 -121
  582. package/clis/ones/resolve-labels.js +0 -64
  583. package/clis/ones/task-helpers.js +0 -212
  584. package/clis/ones/task-helpers.test.js +0 -12
  585. package/clis/ones/task.js +0 -67
  586. package/clis/ones/tasks.js +0 -80
  587. package/clis/ones/token-info.js +0 -43
  588. package/clis/ones/worklog.js +0 -268
  589. package/clis/ones/worklog.test.js +0 -20
  590. package/clis/powerchina/auth.js +0 -52
  591. package/clis/powerchina/search.js +0 -251
  592. package/clis/powerchina/search.test.js +0 -93
  593. package/clis/quark/auth.js +0 -47
  594. package/clis/quark/ls.js +0 -64
  595. package/clis/quark/mkdir.js +0 -37
  596. package/clis/quark/mv.js +0 -54
  597. package/clis/quark/rename.js +0 -27
  598. package/clis/quark/rm.js +0 -25
  599. package/clis/quark/save.js +0 -81
  600. package/clis/quark/share-tree.js +0 -46
  601. package/clis/quark/utils.js +0 -146
  602. package/clis/quark/utils.test.js +0 -58
  603. package/clis/qwen/ask.js +0 -104
  604. package/clis/qwen/ask.test.js +0 -36
  605. package/clis/qwen/auth.js +0 -56
  606. package/clis/qwen/detail.js +0 -62
  607. package/clis/qwen/history.js +0 -61
  608. package/clis/qwen/image.js +0 -179
  609. package/clis/qwen/new.js +0 -23
  610. package/clis/qwen/read.js +0 -41
  611. package/clis/qwen/send.js +0 -55
  612. package/clis/qwen/status.js +0 -37
  613. package/clis/qwen/utils.js +0 -461
  614. package/clis/qwen/utils.test.js +0 -128
  615. package/clis/rednote/auth.js +0 -52
  616. package/clis/rednote/comments.js +0 -85
  617. package/clis/rednote/download.js +0 -59
  618. package/clis/rednote/feed.js +0 -27
  619. package/clis/rednote/navigation.test.js +0 -26
  620. package/clis/rednote/note.js +0 -68
  621. package/clis/rednote/notifications.js +0 -139
  622. package/clis/rednote/rednote.test.js +0 -240
  623. package/clis/rednote/search.js +0 -107
  624. package/clis/rednote/user.js +0 -55
  625. package/clis/sinablog/article.js +0 -15
  626. package/clis/sinablog/hot.js +0 -15
  627. package/clis/sinablog/search.js +0 -52
  628. package/clis/sinablog/user.js +0 -16
  629. package/clis/sinablog/utils.js +0 -186
  630. package/clis/sinafinance/news.js +0 -62
  631. package/clis/sinafinance/rolling-news.js +0 -41
  632. package/clis/sinafinance/stock-rank.js +0 -66
  633. package/clis/sinafinance/stock.js +0 -121
  634. package/clis/sinafinance/stock.test.js +0 -59
  635. package/clis/smzdm/search.js +0 -149
  636. package/clis/smzdm/search.test.js +0 -114
  637. package/clis/taobao/add-cart.js +0 -150
  638. package/clis/taobao/auth.js +0 -58
  639. package/clis/taobao/cart.js +0 -96
  640. package/clis/taobao/commands.test.js +0 -41
  641. package/clis/taobao/detail.js +0 -71
  642. package/clis/taobao/reviews.js +0 -77
  643. package/clis/taobao/search.js +0 -97
  644. package/clis/tdx/hot-rank.js +0 -48
  645. package/clis/tdx/hot-rank.test.js +0 -59
  646. package/clis/ths/hot-rank.js +0 -50
  647. package/clis/ths/hot-rank.test.js +0 -64
  648. package/clis/tieba/commands.test.js +0 -79
  649. package/clis/tieba/hot.js +0 -48
  650. package/clis/tieba/posts.js +0 -86
  651. package/clis/tieba/read.js +0 -141
  652. package/clis/tieba/search.js +0 -109
  653. package/clis/tieba/utils.js +0 -240
  654. package/clis/tieba/utils.test.js +0 -290
  655. package/clis/toutiao/articles.js +0 -55
  656. package/clis/toutiao/auth.js +0 -70
  657. package/clis/toutiao/hot.js +0 -63
  658. package/clis/toutiao/toutiao.test.js +0 -378
  659. package/clis/toutiao/utils.js +0 -161
  660. package/clis/trae-cn/activity.js +0 -22
  661. package/clis/trae-cn/approve.js +0 -52
  662. package/clis/trae-cn/ask.js +0 -99
  663. package/clis/trae-cn/dump.js +0 -5
  664. package/clis/trae-cn/export.js +0 -40
  665. package/clis/trae-cn/model.js +0 -22
  666. package/clis/trae-cn/new.js +0 -63
  667. package/clis/trae-cn/read.js +0 -23
  668. package/clis/trae-cn/screenshot.js +0 -5
  669. package/clis/trae-cn/select-model.js +0 -25
  670. package/clis/trae-cn/send.js +0 -23
  671. package/clis/trae-cn/setup.js +0 -75
  672. package/clis/trae-cn/status.js +0 -27
  673. package/clis/trae-cn/targets.js +0 -96
  674. package/clis/trae-cn/trae-cn.test.js +0 -412
  675. package/clis/trae-cn/utils.js +0 -750
  676. package/clis/trae-cn/watch.js +0 -119
  677. package/clis/uisdc/news.js +0 -105
  678. package/clis/uisdc/news.test.js +0 -66
  679. package/clis/v2ex/auth.js +0 -44
  680. package/clis/v2ex/daily.js +0 -99
  681. package/clis/v2ex/hot.js +0 -26
  682. package/clis/v2ex/latest.js +0 -26
  683. package/clis/v2ex/me.js +0 -100
  684. package/clis/v2ex/member.js +0 -28
  685. package/clis/v2ex/node.js +0 -39
  686. package/clis/v2ex/nodes.js +0 -26
  687. package/clis/v2ex/notifications.js +0 -72
  688. package/clis/v2ex/replies.js +0 -27
  689. package/clis/v2ex/topic.js +0 -31
  690. package/clis/v2ex/user.js +0 -34
  691. package/clis/wanfang/search.js +0 -66
  692. package/clis/wanfang/search.test.js +0 -23
  693. package/clis/wechat-channels/auth.js +0 -62
  694. package/clis/wechat-channels/publish.js +0 -732
  695. package/clis/wechat-channels/publish.test.js +0 -144
  696. package/clis/weibo/auth.js +0 -53
  697. package/clis/weibo/comments.js +0 -53
  698. package/clis/weibo/delete.js +0 -172
  699. package/clis/weibo/delete.test.js +0 -94
  700. package/clis/weibo/envelope.test.js +0 -85
  701. package/clis/weibo/favorites.js +0 -170
  702. package/clis/weibo/favorites.test.js +0 -114
  703. package/clis/weibo/feed.js +0 -69
  704. package/clis/weibo/hot.js +0 -39
  705. package/clis/weibo/me.js +0 -75
  706. package/clis/weibo/post.js +0 -75
  707. package/clis/weibo/publish.js +0 -306
  708. package/clis/weibo/publish.test.js +0 -192
  709. package/clis/weibo/search.js +0 -80
  710. package/clis/weibo/user-posts.js +0 -234
  711. package/clis/weibo/user-posts.test.js +0 -92
  712. package/clis/weibo/user.js +0 -63
  713. package/clis/weibo/utils.js +0 -59
  714. package/clis/weibo/utils.test.js +0 -36
  715. package/clis/weixin/create-draft.js +0 -226
  716. package/clis/weixin/download.js +0 -371
  717. package/clis/weixin/download.test.js +0 -106
  718. package/clis/weixin/drafts.js +0 -66
  719. package/clis/weixin/drafts.test.js +0 -69
  720. package/clis/weixin/search.js +0 -157
  721. package/clis/weixin/search.test.js +0 -227
  722. package/clis/weread/ai-outline.js +0 -171
  723. package/clis/weread/ai-outline.test.js +0 -83
  724. package/clis/weread/auth.js +0 -59
  725. package/clis/weread/book-search.js +0 -438
  726. package/clis/weread/book-search.test.js +0 -242
  727. package/clis/weread/book.js +0 -233
  728. package/clis/weread/commands.test.js +0 -398
  729. package/clis/weread/highlights.js +0 -24
  730. package/clis/weread/notebooks.js +0 -22
  731. package/clis/weread/notes.js +0 -30
  732. package/clis/weread/private-api-regression.test.js +0 -369
  733. package/clis/weread/ranking.js +0 -29
  734. package/clis/weread/search-regression.test.js +0 -494
  735. package/clis/weread/search.js +0 -186
  736. package/clis/weread/shelf.js +0 -66
  737. package/clis/weread/utils.js +0 -321
  738. package/clis/weread/utils.test.js +0 -128
  739. package/clis/weread-official/book.js +0 -135
  740. package/clis/weread-official/commands.test.js +0 -385
  741. package/clis/weread-official/discover.js +0 -107
  742. package/clis/weread-official/list-apis.js +0 -95
  743. package/clis/weread-official/notes.js +0 -171
  744. package/clis/weread-official/readdata.js +0 -158
  745. package/clis/weread-official/review.js +0 -93
  746. package/clis/weread-official/search.js +0 -106
  747. package/clis/weread-official/shelf.js +0 -97
  748. package/clis/weread-official/utils.js +0 -293
  749. package/clis/weread-official/utils.test.js +0 -242
  750. package/clis/xianyu/auth.js +0 -68
  751. package/clis/xianyu/chat.js +0 -74
  752. package/clis/xianyu/chat.test.js +0 -84
  753. package/clis/xianyu/im.js +0 -322
  754. package/clis/xianyu/im.test.js +0 -253
  755. package/clis/xianyu/inbox.js +0 -96
  756. package/clis/xianyu/item.js +0 -153
  757. package/clis/xianyu/item.test.js +0 -56
  758. package/clis/xianyu/messages.js +0 -91
  759. package/clis/xianyu/publish.js +0 -485
  760. package/clis/xianyu/publish.test.js +0 -220
  761. package/clis/xianyu/reply.js +0 -82
  762. package/clis/xianyu/search.js +0 -262
  763. package/clis/xianyu/search.test.js +0 -104
  764. package/clis/xianyu/utils.js +0 -8
  765. package/clis/xiaoe/auth.js +0 -55
  766. package/clis/xiaoe/catalog.js +0 -227
  767. package/clis/xiaoe/content.js +0 -175
  768. package/clis/xiaoe/courses.js +0 -127
  769. package/clis/xiaoe/detail.js +0 -36
  770. package/clis/xiaoe/play-url.js +0 -121
  771. package/clis/xiaoe/xiaoe.test.js +0 -486
  772. package/clis/xiaohongshu/ask.js +0 -426
  773. package/clis/xiaohongshu/ask.test.js +0 -271
  774. package/clis/xiaohongshu/auth.js +0 -53
  775. package/clis/xiaohongshu/collection-helpers.js +0 -283
  776. package/clis/xiaohongshu/collection-helpers.test.js +0 -125
  777. package/clis/xiaohongshu/comments.js +0 -228
  778. package/clis/xiaohongshu/comments.test.js +0 -320
  779. package/clis/xiaohongshu/creator-note-detail.js +0 -482
  780. package/clis/xiaohongshu/creator-note-detail.test.js +0 -451
  781. package/clis/xiaohongshu/creator-notes-summary.js +0 -98
  782. package/clis/xiaohongshu/creator-notes-summary.test.js +0 -94
  783. package/clis/xiaohongshu/creator-notes.js +0 -479
  784. package/clis/xiaohongshu/creator-notes.test.js +0 -281
  785. package/clis/xiaohongshu/creator-profile.js +0 -55
  786. package/clis/xiaohongshu/creator-stats.js +0 -76
  787. package/clis/xiaohongshu/creator-stats.test.js +0 -24
  788. package/clis/xiaohongshu/delete-note.js +0 -260
  789. package/clis/xiaohongshu/delete-note.test.js +0 -172
  790. package/clis/xiaohongshu/download.js +0 -249
  791. package/clis/xiaohongshu/download.test.js +0 -339
  792. package/clis/xiaohongshu/draft-clear.js +0 -91
  793. package/clis/xiaohongshu/draft-delete.js +0 -103
  794. package/clis/xiaohongshu/draft-open.js +0 -43
  795. package/clis/xiaohongshu/draft-utils.js +0 -142
  796. package/clis/xiaohongshu/drafts.js +0 -28
  797. package/clis/xiaohongshu/drafts.test.js +0 -172
  798. package/clis/xiaohongshu/feed.js +0 -163
  799. package/clis/xiaohongshu/feed.test.js +0 -126
  800. package/clis/xiaohongshu/follow.js +0 -226
  801. package/clis/xiaohongshu/follow.test.js +0 -211
  802. package/clis/xiaohongshu/liked.js +0 -29
  803. package/clis/xiaohongshu/liked.test.js +0 -82
  804. package/clis/xiaohongshu/navigation.test.js +0 -38
  805. package/clis/xiaohongshu/note-helpers.js +0 -69
  806. package/clis/xiaohongshu/note.js +0 -104
  807. package/clis/xiaohongshu/note.test.js +0 -249
  808. package/clis/xiaohongshu/notifications.js +0 -46
  809. package/clis/xiaohongshu/publish.js +0 -1423
  810. package/clis/xiaohongshu/publish.test.js +0 -1141
  811. package/clis/xiaohongshu/saved.js +0 -29
  812. package/clis/xiaohongshu/saved.test.js +0 -143
  813. package/clis/xiaohongshu/search.js +0 -330
  814. package/clis/xiaohongshu/search.test.js +0 -325
  815. package/clis/xiaohongshu/unfollow.js +0 -285
  816. package/clis/xiaohongshu/user-helpers.js +0 -78
  817. package/clis/xiaohongshu/user-helpers.test.js +0 -160
  818. package/clis/xiaohongshu/user.js +0 -140
  819. package/clis/xiaohongshu/user.test.js +0 -141
  820. package/clis/xiaoyuzhou/auth.js +0 -303
  821. package/clis/xiaoyuzhou/auth.test.js +0 -124
  822. package/clis/xiaoyuzhou/download.js +0 -54
  823. package/clis/xiaoyuzhou/download.test.js +0 -135
  824. package/clis/xiaoyuzhou/episode.js +0 -34
  825. package/clis/xiaoyuzhou/podcast-episodes.js +0 -41
  826. package/clis/xiaoyuzhou/podcast-episodes.test.js +0 -78
  827. package/clis/xiaoyuzhou/podcast.js +0 -33
  828. package/clis/xiaoyuzhou/transcript.js +0 -77
  829. package/clis/xiaoyuzhou/transcript.test.js +0 -195
  830. package/clis/xiaoyuzhou/utils.js +0 -15
  831. package/clis/xiaoyuzhou/utils.test.js +0 -39
  832. package/clis/xueqiu/auth.js +0 -63
  833. package/clis/xueqiu/comments.js +0 -355
  834. package/clis/xueqiu/comments.test.js +0 -696
  835. package/clis/xueqiu/danjuan-utils.js +0 -126
  836. package/clis/xueqiu/danjuan-utils.test.js +0 -41
  837. package/clis/xueqiu/earnings-date.js +0 -45
  838. package/clis/xueqiu/feed.js +0 -39
  839. package/clis/xueqiu/fund-holdings.js +0 -29
  840. package/clis/xueqiu/fund-snapshot.js +0 -26
  841. package/clis/xueqiu/groups.js +0 -23
  842. package/clis/xueqiu/hot-stock.js +0 -32
  843. package/clis/xueqiu/hot.js +0 -37
  844. package/clis/xueqiu/kline.js +0 -44
  845. package/clis/xueqiu/search.js +0 -37
  846. package/clis/xueqiu/stock.js +0 -65
  847. package/clis/xueqiu/utils.js +0 -48
  848. package/clis/xueqiu/utils.test.js +0 -26
  849. package/clis/xueqiu/watchlist.js +0 -37
  850. package/clis/youdao/note.js +0 -258
  851. package/clis/youdao/note.test.js +0 -99
  852. package/clis/yuanbao/ask.js +0 -362
  853. package/clis/yuanbao/ask.test.js +0 -124
  854. package/clis/yuanbao/auth.js +0 -59
  855. package/clis/yuanbao/detail.js +0 -65
  856. package/clis/yuanbao/history.js +0 -51
  857. package/clis/yuanbao/new.js +0 -72
  858. package/clis/yuanbao/new.test.js +0 -30
  859. package/clis/yuanbao/read.js +0 -38
  860. package/clis/yuanbao/send.js +0 -57
  861. package/clis/yuanbao/shared.js +0 -341
  862. package/clis/yuanbao/shared.test.js +0 -80
  863. package/clis/yuanbao/status.js +0 -44
  864. package/clis/zhihu/answer-comments.js +0 -280
  865. package/clis/zhihu/answer-comments.test.js +0 -287
  866. package/clis/zhihu/answer-detail.js +0 -216
  867. package/clis/zhihu/answer-detail.test.js +0 -338
  868. package/clis/zhihu/answer.js +0 -54
  869. package/clis/zhihu/answer.test.js +0 -54
  870. package/clis/zhihu/auth.js +0 -59
  871. package/clis/zhihu/collection.js +0 -199
  872. package/clis/zhihu/collection.test.js +0 -337
  873. package/clis/zhihu/collections.js +0 -128
  874. package/clis/zhihu/collections.test.js +0 -182
  875. package/clis/zhihu/comment.js +0 -55
  876. package/clis/zhihu/comment.test.js +0 -50
  877. package/clis/zhihu/download.js +0 -80
  878. package/clis/zhihu/download.test.js +0 -12
  879. package/clis/zhihu/favorite.js +0 -87
  880. package/clis/zhihu/favorite.test.js +0 -59
  881. package/clis/zhihu/follow.js +0 -50
  882. package/clis/zhihu/follow.test.js +0 -42
  883. package/clis/zhihu/followers.js +0 -40
  884. package/clis/zhihu/followers.test.js +0 -42
  885. package/clis/zhihu/following.js +0 -40
  886. package/clis/zhihu/following.test.js +0 -44
  887. package/clis/zhihu/hot.js +0 -44
  888. package/clis/zhihu/like.js +0 -47
  889. package/clis/zhihu/like.test.js +0 -41
  890. package/clis/zhihu/paginate.js +0 -128
  891. package/clis/zhihu/pins.js +0 -41
  892. package/clis/zhihu/pins.test.js +0 -44
  893. package/clis/zhihu/question.js +0 -113
  894. package/clis/zhihu/question.test.js +0 -251
  895. package/clis/zhihu/recommend.js +0 -103
  896. package/clis/zhihu/recommend.test.js +0 -143
  897. package/clis/zhihu/search.js +0 -206
  898. package/clis/zhihu/search.test.js +0 -198
  899. package/clis/zhihu/target.js +0 -91
  900. package/clis/zhihu/target.test.js +0 -77
  901. package/clis/zhihu/text.js +0 -29
  902. package/clis/zhihu/text.test.js +0 -24
  903. package/clis/zhihu/user-answers.js +0 -41
  904. package/clis/zhihu/user-answers.test.js +0 -69
  905. package/clis/zhihu/user-arg.js +0 -34
  906. package/clis/zhihu/user-articles.js +0 -40
  907. package/clis/zhihu/user-articles.test.js +0 -44
  908. package/clis/zhihu/user.js +0 -59
  909. package/clis/zhihu/user.test.js +0 -73
  910. package/clis/zhihu/write-shared.js +0 -228
  911. package/clis/zhihu/write-shared.test.js +0 -176
  912. package/clis/zsxq/auth.js +0 -68
  913. package/clis/zsxq/dynamics.js +0 -48
  914. package/clis/zsxq/groups.js +0 -33
  915. package/clis/zsxq/search.js +0 -44
  916. package/clis/zsxq/search.test.js +0 -24
  917. package/clis/zsxq/topic.js +0 -50
  918. package/clis/zsxq/topic.test.js +0 -30
  919. package/clis/zsxq/topics.js +0 -26
  920. package/clis/zsxq/topics.test.js +0 -24
  921. package/clis/zsxq/utils.js +0 -233
  922. package/clis/zsxq/utils.test.js +0 -31
  923. package/dist/src/weixin-download.test.js +0 -45
  924. package/skills/webcmd-adapter-author/references/site-memory/bilibili.md +0 -70
  925. package/skills/webcmd-adapter-author/references/site-memory/eastmoney.md +0 -70
  926. package/skills/webcmd-adapter-author/references/site-memory/tonghuashun.md +0 -51
  927. package/skills/webcmd-adapter-author/references/site-memory/xueqiu.md +0 -58
  928. /package/{clis/douyin/_shared/types.js → dist/src/generate-release-notes-cli.test.d.ts} +0 -0
  929. /package/dist/src/{weixin-download.test.d.ts → release-notes.test.d.ts} +0 -0
@@ -1,471 +1,278 @@
1
1
  # Adapter Template
2
2
 
3
- 一份 adapter 就是一次 `cli({...})` 调用。文件结构固定,三段:declaration、args、func。
3
+ Use this after recon, endpoint verification, field decoding, output design, and strategy-note writing are complete.
4
4
 
5
- `clis/eastmoney/convertible.js` 当活例子,对照拆解。
5
+ ## Create The File
6
6
 
7
- ---
7
+ For private iteration:
8
8
 
9
- ## 活例子:convertible.js
9
+ ```bash
10
+ webcmd browser init <site>/<name> --strategy <strategy>
11
+ ```
12
+
13
+ Write the working file at:
14
+
15
+ ```text
16
+ ~/.webcmd/clis/<site>/<name>.js
17
+ ```
18
+
19
+ Copy it to the repo only when preparing a PR:
20
+
21
+ ```text
22
+ clis/<site>/<name>.js
23
+ ```
10
24
 
11
- > **注意(2026-05 起)**:下面这份 `convertible.js` 的 limit clamp 和 `CliError('HTTP_ERROR' / 'NO_DATA')` 是 grandfathered 写法(在 [`scripts/typed-error-lint-baseline.json`](../../../scripts/typed-error-lint-baseline.json) 里)。结构布局(cli 声明 / args / columns / map)仍然是好范本,但 **error 处理 + limit 校验请按下文 §3 + [`typed-errors.md`](./typed-errors.md) 写**。新写 adapter 抄这个文件别连 `Math.max(1, Math.min(...))` 和 `CliError(...)` 一起抄过去。
25
+ ## Minimal Registry Shape
12
26
 
13
- ```javascript
14
- // eastmoney convertible — on-market convertible bond listing.
27
+ Adapters register commands with `cli` and `Strategy` from `@agentrhq/webcmd/registry`.
28
+
29
+ ```js
15
30
  import { cli, Strategy } from '@agentrhq/webcmd/registry';
16
- import { CliError } from '@agentrhq/webcmd/errors';
17
-
18
- const SORTS = {
19
- change: { fid: 'f3', order: 'desc' },
20
- drop: { fid: 'f3', order: 'asc' },
21
- turnover: { fid: 'f6', order: 'desc' },
22
- price: { fid: 'f2', order: 'desc' },
23
- premium: { fid: 'f237', order: 'desc' },
24
- value: { fid: 'f236', order: 'desc' },
25
- ytm: { fid: 'f239', order: 'desc' },
26
- };
27
31
 
28
32
  cli({
29
- site: 'eastmoney',
30
- name: 'convertible',
31
- description: '可转债行情列表(默认按成交额排序)',
32
- domain: 'push2.eastmoney.com',
33
+ site: 'hackernews',
34
+ name: 'top',
35
+ access: 'read',
36
+ description: 'Hacker News top stories',
37
+ domain: 'news.ycombinator.com',
33
38
  strategy: Strategy.PUBLIC,
34
39
  browser: false,
35
40
  args: [
36
- { name: 'sort', type: 'string', default: 'turnover', help: '排序:turnover / change / drop / price / premium' },
37
- { name: 'limit', type: 'int', default: 20, help: '返回数量 (max 100)' },
41
+ { name: 'limit', type: 'int', default: 20, help: 'Number of rows' },
42
+ ],
43
+ columns: ['rank', 'title', 'url', 'score', 'author', 'commentCount'],
44
+ pipeline: [
45
+ { navigate: 'https://news.ycombinator.com/' },
46
+ {
47
+ evaluate: `(async () => {
48
+ const rows = [...document.querySelectorAll('.athing')].slice(0, \${{ args.limit }});
49
+ return rows.map((row, index) => {
50
+ const subtext = row.nextElementSibling;
51
+ const titleLink = row.querySelector('.titleline a');
52
+ return {
53
+ rank: index + 1,
54
+ title: titleLink?.textContent?.trim() || '',
55
+ url: titleLink?.href || '',
56
+ score: Number((subtext?.querySelector('.score')?.textContent || '').match(/\\d+/)?.[0] || 0),
57
+ author: subtext?.querySelector('.hnuser')?.textContent?.trim() || '',
58
+ commentCount: Number((subtext?.textContent || '').match(/(\\d+)\\s+comments?/)?.[1] || 0),
59
+ };
60
+ });
61
+ })()`,
62
+ },
63
+ {
64
+ map: {
65
+ rank: '${{ item.rank }}',
66
+ title: '${{ item.title }}',
67
+ url: '${{ item.url }}',
68
+ score: '${{ item.score }}',
69
+ author: '${{ item.author }}',
70
+ commentCount: '${{ item.commentCount }}',
71
+ },
72
+ },
73
+ { limit: '${{ args.limit }}' },
38
74
  ],
39
- columns: ['rank', 'bondCode', 'bondName', 'bondPrice', 'bondChangePct',
40
- 'stockCode', 'stockName', 'stockPrice', 'stockChangePct',
41
- 'convPrice', 'convValue', 'convPremiumPct', 'remainingYears', 'ytm', 'listDate'],
42
- func: async (args) => {
43
- const sortKey = String(args.sort ?? 'turnover').toLowerCase();
44
- const sort = SORTS[sortKey];
45
- if (!sort) throw new CliError('INVALID_ARGUMENT', `Unknown sort "${sortKey}". Valid: ${Object.keys(SORTS).join(', ')}`);
46
- const limit = Math.max(1, Math.min(Number(args.limit) || 20, 100));
47
-
48
- const url = new URL('https://push2.eastmoney.com/api/qt/clist/get');
49
- url.searchParams.set('pn', '1');
50
- url.searchParams.set('pz', String(limit));
51
- url.searchParams.set('po', sort.order === 'desc' ? '1' : '0');
52
- url.searchParams.set('np', '1');
53
- url.searchParams.set('fltt', '2');
54
- url.searchParams.set('invt', '2');
55
- url.searchParams.set('fid', sort.fid);
56
- url.searchParams.set('fs', 'b:MK0354');
57
- url.searchParams.set('fields', 'f12,f14,f2,f3,f6,f229,f230,f232,f234,f235,f236,f237,f238,f239,f243');
58
- url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');
59
-
60
- const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
61
- if (!resp.ok) throw new CliError('HTTP_ERROR', `convertible failed: HTTP ${resp.status}`);
62
- const data = await resp.json();
63
- const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
64
- if (diff.length === 0) throw new CliError('NO_DATA', 'eastmoney returned no convertible data');
65
-
66
- return diff.slice(0, limit).map((it, i) => ({
67
- rank: i + 1,
68
- bondCode: it.f12,
69
- bondName: it.f14,
70
- bondPrice: it.f2,
71
- bondChangePct: it.f3,
72
- stockCode: it.f232,
73
- stockName: it.f234,
74
- stockPrice: it.f229,
75
- stockChangePct: it.f230,
76
- convPrice: it.f235,
77
- convValue: it.f236,
78
- convPremiumPct: it.f237,
79
- remainingYears: it.f238,
80
- ytm: it.f239,
81
- listDate: String(it.f243 ?? ''),
82
- }));
83
- },
84
75
  });
85
76
  ```
86
77
 
87
- ---
88
-
89
- ## 三段解剖
78
+ Treat this as shape guidance, not a universal solution. Prefer the closest existing adapter for the same site or source type.
90
79
 
91
- ### 1. Declaration — 标头
92
-
93
- ```javascript
94
- cli({
95
- site: 'eastmoney', // 第一级命名空间,目录名一致
96
- name: 'convertible', // 第二级,CLI 上的子命令
97
- description: '...', // 一句话,出现在 `webcmd list` 和 `webcmd <site> -h`
98
- domain: 'push2.eastmoney.com', // 主要请求域名(诊断面板用)
99
- strategy: Strategy.PUBLIC, // PUBLIC / COOKIE / INTERCEPT / UI
100
- browser: false, // PUBLIC 几乎总是 false;COOKIE/INTERCEPT/UI 一律 true
101
- ...
102
- });
103
- ```
80
+ ## Imports
104
81
 
105
- ### 2. Args & Columns
82
+ Allowed imports:
106
83
 
107
- ```javascript
108
- args: [
109
- { name: 'sort', type: 'string', default: 'turnover', help: '...' },
110
- { name: 'limit', type: 'int', default: 20, help: '...' },
111
- ],
112
- columns: ['rank', 'bondCode', 'bondName', /* ... */ ],
84
+ ```js
85
+ import { cli, Strategy } from '@agentrhq/webcmd/registry';
86
+ import {
87
+ ArgumentError,
88
+ AuthRequiredError,
89
+ CommandExecutionError,
90
+ EmptyResultError,
91
+ TimeoutError,
92
+ } from '@agentrhq/webcmd/errors';
113
93
  ```
114
94
 
115
- **规则**:
95
+ Rules:
116
96
 
117
- - `type`: `string` / `int` / `float` / `bool`
118
- - `default` 必填(缺失的命令会拒绝启动)
119
- - `columns` 数组必须跟 `func` 返回的 object keys 完全对上,顺序也一致(决定表格列顺序)
120
- - 列名 camelCase,跟 `cli({...})` 其他 adapter 保持统一
121
- - **中间解析对象 key 不能跟 columns 任一项重叠** —— 否则 `silent-column-drop` audit 会把它当 row 候选误判。`{pid, html, start}` 这类中间结构改成 `{postId, body, offset}`,最后在 push row 时再 destructure aliasing 回 column 命名。背景:PR #1329 R1 codex-mini0 catch 的([before](https://github.com/agentrhq/webcmd/blob/384bcd6fdd93f3075bd2c835e82689c42bfe4b2f/clis/1point3acres/thread.js#L50-L63) → [after](../../../clis/1point3acres/thread.js#L50-L65))
97
+ - Do not add third-party dependencies.
98
+ - Do not import private repo internals unless an established neighboring adapter already does so.
99
+ - Keep helpers local unless there is real duplication in the same site directory.
122
100
 
123
- ### 3. func — 主体
101
+ ## Required Fields
124
102
 
125
- ```javascript
126
- import { ArgumentError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
103
+ | Field | Rule |
104
+ | --- | --- |
105
+ | `site` | Directory/site id. Keep lowercase and stable. |
106
+ | `name` | Command id. Keep lowercase and stable. |
107
+ | `access` | Usually `read`; use write-like access only for commands that mutate state. |
108
+ | `description` | One clear sentence. |
109
+ | `domain` | Primary domain for auth and help output. |
110
+ | `strategy` | Use a registry enum such as `Strategy.PUBLIC` or `Strategy.COOKIE`; align it with the strategy note. |
111
+ | `browser` | `false` for plain Node-side adapters; `true` when the adapter needs the page, cookie jar, or browser runtime. |
112
+ | `args` | Include type, default, and help for every external parameter. |
113
+ | `columns` | Must exactly match row keys, including order. |
114
+ | `pipeline` or `func` | Use the style already established by nearby adapters. |
127
115
 
128
- func: async (args) => {
129
- // 1. 解析参数 — 越界一律抛,不要 silent clamp
130
- const n = Number(args.limit ?? 20);
131
- if (!Number.isInteger(n) || n <= 0) throw new ArgumentError('limit must be a positive integer');
132
- if (n > 100) throw new ArgumentError('limit must be <= 100');
133
- const limit = n;
134
-
135
- // 2. 构造 URL / 请求
136
- const url = new URL(...);
137
- url.searchParams.set(...);
138
-
139
- // 3. 发请求 — fetch 抛 / HTTP 非 2xx 都归 CommandExecutionError
140
- let resp;
141
- try {
142
- resp = await fetch(url, { headers: { /* ... */ } });
143
- } catch (error) {
144
- throw new CommandExecutionError(`request failed: ${error?.message || error}`);
145
- }
146
- if (!resp.ok) throw new CommandExecutionError(`request failed: HTTP ${resp.status}`);
147
-
148
- // 4. 解析 + 业务校验 — 业务空 → EmptyResultError,不要 sentinel row 也不要 return []
149
- const data = await resp.json();
150
- const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
151
- if (diff.length === 0) throw new EmptyResultError('site command', 'API returned no rows');
152
-
153
- // 5. map 到 columns 同名 keys
154
- return diff.slice(0, limit).map((it, i) => ({
155
- rank: i + 1,
156
- bondCode: it.f12,
157
- // ...
158
- }));
159
- },
160
- ```
116
+ ## Strategy Enum Examples
161
117
 
162
- **站点级 helper**:≥ 2 个同站 adapter 都做相同 limit / page 校验时,把校验抽成 `clis/<site>/utils.js` `normalizeLimit(value, default, max, label)` / `normalizePositiveInteger(value, default, label, { min })`,避免每个 adapter 都 inline 一遍。模板见 [`typed-errors.md` §2](./typed-errors.md) 和 [`clis/1point3acres/utils.js`](../../../clis/1point3acres/utils.js)。1 个 adapter 用就直接 inline,不要为 1 处单点抽 helper。
118
+ The strategy note uses discovery names such as `PUBLIC_API` and `COOKIE_API`. The adapter declaration records the runtime choice with `Strategy` enum values.
163
119
 
164
- **参数形态**(**踩过最多次的坑**:搞反签名后 `args` 实际是 `debug` flag,所有 `args.foo` 静默 undefined fallback default。#1329 upstream 之前 8 non-browser adapter 写错过签名,全部 silently fallback 到默认参数):
120
+ Use `Strategy.PUBLIC` when an anonymous, stable endpoint can be fetched directly from Node:
165
121
 
166
- - `browser: false`:`func: async (args, debug?) => { ... }` —— **单参 args**,不会收到 `page`
167
- - `browser: true`:`func: async (page, args, debug?) => { ... }` —— **双参 (page, args)**,第一参是浏览器上下文
168
- - `args`:所有 `args[]` 声明的参数解析后的 object
122
+ ```js
123
+ import { cli, Strategy } from '@agentrhq/webcmd/registry';
124
+ import { ArgumentError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
169
125
 
170
- **错误处理**:用 typed error 5-classification(参见 [`typed-errors.md`](./typed-errors.md)),**不要** `CliError('XXX', ...)` 直传,**不要** `return []` 了事,**不要** `return [{sentinel}]` 装一行业务数据冒充 empty。autofix skill 靠 typed error 的 exit code(66 = empty / 77 = auth / 75 = timeout / 2 = argument / 1 = exec)决定要不要重试。
126
+ cli({
127
+ site: 'example',
128
+ name: 'public-list',
129
+ access: 'read',
130
+ description: 'Example public listing',
131
+ domain: 'api.example.com',
132
+ strategy: Strategy.PUBLIC,
133
+ browser: false,
134
+ args: [{ name: 'limit', type: 'int', default: 20, help: 'Number of rows' }],
135
+ columns: ['index', 'title', 'url'],
136
+ func: async (args) => {
137
+ const limit = Number(args.limit ?? 20);
138
+ if (!Number.isInteger(limit) || limit <= 0) {
139
+ throw new ArgumentError('limit must be a positive integer');
140
+ }
171
141
 
172
- ---
142
+ const resp = await fetch(`https://api.example.com/items?limit=${limit}`, {
143
+ headers: { 'User-Agent': 'Mozilla/5.0' },
144
+ });
145
+ if (!resp.ok) throw new CommandExecutionError(`example request failed: HTTP ${resp.status}`);
173
146
 
174
- ## COOKIE adapter 骨架(需要登录态)
147
+ const data = await resp.json();
148
+ const items = Array.isArray(data?.items) ? data.items : [];
149
+ if (!items.length) throw new EmptyResultError('example public-list', 'API returned no rows');
175
150
 
176
- PUBLIC 模式不够(接口 401 / 302 到 login / 响应是"请登录"页)就走这里。要点三条:
151
+ return items.map((item, index) => ({
152
+ index: index + 1,
153
+ title: item.title,
154
+ url: item.url,
155
+ }));
156
+ },
157
+ });
158
+ ```
177
159
 
178
- 1. cookie `page.getCookies(...)`,**不要读 `document.cookie`**。
179
- 2. 拿 HTML 走 Node 端 `fetch` + 手动解码,**不要塞进 `page.evaluate` 里**。
180
- 3. Declaration 加 `browser: true`;不需要真的打开目标页时 `navigateBefore: false`。
160
+ Use `Strategy.COOKIE` when the endpoint or HTML page needs the user's existing browser session. Read cookies with `page.getCookies()` and pass them to Node-side `fetch`; do not rely on `document.cookie` for HttpOnly auth cookies.
181
161
 
182
- ```javascript
162
+ ```js
183
163
  import { cli, Strategy } from '@agentrhq/webcmd/registry';
184
164
  import { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@agentrhq/webcmd/errors';
185
165
 
186
166
  const BASE = 'https://www.example.com';
187
167
  const HOST = 'www.example.com';
188
- const ROOT = '.example.com'; // 根域(auth 常在这里)
189
-
190
- async function readCookie(page) {
191
- const seen = new Map();
192
- for (const opts of [{ domain: HOST }, { domain: ROOT }]) {
193
- try {
194
- const cookies = await page.getCookies(opts);
195
- for (const c of cookies || []) {
196
- if (!seen.has(c.name)) seen.set(c.name, c.value);
197
- }
198
- } catch { /* try next domain */ }
168
+ const ROOT = '.example.com';
169
+
170
+ async function cookieHeader(page) {
171
+ const seen = new Map();
172
+ for (const opts of [{ domain: HOST }, { domain: ROOT }]) {
173
+ for (const cookie of await page.getCookies(opts).catch(() => [])) {
174
+ if (!seen.has(cookie.name)) seen.set(cookie.name, cookie.value);
199
175
  }
200
- return [...seen].map(([k, v]) => `${k}=${v}`).join('; ');
176
+ }
177
+ return [...seen].map(([name, value]) => `${name}=${value}`).join('; ');
201
178
  }
202
179
 
203
- async function fetchHtml(url, { cookie, encoding = 'utf-8', headers = {} } = {}) {
204
- let resp;
205
- try {
206
- resp = await fetch(url, {
207
- headers: {
208
- 'User-Agent': 'Mozilla/5.0',
209
- 'Accept-Language': 'zh-CN,zh;q=0.9',
210
- Referer: `${BASE}/`,
211
- ...(cookie ? { Cookie: cookie } : {}),
212
- ...headers,
213
- },
214
- redirect: 'follow',
215
- });
216
- } catch (error) {
217
- throw new CommandExecutionError(`example request failed: ${error?.message || error}`);
218
- }
219
- if (!resp.ok) throw new CommandExecutionError(`example request failed: HTTP ${resp.status}`);
220
- const buf = await resp.arrayBuffer();
221
- return new TextDecoder(encoding).decode(buf);
180
+ function parseRowsFromHtml(html) {
181
+ return [...html.matchAll(/<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>/g)].map((match, index) => ({
182
+ index: index + 1,
183
+ title: match[2].trim(),
184
+ time: '',
185
+ }));
222
186
  }
223
187
 
224
188
  cli({
225
- site: 'example',
226
- name: 'me',
227
- access: 'read',
228
- description: '示例:需要登录的私有页面',
229
- domain: HOST,
230
- strategy: Strategy.COOKIE,
231
- browser: true,
232
- navigateBefore: false, // 本命令不需要先开目标页
233
- args: [{ name: 'limit', type: 'int', default: 20, help: '返回条数' }],
234
- columns: ['index', 'title', 'time'],
235
- func: async (page, args) => {
236
- const limit = Number(args.limit ?? 20);
237
- if (!Number.isInteger(limit) || limit <= 0) throw new ArgumentError('limit must be a positive integer');
238
-
239
- const cookie = await readCookie(page);
240
- const html = await fetchHtml(`${BASE}/inbox`, { cookie, encoding: 'gbk' });
241
-
242
- if (/请登录|需要登录|<title>Login/i.test(html)) {
243
- throw new AuthRequiredError(HOST);
244
- }
245
-
246
- // parse html → rows
247
- if (!rows.length) throw new EmptyResultError('example me', 'inbox is empty');
248
- return rows.slice(0, limit);
249
- },
250
- });
251
- ```
189
+ site: 'example',
190
+ name: 'private-list',
191
+ access: 'read',
192
+ description: 'Example private listing',
193
+ domain: HOST,
194
+ strategy: Strategy.COOKIE,
195
+ browser: true,
196
+ navigateBefore: false,
197
+ args: [{ name: 'limit', type: 'int', default: 20, help: 'Number of rows' }],
198
+ columns: ['index', 'title', 'time'],
199
+ func: async (page, args) => {
200
+ const limit = Number(args.limit ?? 20);
201
+ if (!Number.isInteger(limit) || limit <= 0) {
202
+ throw new ArgumentError('limit must be a positive integer');
203
+ }
252
204
 
253
- ### JSON API `page.fetchJson()`,不要手写 `page.evaluate(fetch(...))`
205
+ const cookie = await cookieHeader(page);
206
+ const resp = await fetch(`${BASE}/inbox`, {
207
+ headers: {
208
+ 'User-Agent': 'Mozilla/5.0',
209
+ Referer: `${BASE}/`,
210
+ ...(cookie ? { Cookie: cookie } : {}),
211
+ },
212
+ redirect: 'follow',
213
+ });
214
+ if (!resp.ok) throw new CommandExecutionError(`example request failed: HTTP ${resp.status}`);
254
215
 
255
- 如果接口必须在浏览器上下文里请求(依赖当前页面 cookie / CORS / origin),用内置 primitive:
216
+ const html = await resp.text();
217
+ if (/login required|sign in/i.test(html)) throw new AuthRequiredError(HOST);
256
218
 
257
- ```javascript
258
- const data = await page.fetchJson(`${BASE}/api/list`, {
259
- method: 'POST',
260
- headers: { 'X-Requested-With': 'XMLHttpRequest' },
261
- body: { page: 1, size: limit },
219
+ const rows = parseRowsFromHtml(html).slice(0, limit);
220
+ if (!rows.length) throw new EmptyResultError('example private-list', 'page returned no rows');
221
+ return rows;
222
+ },
262
223
  });
263
224
  ```
264
225
 
265
- 它固定 `credentials: 'include'`,带 timeout,HTTP 非 2xx / 非 JSON 会抛统一 runtime error。adapter 里不用再手写 `page.evaluate(fetch(...))`;如果你需要额外包一层业务语义,按 [`typed-errors.md`](./typed-errors.md) 映射到 `CommandExecutionError` / `AuthRequiredError` / `EmptyResultError`。
266
-
267
- ### 页面内 DOM 逻辑用 `page.evaluate(fn, ...args)`
268
-
269
- 新 adapter 优先写函数形式,外部变量通过参数传入:
270
-
271
- ```javascript
272
- const href = await page.evaluate((selector) => {
273
- const link = document.querySelector(selector);
274
- return link ? link.getAttribute('href') : null;
275
- }, 'a[data-testid="profile"]');
276
- ```
277
-
278
- `fn` 在浏览器页面上下文执行,不能读取 Node 侧闭包变量;参数必须能被 `JSON.stringify` 序列化。字符串形式 `page.evaluate('document.title')` 仍可用于简单表达式和既有代码,但不要再写依赖隐式 auto-IIFE 的模板字符串函数。
279
-
280
- ### HTML 不走 browser fetch
281
-
282
- 三个坑,踩一个就重写:
283
-
284
- - **HttpOnly cookie 看不见**:绝大多数登录站点把 auth cookie 标 `HttpOnly`,`document.cookie` 永远读不到它,只能通过 CDP 的 cookie jar 拿(`page.getCookies`)。塞到 `page.evaluate` 里就等于回到 `document.cookie` 那条路,必挂。
285
- - **`navigateBefore: false` 时当前 tab 不在目标站**:页面 origin 可能是 `about:blank` 或上一条命令留下的别处,从那儿发 fetch 到目标域就是 cross-origin,浏览器 CORS 一挡就是 "Failed to fetch"。
286
- - **非 UTF-8 编码解码麻烦**:GBK / Big5 / Shift-JIS 的站(Discuz / phpBB 老版 / 日站)在 `page.evaluate` 里用 `response.text()` 拿到的是乱码,`TextDecoder('gbk').decode(buf)` 的写法只在 Node 侧干净。
287
-
288
- **规则**:JSON 型浏览器接口用 `page.fetchJson()`;HTML 型 COOKIE adapter 一律 Node 侧 `fetch`,浏览器只当 cookie jar 用。
289
-
290
- ### Selector 稳定性 — 不要 select 用户可见文本
291
-
292
- issue #1474 触发:同一个发送按钮在英文 Chrome 是 `aria-label="Submit"`,在中文 Chrome(`chrome://settings/languages` 设中文)变 `aria-label="提交"`,CSS 选择器 `button[aria-label="Submit"]` 在中文环境下直接 0 匹配,silent empty result。
293
-
294
- 根因不是 i18n bug,是**选择器的 anchor 选错了**。把页面 DOM 属性按 "locale-stable vs locale-dependent" 分两类:
295
-
296
- | 类 | 例子 | locale 切换会变吗 | 用作 primary selector? |
297
- |----|------|----------------|---------------------|
298
- | **locale-stable 标识** | `data-testid`、`data-*`、稳定 `id` / `class` | 通常不变(开发者内部 ID) | ✅ 首选,但要先确认不是 hash / A-B test |
299
- | **semantic / scope anchor** | `role`、结构关系、邻近稳定容器 | 不按 locale 翻译,但常常不唯一 | ⚠️ 只作 scope/filter;不要单独用 `button[role="button"]` |
300
- | **locale-dependent 文本** | `aria-label`、`title`、`placeholder`、`alt`、`textContent` | 变(被 i18n 框架翻译) | ❌ 仅当 stable 选择器全都不存在时的兜底 |
301
-
302
- ChatGPT 的 web 端就是反例驱动的:有些 controls 暴露稳定 `data-testid`,有些 surfaces 只暴露 `aria-label` / `placeholder`。这种站必须先用 stable selector,再用多语言 fallback list:
303
-
304
- ```javascript
305
- // clis/chatgpt/utils.js(简化活例)
306
- const COMPOSER_SELECTORS = [
307
- '#prompt-textarea',
308
- '[data-testid="composer"] [contenteditable="true"]',
309
- '[aria-label="Chat with ChatGPT"]', // en
310
- '[aria-label="与 ChatGPT 聊天"]', // zh-CN
311
- '[placeholder="Ask anything"]',
312
- '[placeholder="有问题,尽管问"]', // zh-CN
313
- ];
314
- const SEND_BUTTON_SELECTORS = [
315
- 'button[data-testid="send-button"]:not([disabled])',
316
- 'button[aria-label="Send prompt"]:not([disabled])',
317
- 'button[aria-label="发送提示"]:not([disabled])',
318
- ];
319
- ```
320
-
321
- 写 fallback list 的纪律:
322
-
323
- 1. **stable selector 放最前**(`#prompt-textarea` / `[data-testid="send-button"]`),locale-dependent 的放后面当兜底
324
- 2. **`role` 只能当 semantic / scope filter**:`dialog [role="textbox"]` 可以;裸 `button` / `[role="button"]` 不够,因为同页可能有多个按钮
325
- 3. **每种 locale 至少列一条**(en + zh-CN 是底线;扩到 ja / ko / ar 看站点用户分布)
326
- 4. **commit 前 grep `aria-label=` / `placeholder=` / `title=` 看是不是漏了 fallback locale**——见 success-rate-pitfalls.md §11
327
- 5. **失败要 typed fail-fast**:找不到 control 应该 `CommandExecutionError` / send-failed,不要返回空 rows 或假成功
328
- 6. **不要给 framework 加 `--i18n "zh:提交,ja:送信"` 这种 flag** —— 等于把 fallback list 从 adapter 挪到 CLI,多一层 indirection 还要维护翻译字典。这是 over-engineering,已经在评审时被否
329
-
330
- 为什么不在 daemon 端固定 Chrome locale?因为 webcmd **不启动 Chrome**——daemon 是连用户已经在跑的 Chrome(CDP via extension),用户可能就是中文 UI / 中文资料检索需求。强制 en-US 会破坏用户的正当工作流。
331
-
332
- ### Cookie 域的双查
333
-
334
- ```javascript
335
- for (const opts of [{ domain: HOST }, { domain: ROOT }]) { ... }
336
- ```
337
-
338
- 不是所有站都这么玄学,但下面这几类踩坑最多:
339
-
340
- | 站点类型 | 坑 |
341
- |---------|----|
342
- | Discuz!X / phpBB / vBulletin 论坛 | Auth cookie 设在 `.<root>.com`,HttpOnly;业务页在 `www.<root>.com`。只查 `www.` 会漏 |
343
- | 多子域账户体系(`account.x.com` vs `api.x.com`) | 登录时写在 account 域,API 域读取时拿不到 |
344
- | 新版 Chrome SameSite=Lax 默认 | 某些 cookie 查 `url:` 才给返,查 `domain:` 不给 |
345
-
346
- 双查成本很低,不确定就两个都查,用 Map 去重第一次出现的 name。
347
-
348
- ### 空态抛 `EmptyResultError`,**不**塞 sentinel 行
349
-
350
- 历史上这里写的是"返回一行说明 row 比 `return []` 安全"。**这条已经反过来了**——见 PR #1329 R3 的 four anti-pattern fixes。现在的契约:
351
-
352
- ```javascript
353
- import { EmptyResultError } from '@agentrhq/webcmd/errors';
354
-
355
- // ❌ 老写法:sentinel 行污染 row 合同,让 listing→detail round-trip 拿到 tid='' 白跑
356
- if (/暂时没有提醒内容/.test(html)) {
357
- return [{ index: 0, from: '', summary: '暂时没有提醒内容', time: '', threadUrl: '' }];
358
- }
359
-
360
- // ✅ 新写法:empty 是合法状态,但不是 row。exit code 66 让 agent 直接 branch
361
- if (/暂时没有提醒内容/.test(html)) {
362
- throw new EmptyResultError('1point3acres notifications', '暂时没有提醒内容');
363
- }
364
- ```
365
-
366
- 更多反例和详细 routing 见 [`typed-errors.md` §3](./typed-errors.md)。
367
-
368
- ---
369
-
370
- ## 同类型 adapter 对照
371
-
372
- | 类型 | 代表 | 参考 |
373
- |------|------|-----|
374
- | clist 分页排行 | `convertible.js` / `rank.js` / `etf.js` / `sectors.js` | 都共享 `fs` + `fid` + `po` 结构 |
375
- | ulist 批量报价 | `quote.js` | `secids` 逗号拼接 |
376
- | K 线历史 | `kline.js` | `fields1 / fields2` 控列,CSV 解析 |
377
- | 报表(datacenter-web) | `longhu.js` / `holders.js` | `reportName` 驱动 |
378
- | 7x24 新闻 | `kuaixun.js` | `np-listapi` 栏目 id |
379
- | 公司公告 | `announcement.js` | `np-anotice-stock` |
380
- | 指数/北上 | `index-board.js` / `northbound.js` | push2 专用端点 |
381
-
382
- 新写一条时,选最像的那类,复制后改 `name` / URL / fields / column 映射三处。
383
-
384
- ---
226
+ ## Parameter Safety
385
227
 
386
- ## Verify fixture(每个 adapter 配一份 `~/.webcmd/sites/<site>/verify/<name>.json`)
228
+ - Validate user-facing numbers before use.
229
+ - Throw `ArgumentError` for invalid external parameters.
230
+ - Do not silently clamp with `Math.max` / `Math.min` unless the user explicitly requested clamping and the output says so.
231
+ - Do not let a failed selector or missing field become a valid empty result.
387
232
 
388
- verify fixture 是"adapter 产出长什么样"的结构锚点。没有它,`webcmd browser verify` 只能证"adapter 能跑完不抛",证不出数据没错位。**必写**。
233
+ ## Row Safety
389
234
 
390
- 详细 schema 见 `site-memory.md` 的 `verify/<cmd>.json` 节。这里只讲两个容易踩的地方:
235
+ Before mapping rows:
391
236
 
392
- ### args 形态:object vs array
237
+ - Confirm the response contains the expected shape.
238
+ - Throw `EmptyResultError` only when the site truly reports no results.
239
+ - Throw `CommandExecutionError` when the response shape is wrong, parsing fails, or an endpoint returns HTML instead of expected data.
240
+ - Use `AuthRequiredError` when login is required or session expired.
241
+ - Use `TimeoutError` when the page or endpoint did not settle in time.
393
242
 
394
- `args` 字段决定 verify 怎么调你的 adapter:
243
+ ## Column Alignment Checklist
395
244
 
396
- - **对象形态** `{ "limit": 3 }` → 展开成 `--limit 3`,标准 named-flag adapter 用这个
397
- - **数组形态** `["123", "--limit", "3"]` → 原样 append 到命令后,**positional 主语型** adapter 必须用这个
245
+ Before verify:
398
246
 
399
- repo 约定"主语优先 positional"——thread 详情型、url 解析型、关键词搜索型都用 positional:
400
-
401
- ```js
402
- // clis/1point3acres/thread.js 接收 <tid> 作为主语
403
- cli({
404
- site: '1point3acres',
405
- name: 'thread',
406
- args: [
407
- { name: 'tid', type: 'string', required: true, positional: true },
408
- { name: 'limit', type: 'int', default: 20 },
409
- ],
410
- // ...
411
- });
247
+ ```text
248
+ [ ] columns array and row keys match exactly
249
+ [ ] no intermediate object key overlaps a column accidentally
250
+ [ ] values use documented units
251
+ [ ] percentage scale is consistent
252
+ [ ] dates are ISO or clearly documented
253
+ [ ] URLs are absolute when users need to click them
254
+ [ ] one row was compared with the visible page
412
255
  ```
413
256
 
414
- 对应 fixture:
257
+ ## Verify
415
258
 
416
- ```json
417
- {
418
- "args": ["1234567", "--limit", "3"],
419
- "expect": { "rowCount": { "min": 1, "max": 3 }, "...": "..." }
420
- }
421
- ```
422
-
423
- **不要写成** `{ "tid": "1234567", "limit": 3 }`——这会被展开成 `--tid 1234567 --limit 3`,commander 把 `--tid` 当未知 flag 报错,或者 adapter 根本不认。
424
-
425
- ### 种子 → 手改
426
-
427
- named-flag adapter(`hot` / `latest` 类)可以直接让工具生成种子:
259
+ Run:
428
260
 
429
261
  ```bash
430
- # 1. verify 先跑一遍,--write-fixture 生成种子(默认追加 --limit 3)
431
- webcmd browser verify 1point3acres/hot --write-fixture
432
-
433
- # 2. 手改 ~/.webcmd/sites/1point3acres/verify/hot.json
434
- # - patterns: 加 URL / 日期 / ID 正则
435
- # - notEmpty: 加核心字段(title / author / url)
436
- # - rowCount: 收紧到业务合理区间
437
-
438
- # 3. 再跑 verify,fixture 吃得动就 OK
439
- webcmd browser verify 1point3acres/hot
262
+ webcmd browser verify <site>/<name> --trace retain-on-failure
440
263
  ```
441
264
 
442
- positional adapter 目前 `--write-fixture` 没法表达主语,**首份 fixture 要手写**:
265
+ After the first passing run, write a fixture:
443
266
 
444
267
  ```bash
445
- # 1. 先直跑 adapter 看输出长啥样
446
- webcmd 1point3acres thread 1173710 --limit 2 --format json | head
447
-
448
- # 2. 照着响应手写 ~/.webcmd/sites/1point3acres/verify/thread.json
449
- # (args 一定用数组: ["1173710", "--limit", "2"])
450
-
451
- # 3. 跑 verify 核对
452
- webcmd browser verify 1point3acres/thread
453
- ```
454
-
455
- 机器生成的种子只有 rowCount.min=1 / columns / types,挡不住字段值错位。**patterns + notEmpty 无论哪种情形都是肉写的**。
456
-
457
- ---
458
-
459
- ## 私人 adapter vs repo 贡献
460
-
461
- ```
462
- ~/.webcmd/clis/<site>/<name>.js # 私人
463
- clis/<site>/<name>.js # repo 贡献
268
+ webcmd browser verify <site>/<name> --write-fixture
464
269
  ```
465
270
 
466
- **两者在 `cli({...})` 层面完全一样**。差别只在运行入口:
271
+ Then tighten the fixture manually:
467
272
 
468
- - 私人:写完立即可跑(`webcmd <site> <name>`)
469
- - repo:要 `npm run build` 才被注册
273
+ - Add `notEmpty` for essential columns.
274
+ - Add `patterns` for URL, ID, date, or slug formats.
275
+ - Set realistic `rowCount`.
276
+ - Keep `types` narrow.
470
277
 
471
- 先在 `~/.webcmd/clis/` 调通再拷贝到 `clis/`。
278
+ Run verify again and confirm the fixture matches.