@jackwener/opencli 1.5.5 → 1.5.7

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 (540) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +31 -4
  3. package/README.zh-CN.md +40 -5
  4. package/SKILL.md +1 -1
  5. package/dist/browser/cdp.d.ts +1 -0
  6. package/dist/browser/cdp.js +30 -27
  7. package/dist/browser/daemon-client.d.ts +11 -1
  8. package/dist/browser/daemon-client.js +3 -0
  9. package/dist/browser/dom-helpers.js +1 -0
  10. package/dist/browser/dom-helpers.test.js +14 -1
  11. package/dist/browser/mcp.js +18 -13
  12. package/dist/browser/page.d.ts +6 -0
  13. package/dist/browser/page.js +37 -2
  14. package/dist/browser/page.test.d.ts +1 -0
  15. package/dist/browser/page.test.js +44 -0
  16. package/dist/browser/stealth.js +198 -0
  17. package/dist/browser/stealth.test.d.ts +1 -0
  18. package/dist/browser/stealth.test.js +134 -0
  19. package/dist/browser.test.js +1 -1
  20. package/dist/build-manifest.d.ts +1 -0
  21. package/dist/build-manifest.js +5 -1
  22. package/dist/build-manifest.test.js +2 -0
  23. package/dist/cli-manifest.json +1821 -252
  24. package/dist/cli.js +20 -3
  25. package/dist/clis/antigravity/serve.d.ts +1 -1
  26. package/dist/clis/antigravity/serve.js +5 -8
  27. package/dist/clis/band/bands.d.ts +1 -0
  28. package/dist/clis/band/bands.js +72 -0
  29. package/dist/clis/band/mentions.d.ts +1 -0
  30. package/dist/clis/band/mentions.js +127 -0
  31. package/dist/clis/band/post.d.ts +1 -0
  32. package/dist/clis/band/post.js +175 -0
  33. package/dist/clis/band/posts.d.ts +1 -0
  34. package/dist/clis/band/posts.js +94 -0
  35. package/dist/clis/bilibili/subtitle.js +4 -0
  36. package/dist/clis/bilibili/subtitle.test.d.ts +1 -0
  37. package/dist/clis/bilibili/subtitle.test.js +48 -0
  38. package/dist/clis/chatwise/ask.js +0 -2
  39. package/dist/clis/chatwise/export.js +0 -2
  40. package/dist/clis/chatwise/history.js +0 -2
  41. package/dist/clis/chatwise/model.js +0 -2
  42. package/dist/clis/chatwise/new.js +1 -2
  43. package/dist/clis/chatwise/read.js +0 -2
  44. package/dist/clis/chatwise/screenshot.js +1 -2
  45. package/dist/clis/chatwise/send.js +0 -2
  46. package/dist/clis/chatwise/status.js +1 -2
  47. package/dist/clis/ctrip/search.d.ts +13 -0
  48. package/dist/clis/ctrip/search.js +73 -48
  49. package/dist/clis/ctrip/search.test.d.ts +1 -0
  50. package/dist/clis/ctrip/search.test.js +64 -0
  51. package/dist/clis/doubao/detail.d.ts +1 -0
  52. package/dist/clis/doubao/detail.js +33 -0
  53. package/dist/clis/doubao/detail.test.d.ts +1 -0
  54. package/dist/clis/doubao/detail.test.js +42 -0
  55. package/dist/clis/doubao/history.d.ts +1 -0
  56. package/dist/clis/doubao/history.js +28 -0
  57. package/dist/clis/doubao/history.test.d.ts +1 -0
  58. package/dist/clis/doubao/history.test.js +37 -0
  59. package/dist/clis/doubao/meeting-summary.d.ts +1 -0
  60. package/dist/clis/doubao/meeting-summary.js +39 -0
  61. package/dist/clis/doubao/meeting-transcript.d.ts +1 -0
  62. package/dist/clis/doubao/meeting-transcript.js +36 -0
  63. package/dist/clis/doubao/utils.d.ts +27 -0
  64. package/dist/clis/doubao/utils.js +317 -0
  65. package/dist/clis/doubao/utils.test.d.ts +1 -0
  66. package/dist/clis/doubao/utils.test.js +24 -0
  67. package/dist/clis/douyin/_shared/public-api.d.ts +33 -0
  68. package/dist/clis/douyin/_shared/public-api.js +29 -0
  69. package/dist/clis/douyin/_shared/sts2.js +8 -2
  70. package/dist/clis/douyin/_shared/sts2.test.d.ts +1 -0
  71. package/dist/clis/douyin/_shared/sts2.test.js +27 -0
  72. package/dist/clis/douyin/activities.js +4 -2
  73. package/dist/clis/douyin/activities.test.js +34 -1
  74. package/dist/clis/douyin/collections.js +1 -1
  75. package/dist/clis/douyin/collections.test.js +24 -2
  76. package/dist/clis/douyin/draft.d.ts +8 -11
  77. package/dist/clis/douyin/draft.js +302 -185
  78. package/dist/clis/douyin/draft.test.d.ts +1 -1
  79. package/dist/clis/douyin/draft.test.js +357 -2
  80. package/dist/clis/douyin/hashtag.js +9 -2
  81. package/dist/clis/douyin/hashtag.test.js +35 -2
  82. package/dist/clis/douyin/profile.js +1 -1
  83. package/dist/clis/douyin/profile.test.js +36 -1
  84. package/dist/clis/douyin/user-videos.d.ts +5 -0
  85. package/dist/clis/douyin/user-videos.js +74 -0
  86. package/dist/clis/douyin/user-videos.test.d.ts +1 -0
  87. package/dist/clis/douyin/user-videos.test.js +108 -0
  88. package/dist/clis/douyin/videos.js +22 -5
  89. package/dist/clis/douyin/videos.test.js +45 -2
  90. package/dist/clis/facebook/search.test.d.ts +5 -0
  91. package/dist/clis/facebook/search.test.js +60 -0
  92. package/dist/clis/facebook/search.yaml +4 -3
  93. package/dist/clis/instagram/download.d.ts +16 -0
  94. package/dist/clis/instagram/download.js +225 -0
  95. package/dist/clis/instagram/download.test.d.ts +1 -0
  96. package/dist/clis/instagram/download.test.js +118 -0
  97. package/dist/clis/notebooklm/bind-current.d.ts +1 -0
  98. package/dist/clis/notebooklm/bind-current.js +29 -0
  99. package/dist/clis/notebooklm/bind-current.test.d.ts +1 -0
  100. package/dist/clis/notebooklm/bind-current.test.js +35 -0
  101. package/dist/clis/notebooklm/binding.test.d.ts +1 -0
  102. package/dist/clis/notebooklm/binding.test.js +44 -0
  103. package/dist/clis/notebooklm/compat.test.d.ts +3 -0
  104. package/dist/clis/notebooklm/compat.test.js +16 -0
  105. package/dist/clis/notebooklm/current.d.ts +1 -0
  106. package/dist/clis/notebooklm/current.js +28 -0
  107. package/dist/clis/notebooklm/get.d.ts +1 -0
  108. package/dist/clis/notebooklm/get.js +37 -0
  109. package/dist/clis/notebooklm/history.d.ts +1 -0
  110. package/dist/clis/notebooklm/history.js +25 -0
  111. package/dist/clis/notebooklm/history.test.d.ts +1 -0
  112. package/dist/clis/notebooklm/history.test.js +58 -0
  113. package/dist/clis/notebooklm/list.d.ts +1 -0
  114. package/dist/clis/notebooklm/list.js +35 -0
  115. package/dist/clis/notebooklm/note-list.d.ts +1 -0
  116. package/dist/clis/notebooklm/note-list.js +28 -0
  117. package/dist/clis/notebooklm/note-list.test.d.ts +1 -0
  118. package/dist/clis/notebooklm/note-list.test.js +56 -0
  119. package/dist/clis/notebooklm/notes-get.d.ts +1 -0
  120. package/dist/clis/notebooklm/notes-get.js +47 -0
  121. package/dist/clis/notebooklm/notes-get.test.d.ts +1 -0
  122. package/dist/clis/notebooklm/notes-get.test.js +72 -0
  123. package/dist/clis/notebooklm/rpc.d.ts +36 -0
  124. package/dist/clis/notebooklm/rpc.js +189 -0
  125. package/dist/clis/notebooklm/rpc.test.d.ts +1 -0
  126. package/dist/clis/notebooklm/rpc.test.js +105 -0
  127. package/dist/clis/notebooklm/shared.d.ts +87 -0
  128. package/dist/clis/notebooklm/shared.js +3 -0
  129. package/dist/clis/notebooklm/source-fulltext.d.ts +1 -0
  130. package/dist/clis/notebooklm/source-fulltext.js +44 -0
  131. package/dist/clis/notebooklm/source-fulltext.test.d.ts +1 -0
  132. package/dist/clis/notebooklm/source-fulltext.test.js +106 -0
  133. package/dist/clis/notebooklm/source-get.d.ts +1 -0
  134. package/dist/clis/notebooklm/source-get.js +40 -0
  135. package/dist/clis/notebooklm/source-get.test.d.ts +1 -0
  136. package/dist/clis/notebooklm/source-get.test.js +84 -0
  137. package/dist/clis/notebooklm/source-guide.d.ts +1 -0
  138. package/dist/clis/notebooklm/source-guide.js +44 -0
  139. package/dist/clis/notebooklm/source-guide.test.d.ts +1 -0
  140. package/dist/clis/notebooklm/source-guide.test.js +104 -0
  141. package/dist/clis/notebooklm/source-list.d.ts +1 -0
  142. package/dist/clis/notebooklm/source-list.js +30 -0
  143. package/dist/clis/notebooklm/status.d.ts +1 -0
  144. package/dist/clis/notebooklm/status.js +31 -0
  145. package/dist/clis/notebooklm/summary.d.ts +1 -0
  146. package/dist/clis/notebooklm/summary.js +30 -0
  147. package/dist/clis/notebooklm/summary.test.d.ts +1 -0
  148. package/dist/clis/notebooklm/summary.test.js +78 -0
  149. package/dist/clis/notebooklm/utils.d.ts +37 -0
  150. package/dist/clis/notebooklm/utils.js +739 -0
  151. package/dist/clis/notebooklm/utils.test.d.ts +1 -0
  152. package/dist/clis/notebooklm/utils.test.js +390 -0
  153. package/dist/clis/ones/common.d.ts +32 -0
  154. package/dist/clis/ones/common.js +144 -0
  155. package/dist/clis/ones/enrich-tasks.d.ts +5 -0
  156. package/dist/clis/ones/enrich-tasks.js +37 -0
  157. package/dist/clis/ones/login.d.ts +1 -0
  158. package/dist/clis/ones/login.js +80 -0
  159. package/dist/clis/ones/logout.d.ts +1 -0
  160. package/dist/clis/ones/logout.js +17 -0
  161. package/dist/clis/ones/me.d.ts +1 -0
  162. package/dist/clis/ones/me.js +30 -0
  163. package/dist/clis/ones/my-tasks.d.ts +1 -0
  164. package/dist/clis/ones/my-tasks.js +120 -0
  165. package/dist/clis/ones/resolve-labels.d.ts +10 -0
  166. package/dist/clis/ones/resolve-labels.js +64 -0
  167. package/dist/clis/ones/task-helpers.d.ts +29 -0
  168. package/dist/clis/ones/task-helpers.js +212 -0
  169. package/dist/clis/ones/task-helpers.test.d.ts +1 -0
  170. package/dist/clis/ones/task-helpers.test.js +12 -0
  171. package/dist/clis/ones/task.d.ts +1 -0
  172. package/dist/clis/ones/task.js +66 -0
  173. package/dist/clis/ones/tasks.d.ts +1 -0
  174. package/dist/clis/ones/tasks.js +79 -0
  175. package/dist/clis/ones/token-info.d.ts +1 -0
  176. package/dist/clis/ones/token-info.js +42 -0
  177. package/dist/clis/ones/worklog.d.ts +11 -0
  178. package/dist/clis/ones/worklog.js +267 -0
  179. package/dist/clis/ones/worklog.test.d.ts +1 -0
  180. package/dist/clis/ones/worklog.test.js +20 -0
  181. package/dist/clis/spotify/spotify.d.ts +1 -0
  182. package/dist/clis/spotify/spotify.js +316 -0
  183. package/dist/clis/spotify/utils.d.ts +21 -0
  184. package/dist/clis/spotify/utils.js +66 -0
  185. package/dist/clis/spotify/utils.test.d.ts +1 -0
  186. package/dist/clis/spotify/utils.test.js +67 -0
  187. package/dist/clis/substack/utils.d.ts +4 -0
  188. package/dist/clis/substack/utils.js +8 -2
  189. package/dist/clis/substack/utils.test.d.ts +1 -0
  190. package/dist/clis/substack/utils.test.js +46 -0
  191. package/dist/clis/tieba/commands.test.d.ts +4 -0
  192. package/dist/clis/tieba/commands.test.js +79 -0
  193. package/dist/clis/tieba/hot.d.ts +1 -0
  194. package/dist/clis/tieba/hot.js +48 -0
  195. package/dist/clis/tieba/posts.d.ts +1 -0
  196. package/dist/clis/tieba/posts.js +85 -0
  197. package/dist/clis/tieba/read.d.ts +1 -0
  198. package/dist/clis/tieba/read.js +140 -0
  199. package/dist/clis/tieba/search.d.ts +1 -0
  200. package/dist/clis/tieba/search.js +108 -0
  201. package/dist/clis/tieba/utils.d.ts +101 -0
  202. package/dist/clis/tieba/utils.js +240 -0
  203. package/dist/clis/tieba/utils.test.d.ts +1 -0
  204. package/dist/clis/tieba/utils.test.js +290 -0
  205. package/dist/clis/v2ex/hot.yaml +4 -1
  206. package/dist/clis/v2ex/latest.yaml +4 -1
  207. package/dist/clis/v2ex/topic.yaml +6 -1
  208. package/dist/clis/weixin/download.d.ts +9 -0
  209. package/dist/clis/weixin/download.js +76 -6
  210. package/dist/clis/weread/book.js +206 -13
  211. package/dist/clis/weread/commands.test.js +331 -0
  212. package/dist/clis/weread/private-api-regression.test.d.ts +1 -0
  213. package/dist/{weread-private-api-regression.test.js → clis/weread/private-api-regression.test.js} +92 -30
  214. package/dist/clis/weread/search-regression.test.d.ts +1 -0
  215. package/dist/clis/weread/search-regression.test.js +407 -0
  216. package/dist/clis/weread/search.js +143 -7
  217. package/dist/clis/weread/shelf.js +13 -95
  218. package/dist/clis/weread/utils.d.ts +56 -0
  219. package/dist/clis/weread/utils.js +234 -7
  220. package/dist/clis/weread/utils.test.js +71 -1
  221. package/dist/clis/xiaohongshu/comments.d.ts +3 -0
  222. package/dist/clis/xiaohongshu/comments.js +76 -17
  223. package/dist/clis/xiaohongshu/comments.test.js +70 -9
  224. package/dist/clis/xiaohongshu/download.d.ts +4 -1
  225. package/dist/clis/xiaohongshu/download.js +83 -22
  226. package/dist/clis/xiaohongshu/download.test.d.ts +1 -0
  227. package/dist/clis/xiaohongshu/download.test.js +75 -0
  228. package/dist/clis/xiaohongshu/note-helpers.d.ts +12 -0
  229. package/dist/clis/xiaohongshu/note-helpers.js +23 -0
  230. package/dist/clis/xiaohongshu/note.d.ts +7 -0
  231. package/dist/clis/xiaohongshu/note.js +76 -0
  232. package/dist/clis/xiaohongshu/note.test.d.ts +1 -0
  233. package/dist/clis/xiaohongshu/note.test.js +136 -0
  234. package/dist/clis/xiaohongshu/publish.d.ts +1 -1
  235. package/dist/clis/xiaohongshu/publish.js +78 -31
  236. package/dist/clis/xiaohongshu/publish.test.js +66 -1
  237. package/dist/clis/xiaohongshu/search.js +9 -0
  238. package/dist/clis/xiaohongshu/search.test.js +10 -4
  239. package/dist/clis/xiaohongshu/user-helpers.d.ts +1 -0
  240. package/dist/clis/xiaohongshu/user-helpers.js +2 -0
  241. package/dist/clis/xiaohongshu/user-helpers.test.js +18 -0
  242. package/dist/clis/xueqiu/comments.d.ts +118 -0
  243. package/dist/clis/xueqiu/comments.js +354 -0
  244. package/dist/clis/xueqiu/comments.test.d.ts +1 -0
  245. package/dist/clis/xueqiu/comments.test.js +696 -0
  246. package/dist/clis/youtube/search.js +57 -17
  247. package/dist/clis/youtube/transcript.js +2 -4
  248. package/dist/clis/youtube/utils.d.ts +9 -0
  249. package/dist/clis/youtube/utils.js +67 -3
  250. package/dist/clis/youtube/utils.test.d.ts +1 -0
  251. package/dist/clis/youtube/utils.test.js +37 -0
  252. package/dist/clis/youtube/video.js +16 -15
  253. package/dist/clis/zhihu/question.js +19 -17
  254. package/dist/clis/zhihu/question.test.d.ts +1 -0
  255. package/dist/clis/zhihu/question.test.js +54 -0
  256. package/dist/clis/zsxq/dynamics.d.ts +1 -0
  257. package/dist/clis/zsxq/dynamics.js +47 -0
  258. package/dist/clis/zsxq/groups.d.ts +1 -0
  259. package/dist/clis/zsxq/groups.js +32 -0
  260. package/dist/clis/zsxq/search.d.ts +1 -0
  261. package/dist/clis/zsxq/search.js +43 -0
  262. package/dist/clis/zsxq/search.test.d.ts +1 -0
  263. package/dist/clis/zsxq/search.test.js +24 -0
  264. package/dist/clis/zsxq/topic.d.ts +1 -0
  265. package/dist/clis/zsxq/topic.js +47 -0
  266. package/dist/clis/zsxq/topic.test.d.ts +1 -0
  267. package/dist/clis/zsxq/topic.test.js +29 -0
  268. package/dist/clis/zsxq/topics.d.ts +1 -0
  269. package/dist/clis/zsxq/topics.js +25 -0
  270. package/dist/clis/zsxq/topics.test.d.ts +1 -0
  271. package/dist/clis/zsxq/topics.test.js +24 -0
  272. package/dist/clis/zsxq/utils.d.ts +97 -0
  273. package/dist/clis/zsxq/utils.js +230 -0
  274. package/dist/commanderAdapter.js +10 -1
  275. package/dist/commanderAdapter.test.js +64 -0
  276. package/dist/commands/daemon.d.ts +9 -0
  277. package/dist/commands/daemon.js +124 -0
  278. package/dist/commands/daemon.test.d.ts +1 -0
  279. package/dist/commands/daemon.test.js +185 -0
  280. package/dist/completion.js +3 -1
  281. package/dist/constants.d.ts +2 -0
  282. package/dist/constants.js +2 -0
  283. package/dist/daemon.d.ts +1 -1
  284. package/dist/daemon.js +25 -14
  285. package/dist/daemon.test.d.ts +1 -0
  286. package/dist/daemon.test.js +65 -0
  287. package/dist/discovery.d.ts +9 -0
  288. package/dist/discovery.js +47 -2
  289. package/dist/electron-apps.d.ts +29 -0
  290. package/dist/electron-apps.js +65 -0
  291. package/dist/electron-apps.test.d.ts +1 -0
  292. package/dist/electron-apps.test.js +43 -0
  293. package/dist/engine.test.js +41 -9
  294. package/dist/execution.js +20 -16
  295. package/dist/external-clis.yaml +17 -0
  296. package/dist/idle-manager.d.ts +19 -0
  297. package/dist/idle-manager.js +54 -0
  298. package/dist/launcher.d.ts +36 -0
  299. package/dist/launcher.js +152 -0
  300. package/dist/launcher.test.d.ts +1 -0
  301. package/dist/launcher.test.js +57 -0
  302. package/dist/main.js +3 -3
  303. package/dist/registry.d.ts +1 -0
  304. package/dist/registry.js +31 -3
  305. package/dist/registry.test.js +13 -0
  306. package/dist/runtime.d.ts +5 -3
  307. package/dist/runtime.js +12 -5
  308. package/dist/serialization.d.ts +1 -0
  309. package/dist/serialization.js +3 -0
  310. package/dist/serialization.test.js +17 -1
  311. package/dist/tui.d.ts +7 -0
  312. package/dist/tui.js +52 -0
  313. package/dist/tui.test.d.ts +1 -0
  314. package/dist/tui.test.js +19 -0
  315. package/dist/types.d.ts +5 -0
  316. package/dist/weixin-download.test.js +14 -0
  317. package/docs/.vitepress/config.mts +4 -0
  318. package/docs/adapters/browser/band.md +63 -0
  319. package/docs/adapters/browser/notebooklm.md +69 -0
  320. package/docs/adapters/browser/ones.md +59 -0
  321. package/docs/adapters/browser/spotify.md +62 -0
  322. package/docs/adapters/browser/tieba.md +45 -0
  323. package/docs/adapters/browser/xiaohongshu.md +19 -10
  324. package/docs/adapters/browser/xueqiu.md +5 -0
  325. package/docs/adapters/browser/zsxq.md +49 -0
  326. package/docs/adapters/index.md +67 -63
  327. package/docs/adapters-doc/ones.md +32 -0
  328. package/docs/guide/browser-bridge.md +12 -0
  329. package/docs/guide/troubleshooting.md +9 -4
  330. package/docs/superpowers/plans/2026-03-31-daemon-lifecycle-redesign.md +857 -0
  331. package/docs/superpowers/specs/2026-03-31-daemon-lifecycle-redesign.md +208 -0
  332. package/docs/zh/guide/browser-bridge.md +12 -0
  333. package/extension/dist/background.js +794 -513
  334. package/extension/src/background.test.ts +202 -2
  335. package/extension/src/background.ts +189 -10
  336. package/extension/src/cdp.ts +54 -0
  337. package/extension/src/protocol.ts +11 -5
  338. package/package.json +1 -1
  339. package/scripts/postinstall.js +16 -0
  340. package/src/browser/cdp.ts +24 -17
  341. package/src/browser/daemon-client.ts +11 -1
  342. package/src/browser/dom-helpers.test.ts +15 -1
  343. package/src/browser/dom-helpers.ts +1 -0
  344. package/src/browser/mcp.ts +18 -13
  345. package/src/browser/page.test.ts +58 -0
  346. package/src/browser/page.ts +34 -2
  347. package/src/browser/stealth.test.ts +153 -0
  348. package/src/browser/stealth.ts +198 -0
  349. package/src/browser.test.ts +1 -1
  350. package/src/build-manifest.test.ts +2 -0
  351. package/src/build-manifest.ts +6 -1
  352. package/src/cli.ts +21 -3
  353. package/src/clis/antigravity/SKILL.md +3 -12
  354. package/src/clis/antigravity/serve.ts +5 -10
  355. package/src/clis/band/bands.ts +76 -0
  356. package/src/clis/band/mentions.ts +134 -0
  357. package/src/clis/band/post.ts +187 -0
  358. package/src/clis/band/posts.ts +106 -0
  359. package/src/clis/bilibili/subtitle.test.ts +60 -0
  360. package/src/clis/bilibili/subtitle.ts +4 -0
  361. package/src/clis/chatwise/ask.ts +0 -2
  362. package/src/clis/chatwise/export.ts +0 -2
  363. package/src/clis/chatwise/history.ts +0 -2
  364. package/src/clis/chatwise/model.ts +0 -2
  365. package/src/clis/chatwise/new.ts +1 -2
  366. package/src/clis/chatwise/read.ts +0 -2
  367. package/src/clis/chatwise/screenshot.ts +1 -2
  368. package/src/clis/chatwise/send.ts +0 -2
  369. package/src/clis/chatwise/status.ts +1 -2
  370. package/src/clis/ctrip/search.test.ts +73 -0
  371. package/src/clis/ctrip/search.ts +97 -47
  372. package/src/clis/doubao/detail.test.ts +53 -0
  373. package/src/clis/doubao/detail.ts +41 -0
  374. package/src/clis/doubao/history.test.ts +45 -0
  375. package/src/clis/doubao/history.ts +32 -0
  376. package/src/clis/doubao/meeting-summary.ts +53 -0
  377. package/src/clis/doubao/meeting-transcript.ts +48 -0
  378. package/src/clis/doubao/utils.test.ts +45 -0
  379. package/src/clis/doubao/utils.ts +371 -0
  380. package/src/clis/douyin/_shared/public-api.ts +84 -0
  381. package/src/clis/douyin/_shared/sts2.test.ts +31 -0
  382. package/src/clis/douyin/_shared/sts2.ts +11 -3
  383. package/src/clis/douyin/activities.test.ts +41 -1
  384. package/src/clis/douyin/activities.ts +12 -3
  385. package/src/clis/douyin/collections.test.ts +35 -2
  386. package/src/clis/douyin/collections.ts +1 -1
  387. package/src/clis/douyin/draft.test.ts +444 -2
  388. package/src/clis/douyin/draft.ts +382 -218
  389. package/src/clis/douyin/hashtag.test.ts +42 -2
  390. package/src/clis/douyin/hashtag.ts +11 -3
  391. package/src/clis/douyin/profile.test.ts +43 -1
  392. package/src/clis/douyin/profile.ts +9 -2
  393. package/src/clis/douyin/user-videos.test.ts +122 -0
  394. package/src/clis/douyin/user-videos.ts +101 -0
  395. package/src/clis/douyin/videos.test.ts +52 -2
  396. package/src/clis/douyin/videos.ts +49 -15
  397. package/src/clis/facebook/search.test.ts +70 -0
  398. package/src/clis/facebook/search.yaml +4 -3
  399. package/src/clis/instagram/download.test.ts +159 -0
  400. package/src/clis/instagram/download.ts +286 -0
  401. package/src/clis/notebooklm/bind-current.test.ts +43 -0
  402. package/src/clis/notebooklm/bind-current.ts +36 -0
  403. package/src/clis/notebooklm/binding.test.ts +53 -0
  404. package/src/clis/notebooklm/compat.test.ts +19 -0
  405. package/src/clis/notebooklm/current.ts +38 -0
  406. package/src/clis/notebooklm/get.ts +53 -0
  407. package/src/clis/notebooklm/history.test.ts +70 -0
  408. package/src/clis/notebooklm/history.ts +36 -0
  409. package/src/clis/notebooklm/list.ts +40 -0
  410. package/src/clis/notebooklm/note-list.test.ts +64 -0
  411. package/src/clis/notebooklm/note-list.ts +42 -0
  412. package/src/clis/notebooklm/notes-get.test.ts +88 -0
  413. package/src/clis/notebooklm/notes-get.ts +67 -0
  414. package/src/clis/notebooklm/rpc.test.ts +126 -0
  415. package/src/clis/notebooklm/rpc.ts +286 -0
  416. package/src/clis/notebooklm/shared.ts +98 -0
  417. package/src/clis/notebooklm/source-fulltext.test.ts +123 -0
  418. package/src/clis/notebooklm/source-fulltext.ts +69 -0
  419. package/src/clis/notebooklm/source-get.test.ts +100 -0
  420. package/src/clis/notebooklm/source-get.ts +60 -0
  421. package/src/clis/notebooklm/source-guide.test.ts +121 -0
  422. package/src/clis/notebooklm/source-guide.ts +69 -0
  423. package/src/clis/notebooklm/source-list.ts +45 -0
  424. package/src/clis/notebooklm/status.ts +34 -0
  425. package/src/clis/notebooklm/summary.test.ts +94 -0
  426. package/src/clis/notebooklm/summary.ts +45 -0
  427. package/src/clis/notebooklm/utils.test.ts +446 -0
  428. package/src/clis/notebooklm/utils.ts +893 -0
  429. package/src/clis/ones/common.ts +187 -0
  430. package/src/clis/ones/enrich-tasks.ts +47 -0
  431. package/src/clis/ones/login.ts +103 -0
  432. package/src/clis/ones/logout.ts +19 -0
  433. package/src/clis/ones/me.ts +34 -0
  434. package/src/clis/ones/my-tasks.ts +148 -0
  435. package/src/clis/ones/resolve-labels.ts +80 -0
  436. package/src/clis/ones/task-helpers.test.ts +14 -0
  437. package/src/clis/ones/task-helpers.ts +214 -0
  438. package/src/clis/ones/task.ts +79 -0
  439. package/src/clis/ones/tasks.ts +92 -0
  440. package/src/clis/ones/token-info.ts +46 -0
  441. package/src/clis/ones/worklog.test.ts +24 -0
  442. package/src/clis/ones/worklog.ts +306 -0
  443. package/src/clis/spotify/spotify.ts +328 -0
  444. package/src/clis/spotify/utils.test.ts +87 -0
  445. package/src/clis/spotify/utils.ts +92 -0
  446. package/src/clis/substack/utils.test.ts +54 -0
  447. package/src/clis/substack/utils.ts +10 -2
  448. package/src/clis/tieba/commands.test.ts +86 -0
  449. package/src/clis/tieba/hot.ts +52 -0
  450. package/src/clis/tieba/posts.ts +108 -0
  451. package/src/clis/tieba/read.ts +158 -0
  452. package/src/clis/tieba/search.ts +119 -0
  453. package/src/clis/tieba/utils.test.ts +322 -0
  454. package/src/clis/tieba/utils.ts +348 -0
  455. package/src/clis/v2ex/hot.yaml +4 -1
  456. package/src/clis/v2ex/latest.yaml +4 -1
  457. package/src/clis/v2ex/topic.yaml +6 -1
  458. package/src/clis/weixin/download.ts +95 -6
  459. package/src/clis/weread/book.ts +256 -13
  460. package/src/clis/weread/commands.test.ts +409 -0
  461. package/src/{weread-private-api-regression.test.ts → clis/weread/private-api-regression.test.ts} +108 -30
  462. package/src/clis/weread/search-regression.test.ts +440 -0
  463. package/src/clis/weread/search.ts +189 -9
  464. package/src/clis/weread/shelf.ts +20 -122
  465. package/src/clis/weread/utils.test.ts +81 -1
  466. package/src/clis/weread/utils.ts +293 -7
  467. package/src/clis/xiaohongshu/comments.test.ts +85 -9
  468. package/src/clis/xiaohongshu/comments.ts +76 -17
  469. package/src/clis/xiaohongshu/download.test.ts +96 -0
  470. package/src/clis/xiaohongshu/download.ts +83 -22
  471. package/src/clis/xiaohongshu/note-helpers.ts +25 -0
  472. package/src/clis/xiaohongshu/note.test.ts +164 -0
  473. package/src/clis/xiaohongshu/note.ts +86 -0
  474. package/src/clis/xiaohongshu/publish.test.ts +79 -1
  475. package/src/clis/xiaohongshu/publish.ts +84 -30
  476. package/src/clis/xiaohongshu/search.test.ts +11 -4
  477. package/src/clis/xiaohongshu/search.ts +13 -0
  478. package/src/clis/xiaohongshu/user-helpers.test.ts +23 -0
  479. package/src/clis/xiaohongshu/user-helpers.ts +4 -0
  480. package/src/clis/xueqiu/comments.test.ts +823 -0
  481. package/src/clis/xueqiu/comments.ts +461 -0
  482. package/src/clis/youtube/search.ts +57 -17
  483. package/src/clis/youtube/transcript.ts +2 -4
  484. package/src/clis/youtube/utils.test.ts +43 -0
  485. package/src/clis/youtube/utils.ts +69 -0
  486. package/src/clis/youtube/video.ts +16 -15
  487. package/src/clis/zhihu/question.test.ts +71 -0
  488. package/src/clis/zhihu/question.ts +27 -15
  489. package/src/clis/zsxq/dynamics.ts +60 -0
  490. package/src/clis/zsxq/groups.ts +41 -0
  491. package/src/clis/zsxq/search.test.ts +29 -0
  492. package/src/clis/zsxq/search.ts +54 -0
  493. package/src/clis/zsxq/topic.test.ts +34 -0
  494. package/src/clis/zsxq/topic.ts +68 -0
  495. package/src/clis/zsxq/topics.test.ts +29 -0
  496. package/src/clis/zsxq/topics.ts +36 -0
  497. package/src/clis/zsxq/utils.ts +351 -0
  498. package/src/commanderAdapter.test.ts +77 -0
  499. package/src/commanderAdapter.ts +8 -1
  500. package/src/commands/daemon.test.ts +238 -0
  501. package/src/commands/daemon.ts +135 -0
  502. package/src/completion.ts +2 -1
  503. package/src/constants.ts +3 -0
  504. package/src/daemon.test.ts +88 -0
  505. package/src/daemon.ts +26 -14
  506. package/src/discovery.ts +52 -2
  507. package/src/electron-apps.test.ts +50 -0
  508. package/src/electron-apps.ts +89 -0
  509. package/src/engine.test.ts +45 -9
  510. package/src/execution.ts +24 -19
  511. package/src/external-clis.yaml +17 -0
  512. package/src/idle-manager.ts +60 -0
  513. package/src/launcher.test.ts +67 -0
  514. package/src/launcher.ts +185 -0
  515. package/src/main.ts +3 -2
  516. package/src/registry.test.ts +15 -0
  517. package/src/registry.ts +32 -3
  518. package/src/runtime.ts +13 -7
  519. package/src/serialization.test.ts +19 -1
  520. package/src/serialization.ts +2 -0
  521. package/src/tui.test.ts +23 -0
  522. package/src/tui.ts +65 -0
  523. package/src/types.ts +5 -0
  524. package/src/weixin-download.test.ts +27 -0
  525. package/tests/e2e/band-auth.test.ts +20 -0
  526. package/tests/e2e/browser-auth-helpers.ts +18 -0
  527. package/tests/e2e/browser-auth.test.ts +35 -47
  528. package/tests/e2e/browser-public-extended.test.ts +6 -2
  529. package/tests/e2e/browser-public.test.ts +288 -0
  530. package/tests/e2e/management.test.ts +1 -1
  531. package/tests/e2e/plugin-management.test.ts +1 -1
  532. package/vitest.config.ts +1 -0
  533. package/chatwise-opencli.ps1 +0 -82
  534. package/dist/clis/chatwise/shared.d.ts +0 -2
  535. package/dist/clis/chatwise/shared.js +0 -6
  536. package/dist/weread-private-api-regression.test.d.ts +0 -1
  537. package/dist/weread-search-regression.test.d.ts +0 -1
  538. package/dist/weread-search-regression.test.js +0 -39
  539. package/src/clis/chatwise/shared.ts +0 -8
  540. package/src/weread-search-regression.test.ts +0 -44
@@ -149,6 +149,204 @@ export function generateStealthJs() {
149
149
  }
150
150
  } catch {}
151
151
 
152
+ // ── Shared toString disguise infrastructure ──
153
+ // Save the pristine Function.prototype.toString BEFORE any patches,
154
+ // so all subsequent disguises use the real native reference.
155
+ // Anti-bot scripts detect per-instance toString overrides via:
156
+ // Function.hasOwnProperty('toString') → true if patched
157
+ // Function.prototype.toString.call(fn) !== fn.toString()
158
+ // Instead we patch Function.prototype.toString once with a WeakMap
159
+ // lookup, making disguised functions indistinguishable from native.
160
+ const _origToString = Function.prototype.toString;
161
+ const _disguised = new WeakMap();
162
+ try {
163
+ Object.defineProperty(Function.prototype, 'toString', {
164
+ value: function() {
165
+ const override = _disguised.get(this);
166
+ return override !== undefined ? override : _origToString.call(this);
167
+ },
168
+ writable: true, configurable: true,
169
+ });
170
+ } catch {}
171
+ const _disguise = (fn, name) => {
172
+ _disguised.set(fn, 'function ' + name + '() { [native code] }');
173
+ try { Object.defineProperty(fn, 'name', { value: name, configurable: true }); } catch {}
174
+ return fn;
175
+ };
176
+
177
+ // 8. Anti-debugger statement trap
178
+ // Sites inject debugger statements to detect DevTools/CDP.
179
+ // When a CDP debugger is attached, the statement pauses execution
180
+ // and the site measures the time gap to confirm automation.
181
+ // We neutralize this by overriding the Function constructor and
182
+ // eval to strip debugger statements from dynamically created code.
183
+ // Note: this does NOT affect static debugger statements in parsed
184
+ // scripts — those require CDP Debugger.setBreakpointsActive(false)
185
+ // which we handle at the extension level.
186
+ // Caveat: the regex targets standalone debugger statements (preceded
187
+ // by a statement boundary) to minimise false positives inside string
188
+ // literals, but cannot perfectly distinguish all cases without a
189
+ // full parser. This is an acceptable trade-off for stealth code.
190
+ try {
191
+ const _OrigFunction = Function;
192
+ // Match standalone debugger statements preceded by a statement
193
+ // boundary (start of string, semicolon, brace, or newline).
194
+ // This avoids most false positives inside string literals like
195
+ // "use debugger mode" while still catching the anti-bot patterns.
196
+ const _debuggerRe = /(?:^|(?<=[;{}\\n\\r]))\\s*debugger\\s*;?/g;
197
+ const _cleanDebugger = (src) => typeof src === 'string' ? src.replace(_debuggerRe, '') : src;
198
+ // Patch Function constructor to strip debugger from dynamic code.
199
+ // Support both Function('code') and new Function('code') via
200
+ // new.target / Reflect.construct.
201
+ const _PatchedFunction = function(...args) {
202
+ if (args.length > 0) {
203
+ args[args.length - 1] = _cleanDebugger(args[args.length - 1]);
204
+ }
205
+ if (new.target) {
206
+ return Reflect.construct(_OrigFunction, args, new.target);
207
+ }
208
+ return _OrigFunction.apply(this, args);
209
+ };
210
+ _PatchedFunction.prototype = _OrigFunction.prototype;
211
+ Object.setPrototypeOf(_PatchedFunction, _OrigFunction);
212
+ _disguise(_PatchedFunction, 'Function');
213
+ try { window.Function = _PatchedFunction; } catch {}
214
+
215
+ // Patch eval to strip debugger
216
+ const _origEval = window.eval;
217
+ const _patchedEval = function(code) {
218
+ return _origEval.call(this, _cleanDebugger(code));
219
+ };
220
+ _disguise(_patchedEval, 'eval');
221
+ try { window.eval = _patchedEval; } catch {}
222
+ } catch {}
223
+
224
+ // 9. Console method fingerprinting defense
225
+ // When CDP Runtime.enable is called, Chrome replaces console.log etc.
226
+ // with CDP-bound versions. These bound functions have a different
227
+ // toString() output: "function log() { [native code] }" becomes
228
+ // something like "function () { [native code] }" (no name) or the
229
+ // bound function signature leaks. Anti-bot scripts check:
230
+ // console.log.toString().includes('[native code]')
231
+ // console.log.name === 'log'
232
+ // We re-wrap console methods and register them via the shared
233
+ // _disguise infrastructure so Function.prototype.toString.call()
234
+ // also returns the correct native string.
235
+ try {
236
+ const _consoleMethods = ['log', 'warn', 'error', 'info', 'debug', 'table', 'trace', 'dir', 'group', 'groupEnd', 'groupCollapsed', 'clear', 'count', 'assert', 'profile', 'profileEnd', 'time', 'timeEnd', 'timeStamp'];
237
+ for (const _m of _consoleMethods) {
238
+ if (typeof console[_m] !== 'function') continue;
239
+ const _origMethod = console[_m];
240
+ const _nativeStr = 'function ' + _m + '() { [native code] }';
241
+ // Only patch if toString is wrong (i.e. CDP has replaced it)
242
+ try {
243
+ const _currentStr = _origToString.call(_origMethod);
244
+ if (_currentStr === _nativeStr) continue; // already looks native
245
+ } catch {}
246
+ const _wrapper = function() { return _origMethod.apply(console, arguments); };
247
+ Object.defineProperty(_wrapper, 'length', { value: _origMethod.length || 0, configurable: true });
248
+ _disguise(_wrapper, _m);
249
+ try { console[_m] = _wrapper; } catch {}
250
+ }
251
+ } catch {}
252
+
253
+ // 10. window.outerWidth/outerHeight defense
254
+ // When DevTools or CDP debugger is attached, Chrome may alter the
255
+ // window dimensions. Anti-bot scripts compare outerWidth/innerWidth
256
+ // and outerHeight/innerHeight — a significant difference indicates
257
+ // DevTools is open. We freeze the relationship so the delta stays
258
+ // consistent with a normal browser window.
259
+ // Thresholds: width delta > 100px or height delta > 200px indicates
260
+ // a docked DevTools panel. When triggered, we report outerWidth
261
+ // equal to innerWidth (normal for maximised windows) and
262
+ // outerHeight as innerHeight + the captured "normal" delta (capped
263
+ // to a reasonable range), so the result is plausible across OSes.
264
+ try {
265
+ const _normalWidthDelta = window.outerWidth - window.innerWidth;
266
+ const _normalHeightDelta = window.outerHeight - window.innerHeight;
267
+ // Only patch if the delta looks suspicious (e.g. DevTools docked)
268
+ if (_normalWidthDelta > 100 || _normalHeightDelta > 200) {
269
+ Object.defineProperty(window, 'outerWidth', {
270
+ get: () => window.innerWidth,
271
+ configurable: true,
272
+ });
273
+ // Use a clamped height offset (40-120px covers macOS ~78px,
274
+ // Windows ~40px, and Linux ~37-50px title bar heights).
275
+ const _heightOffset = Math.max(40, Math.min(120, _normalHeightDelta));
276
+ Object.defineProperty(window, 'outerHeight', {
277
+ get: () => window.innerHeight + _heightOffset,
278
+ configurable: true,
279
+ });
280
+ }
281
+ } catch {}
282
+
283
+ // 11. Performance API cleanup
284
+ // CDP injects internal resources and timing entries that don't exist
285
+ // in normal browsing. Filter entries with debugger/devtools URLs.
286
+ try {
287
+ const _origGetEntries = Performance.prototype.getEntries;
288
+ const _origGetByType = Performance.prototype.getEntriesByType;
289
+ const _origGetByName = Performance.prototype.getEntriesByName;
290
+ const _suspiciousPatterns = ['debugger', 'devtools', '__puppeteer', '__playwright', 'pptr:'];
291
+ const _filterEntries = (entries) => {
292
+ if (!Array.isArray(entries)) return entries;
293
+ return entries.filter(e => {
294
+ const name = e.name || '';
295
+ return !_suspiciousPatterns.some(p => name.includes(p));
296
+ });
297
+ };
298
+ Performance.prototype.getEntries = function() {
299
+ return _filterEntries(_origGetEntries.call(this));
300
+ };
301
+ Performance.prototype.getEntriesByType = function(type) {
302
+ return _filterEntries(_origGetByType.call(this, type));
303
+ };
304
+ Performance.prototype.getEntriesByName = function(name, type) {
305
+ return _filterEntries(_origGetByName.call(this, name, type));
306
+ };
307
+ } catch {}
308
+
309
+ // 12. WebDriver-related property defense
310
+ // Some anti-bot systems check additional navigator properties
311
+ // and document properties that may indicate automation.
312
+ try {
313
+ // document.$cdc_ properties (ChromeDriver specific, backup for #6)
314
+ for (const _prop of Object.getOwnPropertyNames(document)) {
315
+ if (_prop.startsWith('$cdc_') || _prop.startsWith('$chrome_')) {
316
+ try { delete document[_prop]; } catch {}
317
+ }
318
+ }
319
+ } catch {}
320
+
321
+ // 13. Iframe contentWindow.chrome consistency
322
+ // Anti-bot scripts create iframes and check if
323
+ // iframe.contentWindow.chrome exists and matches the parent.
324
+ // CDP-controlled pages may have inconsistent iframe contexts.
325
+ try {
326
+ const _origHTMLIFrame = HTMLIFrameElement.prototype;
327
+ const _origContentWindow = Object.getOwnPropertyDescriptor(_origHTMLIFrame, 'contentWindow');
328
+ if (_origContentWindow && _origContentWindow.get) {
329
+ Object.defineProperty(_origHTMLIFrame, 'contentWindow', {
330
+ get: function() {
331
+ const _w = _origContentWindow.get.call(this);
332
+ if (_w) {
333
+ try {
334
+ if (!_w.chrome) {
335
+ Object.defineProperty(_w, 'chrome', {
336
+ value: window.chrome,
337
+ writable: true,
338
+ configurable: true,
339
+ });
340
+ }
341
+ } catch {}
342
+ }
343
+ return _w;
344
+ },
345
+ configurable: true,
346
+ });
347
+ }
348
+ } catch {}
349
+
152
350
  return 'applied';
153
351
  })()
154
352
  `;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateStealthJs } from './stealth.js';
3
+ /**
4
+ * Tests for the stealth anti-detection module.
5
+ *
6
+ * We test the generated JS string for expected content and structure.
7
+ * Evaluating in Node is fragile because stealth patches target browser
8
+ * globals (navigator, Performance, HTMLIFrameElement) that don't exist
9
+ * or behave differently in Node. Instead we verify the code string
10
+ * contains the right patches and is syntactically valid.
11
+ */
12
+ describe('generateStealthJs', () => {
13
+ it('returns a non-empty string', () => {
14
+ const code = generateStealthJs();
15
+ expect(typeof code).toBe('string');
16
+ expect(code.length).toBeGreaterThan(0);
17
+ });
18
+ it('is a valid self-contained IIFE', () => {
19
+ const code = generateStealthJs();
20
+ // Should start/end as an IIFE
21
+ expect(code.trim()).toMatch(/^\(\(\) => \{/);
22
+ expect(code.trim()).toMatch(/\}\)\(\)$/);
23
+ });
24
+ it('patches navigator.webdriver', () => {
25
+ const code = generateStealthJs();
26
+ expect(code).toContain("navigator, 'webdriver'");
27
+ expect(code).toContain('() => false');
28
+ });
29
+ it('stubs window.chrome', () => {
30
+ const code = generateStealthJs();
31
+ expect(code).toContain('window.chrome');
32
+ expect(code).toContain('runtime');
33
+ expect(code).toContain('loadTimes');
34
+ expect(code).toContain('csi');
35
+ });
36
+ it('fakes navigator.plugins if empty', () => {
37
+ const code = generateStealthJs();
38
+ expect(code).toContain('navigator.plugins');
39
+ expect(code).toContain('PDF Viewer');
40
+ expect(code).toContain('Chrome PDF Viewer');
41
+ });
42
+ it('ensures navigator.languages is non-empty', () => {
43
+ const code = generateStealthJs();
44
+ expect(code).toContain('navigator.languages');
45
+ expect(code).toContain("'en-US'");
46
+ });
47
+ it('normalizes Permissions.query for notifications', () => {
48
+ const code = generateStealthJs();
49
+ expect(code).toContain('Permissions');
50
+ expect(code).toContain('notifications');
51
+ });
52
+ it('cleans automation artifacts', () => {
53
+ const code = generateStealthJs();
54
+ expect(code).toContain('__playwright');
55
+ expect(code).toContain('__puppeteer');
56
+ expect(code).toContain("'cdc_'");
57
+ expect(code).toContain("'__cdc_'");
58
+ });
59
+ it('filters CDP patterns from Error.stack', () => {
60
+ const code = generateStealthJs();
61
+ expect(code).toContain('puppeteer_evaluation_script');
62
+ expect(code).toContain("'pptr:'");
63
+ expect(code).toContain("'debugger://'");
64
+ });
65
+ it('neutralizes debugger statement traps', () => {
66
+ const code = generateStealthJs();
67
+ // Should patch Function constructor with new.target / Reflect.construct
68
+ expect(code).toContain('_OrigFunction');
69
+ expect(code).toContain('_PatchedFunction');
70
+ expect(code).toContain('new.target');
71
+ expect(code).toContain('Reflect.construct');
72
+ // Should patch eval
73
+ expect(code).toContain('_origEval');
74
+ expect(code).toContain('_patchedEval');
75
+ // Regex to strip debugger (lookbehind for statement boundaries)
76
+ expect(code).toContain('_debuggerRe');
77
+ });
78
+ it('uses shared toString disguise via WeakMap', () => {
79
+ const code = generateStealthJs();
80
+ // Shared infrastructure at the top of the IIFE
81
+ expect(code).toContain('_origToString');
82
+ expect(code).toContain('WeakMap');
83
+ expect(code).toContain('_disguised');
84
+ expect(code).toContain('_disguise');
85
+ // Should NOT have per-instance toString overrides on Function/eval
86
+ // (they go through _disguise instead)
87
+ });
88
+ it('defends console method fingerprinting', () => {
89
+ const code = generateStealthJs();
90
+ expect(code).toContain('_consoleMethods');
91
+ expect(code).toContain("'log'");
92
+ expect(code).toContain("'warn'");
93
+ expect(code).toContain("'error'");
94
+ expect(code).toContain('[native code]');
95
+ // Uses saved _origToString reference
96
+ expect(code).toContain('_origToString.call');
97
+ });
98
+ it('defends window dimension detection', () => {
99
+ const code = generateStealthJs();
100
+ expect(code).toContain('outerWidth');
101
+ expect(code).toContain('outerHeight');
102
+ expect(code).toContain('innerWidth');
103
+ expect(code).toContain('innerHeight');
104
+ });
105
+ it('filters Performance API entries', () => {
106
+ const code = generateStealthJs();
107
+ expect(code).toContain('getEntries');
108
+ expect(code).toContain('getEntriesByType');
109
+ expect(code).toContain('getEntriesByName');
110
+ expect(code).toContain('_suspiciousPatterns');
111
+ });
112
+ it('cleans document $cdc_ properties', () => {
113
+ const code = generateStealthJs();
114
+ expect(code).toContain("'$cdc_'");
115
+ expect(code).toContain("'$chrome_'");
116
+ });
117
+ it('patches iframe contentWindow.chrome consistency', () => {
118
+ const code = generateStealthJs();
119
+ expect(code).toContain('contentWindow');
120
+ expect(code).toContain('HTMLIFrameElement');
121
+ });
122
+ it('uses non-enumerable guard flag on EventTarget.prototype', () => {
123
+ const code = generateStealthJs();
124
+ expect(code).toContain('EventTarget.prototype');
125
+ expect(code).toContain("'__lsn'");
126
+ expect(code).toContain('enumerable: false');
127
+ });
128
+ it('generates syntactically valid JavaScript', () => {
129
+ const code = generateStealthJs();
130
+ // new Function() parses the code without executing it in a real
131
+ // browser context, catching syntax errors from template literal issues.
132
+ expect(() => new Function(code)).not.toThrow();
133
+ });
134
+ });
@@ -108,7 +108,7 @@ describe('BrowserBridge state', () => {
108
108
  vi.spyOn(daemonClient, 'isExtensionConnected').mockResolvedValue(false);
109
109
  vi.spyOn(daemonClient, 'isDaemonRunning').mockResolvedValue(true);
110
110
  const mcp = new BrowserBridge();
111
- await expect(mcp.connect()).rejects.toThrow('Browser Extension is not connected');
111
+ await expect(mcp.connect({ timeout: 0.1 })).rejects.toThrow('Browser Extension is not connected');
112
112
  });
113
113
  });
114
114
  describe('stealth anti-detection', () => {
@@ -11,6 +11,7 @@
11
11
  export interface ManifestEntry {
12
12
  site: string;
13
13
  name: string;
14
+ aliases?: string[];
14
15
  description: string;
15
16
  domain?: string;
16
17
  strategy: string;
@@ -46,6 +46,7 @@ function toManifestEntry(cmd, modulePath) {
46
46
  return {
47
47
  site: cmd.site,
48
48
  name: cmd.name,
49
+ aliases: cmd.aliases,
49
50
  description: cmd.description ?? '',
50
51
  domain: cmd.domain,
51
52
  strategy: (cmd.strategy ?? 'public').toString().toLowerCase(),
@@ -78,6 +79,9 @@ function scanYaml(filePath, site) {
78
79
  domain: cliDef.domain,
79
80
  strategy: strategy.toLowerCase(),
80
81
  browser,
82
+ aliases: isRecord(cliDef) && Array.isArray(cliDef.aliases)
83
+ ? cliDef.aliases.filter((value) => typeof value === 'string')
84
+ : undefined,
81
85
  args,
82
86
  columns: cliDef.columns,
83
87
  pipeline: cliDef.pipeline,
@@ -181,7 +185,7 @@ export async function buildManifest() {
181
185
  }
182
186
  }
183
187
  }
184
- return [...manifest.values()];
188
+ return [...manifest.values()].sort((a, b) => a.site.localeCompare(b.site) || a.name.localeCompare(b.name));
185
189
  }
186
190
  async function main() {
187
191
  const manifest = await buildManifest();
@@ -70,6 +70,7 @@ describe('manifest helper rules', () => {
70
70
  description: 'dynamic command',
71
71
  strategy: Strategy.PUBLIC,
72
72
  browser: false,
73
+ aliases: ['metadata'],
73
74
  args: [
74
75
  {
75
76
  name: 'model',
@@ -94,6 +95,7 @@ describe('manifest helper rules', () => {
94
95
  domain: 'localhost',
95
96
  strategy: 'public',
96
97
  browser: false,
98
+ aliases: ['metadata'],
97
99
  args: [
98
100
  {
99
101
  name: 'model',