agent-messenger 2.10.1 → 2.11.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 (536) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.env.template +4 -1
  3. package/README.md +77 -27
  4. package/bun.lock +26 -0
  5. package/dist/package.json +14 -1
  6. package/dist/src/platforms/channeltalk/commands/auth.d.ts +2 -1
  7. package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
  8. package/dist/src/platforms/channeltalk/commands/auth.js +5 -3
  9. package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
  10. package/dist/src/platforms/channeltalk/token-extractor.d.ts +2 -1
  11. package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
  12. package/dist/src/platforms/channeltalk/token-extractor.js +22 -6
  13. package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
  14. package/dist/src/platforms/channeltalkbot/cli.d.ts.map +1 -1
  15. package/dist/src/platforms/channeltalkbot/cli.js +11 -1
  16. package/dist/src/platforms/channeltalkbot/cli.js.map +1 -1
  17. package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
  18. package/dist/src/platforms/channeltalkbot/commands/auth.js +1 -5
  19. package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
  20. package/dist/src/platforms/channeltalkbot/commands/bot.d.ts.map +1 -1
  21. package/dist/src/platforms/channeltalkbot/commands/bot.js +1 -6
  22. package/dist/src/platforms/channeltalkbot/commands/bot.js.map +1 -1
  23. package/dist/src/platforms/channeltalkbot/commands/chat.d.ts.map +1 -1
  24. package/dist/src/platforms/channeltalkbot/commands/chat.js +1 -6
  25. package/dist/src/platforms/channeltalkbot/commands/chat.js.map +1 -1
  26. package/dist/src/platforms/channeltalkbot/commands/group.d.ts.map +1 -1
  27. package/dist/src/platforms/channeltalkbot/commands/group.js +1 -6
  28. package/dist/src/platforms/channeltalkbot/commands/group.js.map +1 -1
  29. package/dist/src/platforms/channeltalkbot/commands/manager.d.ts.map +1 -1
  30. package/dist/src/platforms/channeltalkbot/commands/manager.js +1 -6
  31. package/dist/src/platforms/channeltalkbot/commands/manager.js.map +1 -1
  32. package/dist/src/platforms/channeltalkbot/commands/message.d.ts.map +1 -1
  33. package/dist/src/platforms/channeltalkbot/commands/message.js +1 -6
  34. package/dist/src/platforms/channeltalkbot/commands/message.js.map +1 -1
  35. package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts.map +1 -1
  36. package/dist/src/platforms/channeltalkbot/commands/whoami.js +1 -6
  37. package/dist/src/platforms/channeltalkbot/commands/whoami.js.map +1 -1
  38. package/dist/src/platforms/channeltalkbot/credential-manager.d.ts +5 -0
  39. package/dist/src/platforms/channeltalkbot/credential-manager.d.ts.map +1 -1
  40. package/dist/src/platforms/channeltalkbot/credential-manager.js +34 -4
  41. package/dist/src/platforms/channeltalkbot/credential-manager.js.map +1 -1
  42. package/dist/src/platforms/discord/commands/auth.d.ts +1 -0
  43. package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -1
  44. package/dist/src/platforms/discord/commands/auth.js +3 -1
  45. package/dist/src/platforms/discord/commands/auth.js.map +1 -1
  46. package/dist/src/platforms/discord/listener.d.ts +2 -0
  47. package/dist/src/platforms/discord/listener.d.ts.map +1 -1
  48. package/dist/src/platforms/discord/listener.js +51 -21
  49. package/dist/src/platforms/discord/listener.js.map +1 -1
  50. package/dist/src/platforms/discord/token-extractor.d.ts +2 -1
  51. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  52. package/dist/src/platforms/discord/token-extractor.js +21 -6
  53. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  54. package/dist/src/platforms/discordbot/cli.d.ts.map +1 -1
  55. package/dist/src/platforms/discordbot/cli.js +12 -1
  56. package/dist/src/platforms/discordbot/cli.js.map +1 -1
  57. package/dist/src/platforms/discordbot/client.d.ts +3 -0
  58. package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
  59. package/dist/src/platforms/discordbot/client.js +3 -0
  60. package/dist/src/platforms/discordbot/client.js.map +1 -1
  61. package/dist/src/platforms/discordbot/commands/auth.d.ts.map +1 -1
  62. package/dist/src/platforms/discordbot/commands/auth.js +1 -5
  63. package/dist/src/platforms/discordbot/commands/auth.js.map +1 -1
  64. package/dist/src/platforms/discordbot/commands/message.d.ts.map +1 -1
  65. package/dist/src/platforms/discordbot/commands/message.js +1 -6
  66. package/dist/src/platforms/discordbot/commands/message.js.map +1 -1
  67. package/dist/src/platforms/discordbot/commands/server.d.ts.map +1 -1
  68. package/dist/src/platforms/discordbot/commands/server.js +1 -4
  69. package/dist/src/platforms/discordbot/commands/server.js.map +1 -1
  70. package/dist/src/platforms/discordbot/commands/whoami.d.ts.map +1 -1
  71. package/dist/src/platforms/discordbot/commands/whoami.js +1 -6
  72. package/dist/src/platforms/discordbot/commands/whoami.js.map +1 -1
  73. package/dist/src/platforms/discordbot/index.d.ts +3 -1
  74. package/dist/src/platforms/discordbot/index.d.ts.map +1 -1
  75. package/dist/src/platforms/discordbot/index.js +2 -1
  76. package/dist/src/platforms/discordbot/index.js.map +1 -1
  77. package/dist/src/platforms/discordbot/listener.d.ts +43 -0
  78. package/dist/src/platforms/discordbot/listener.d.ts.map +1 -0
  79. package/dist/src/platforms/discordbot/listener.js +292 -0
  80. package/dist/src/platforms/discordbot/listener.js.map +1 -0
  81. package/dist/src/platforms/discordbot/types.d.ts +161 -0
  82. package/dist/src/platforms/discordbot/types.d.ts.map +1 -1
  83. package/dist/src/platforms/discordbot/types.js +34 -0
  84. package/dist/src/platforms/discordbot/types.js.map +1 -1
  85. package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
  86. package/dist/src/platforms/instagram/commands/auth.js +3 -1
  87. package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
  88. package/dist/src/platforms/instagram/token-extractor.d.ts +2 -1
  89. package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
  90. package/dist/src/platforms/instagram/token-extractor.js +11 -2
  91. package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
  92. package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
  93. package/dist/src/platforms/slack/commands/auth.js +4 -2
  94. package/dist/src/platforms/slack/commands/auth.js.map +1 -1
  95. package/dist/src/platforms/slack/token-extractor.d.ts +4 -1
  96. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  97. package/dist/src/platforms/slack/token-extractor.js +64 -15
  98. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  99. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  100. package/dist/src/platforms/slackbot/cli.js +15 -3
  101. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  102. package/dist/src/platforms/slackbot/client.d.ts +22 -1
  103. package/dist/src/platforms/slackbot/client.d.ts.map +1 -1
  104. package/dist/src/platforms/slackbot/client.js +104 -1
  105. package/dist/src/platforms/slackbot/client.js.map +1 -1
  106. package/dist/src/platforms/slackbot/commands/auth.d.ts.map +1 -1
  107. package/dist/src/platforms/slackbot/commands/auth.js +1 -5
  108. package/dist/src/platforms/slackbot/commands/auth.js.map +1 -1
  109. package/dist/src/platforms/slackbot/commands/file.d.ts +3 -0
  110. package/dist/src/platforms/slackbot/commands/file.d.ts.map +1 -0
  111. package/dist/src/platforms/slackbot/commands/file.js +164 -0
  112. package/dist/src/platforms/slackbot/commands/file.js.map +1 -0
  113. package/dist/src/platforms/slackbot/commands/index.d.ts +1 -0
  114. package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -1
  115. package/dist/src/platforms/slackbot/commands/index.js +1 -0
  116. package/dist/src/platforms/slackbot/commands/index.js.map +1 -1
  117. package/dist/src/platforms/slackbot/commands/message.d.ts.map +1 -1
  118. package/dist/src/platforms/slackbot/commands/message.js +19 -0
  119. package/dist/src/platforms/slackbot/commands/message.js.map +1 -1
  120. package/dist/src/platforms/slackbot/commands/whoami.d.ts.map +1 -1
  121. package/dist/src/platforms/slackbot/commands/whoami.js +1 -6
  122. package/dist/src/platforms/slackbot/commands/whoami.js.map +1 -1
  123. package/dist/src/platforms/slackbot/credential-manager.d.ts +1 -0
  124. package/dist/src/platforms/slackbot/credential-manager.d.ts.map +1 -1
  125. package/dist/src/platforms/slackbot/credential-manager.js +30 -2
  126. package/dist/src/platforms/slackbot/credential-manager.js.map +1 -1
  127. package/dist/src/platforms/slackbot/index.d.ts +4 -1
  128. package/dist/src/platforms/slackbot/index.d.ts.map +1 -1
  129. package/dist/src/platforms/slackbot/index.js +1 -0
  130. package/dist/src/platforms/slackbot/index.js.map +1 -1
  131. package/dist/src/platforms/slackbot/listener.d.ts +44 -0
  132. package/dist/src/platforms/slackbot/listener.d.ts.map +1 -0
  133. package/dist/src/platforms/slackbot/listener.js +313 -0
  134. package/dist/src/platforms/slackbot/listener.js.map +1 -0
  135. package/dist/src/platforms/slackbot/types.d.ts +196 -1
  136. package/dist/src/platforms/slackbot/types.d.ts.map +1 -1
  137. package/dist/src/platforms/slackbot/types.js +4 -1
  138. package/dist/src/platforms/slackbot/types.js.map +1 -1
  139. package/dist/src/platforms/teams/commands/auth.d.ts +1 -0
  140. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
  141. package/dist/src/platforms/teams/commands/auth.js +37 -6
  142. package/dist/src/platforms/teams/commands/auth.js.map +1 -1
  143. package/dist/src/platforms/teams/ensure-auth.js +31 -9
  144. package/dist/src/platforms/teams/ensure-auth.js.map +1 -1
  145. package/dist/src/platforms/teams/token-extractor.d.ts +4 -1
  146. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
  147. package/dist/src/platforms/teams/token-extractor.js +80 -31
  148. package/dist/src/platforms/teams/token-extractor.js.map +1 -1
  149. package/dist/src/platforms/webex/commands/auth.d.ts +1 -0
  150. package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
  151. package/dist/src/platforms/webex/commands/auth.js +3 -1
  152. package/dist/src/platforms/webex/commands/auth.js.map +1 -1
  153. package/dist/src/platforms/webex/token-extractor.d.ts +3 -1
  154. package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
  155. package/dist/src/platforms/webex/token-extractor.js +16 -2
  156. package/dist/src/platforms/webex/token-extractor.js.map +1 -1
  157. package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -1
  158. package/dist/src/platforms/wechatbot/cli.js +11 -1
  159. package/dist/src/platforms/wechatbot/cli.js.map +1 -1
  160. package/dist/src/platforms/wechatbot/commands/auth.d.ts.map +1 -1
  161. package/dist/src/platforms/wechatbot/commands/auth.js +1 -5
  162. package/dist/src/platforms/wechatbot/commands/auth.js.map +1 -1
  163. package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
  164. package/dist/src/platforms/wechatbot/commands/message.js +1 -6
  165. package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
  166. package/dist/src/platforms/wechatbot/commands/template.d.ts.map +1 -1
  167. package/dist/src/platforms/wechatbot/commands/template.js +1 -6
  168. package/dist/src/platforms/wechatbot/commands/template.js.map +1 -1
  169. package/dist/src/platforms/wechatbot/commands/user.d.ts.map +1 -1
  170. package/dist/src/platforms/wechatbot/commands/user.js +1 -6
  171. package/dist/src/platforms/wechatbot/commands/user.js.map +1 -1
  172. package/dist/src/platforms/wechatbot/commands/whoami.d.ts.map +1 -1
  173. package/dist/src/platforms/wechatbot/commands/whoami.js +1 -6
  174. package/dist/src/platforms/wechatbot/commands/whoami.js.map +1 -1
  175. package/dist/src/platforms/whatsappbot/cli.d.ts.map +1 -1
  176. package/dist/src/platforms/whatsappbot/cli.js +11 -1
  177. package/dist/src/platforms/whatsappbot/cli.js.map +1 -1
  178. package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
  179. package/dist/src/platforms/whatsappbot/commands/auth.js +1 -5
  180. package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
  181. package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
  182. package/dist/src/platforms/whatsappbot/commands/message.js +1 -6
  183. package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
  184. package/dist/src/platforms/whatsappbot/commands/template.d.ts.map +1 -1
  185. package/dist/src/platforms/whatsappbot/commands/template.js +1 -6
  186. package/dist/src/platforms/whatsappbot/commands/template.js.map +1 -1
  187. package/dist/src/platforms/whatsappbot/commands/whoami.d.ts.map +1 -1
  188. package/dist/src/platforms/whatsappbot/commands/whoami.js +1 -6
  189. package/dist/src/platforms/whatsappbot/commands/whoami.js.map +1 -1
  190. package/dist/src/shared/chromium/browsers.d.ts +8 -0
  191. package/dist/src/shared/chromium/browsers.d.ts.map +1 -1
  192. package/dist/src/shared/chromium/browsers.js +58 -3
  193. package/dist/src/shared/chromium/browsers.js.map +1 -1
  194. package/dist/src/shared/chromium/cli-options.d.ts +5 -0
  195. package/dist/src/shared/chromium/cli-options.d.ts.map +1 -0
  196. package/dist/src/shared/chromium/cli-options.js +8 -0
  197. package/dist/src/shared/chromium/cli-options.js.map +1 -0
  198. package/dist/src/shared/chromium/decryptor.d.ts +6 -0
  199. package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
  200. package/dist/src/shared/chromium/decryptor.js +26 -6
  201. package/dist/src/shared/chromium/decryptor.js.map +1 -1
  202. package/dist/src/shared/chromium/index.d.ts +3 -1
  203. package/dist/src/shared/chromium/index.d.ts.map +1 -1
  204. package/dist/src/shared/chromium/index.js +2 -1
  205. package/dist/src/shared/chromium/index.js.map +1 -1
  206. package/dist/src/shared/utils/cli-output.d.ts +7 -0
  207. package/dist/src/shared/utils/cli-output.d.ts.map +1 -0
  208. package/dist/src/shared/utils/cli-output.js +7 -0
  209. package/dist/src/shared/utils/cli-output.js.map +1 -0
  210. package/dist/src/tui/app.d.ts.map +1 -1
  211. package/dist/src/tui/app.js +73 -20
  212. package/dist/src/tui/app.js.map +1 -1
  213. package/docs/content/docs/cli/channeltalk.mdx +4 -0
  214. package/docs/content/docs/cli/discord.mdx +5 -0
  215. package/docs/content/docs/cli/instagram.mdx +3 -0
  216. package/docs/content/docs/cli/slack.mdx +5 -0
  217. package/docs/content/docs/cli/slackbot.mdx +60 -22
  218. package/docs/content/docs/cli/teams.mdx +5 -0
  219. package/docs/content/docs/cli/webex.mdx +3 -0
  220. package/docs/content/docs/sdk/channeltalkbot.mdx +38 -1
  221. package/docs/content/docs/sdk/discordbot.mdx +501 -0
  222. package/docs/content/docs/sdk/meta.json +2 -0
  223. package/docs/content/docs/sdk/slackbot.mdx +576 -0
  224. package/e2e/README.md +1 -1
  225. package/e2e/channeltalk.e2e.test.ts +13 -13
  226. package/e2e/channeltalkbot.e2e.test.ts +13 -13
  227. package/e2e/config.ts +9 -4
  228. package/e2e/discord.e2e.test.ts +24 -24
  229. package/e2e/discordbot.e2e.test.ts +16 -16
  230. package/e2e/instagram.e2e.test.ts +10 -10
  231. package/e2e/kakaotalk.e2e.test.ts +7 -7
  232. package/e2e/line.e2e.test.ts +8 -8
  233. package/e2e/slack.e2e.test.ts +34 -34
  234. package/e2e/slackbot.e2e.test.ts +14 -14
  235. package/e2e/teams.e2e.test.ts +23 -23
  236. package/e2e/telegram.e2e.test.ts +8 -8
  237. package/e2e/webex.e2e.test.ts +14 -14
  238. package/e2e/whatsapp.e2e.test.ts +8 -8
  239. package/e2e/whatsappbot.e2e.test.ts +6 -6
  240. package/examples/discordbot-listen.ts +65 -0
  241. package/examples/slackbot-listen.ts +65 -0
  242. package/package.json +14 -1
  243. package/skills/agent-channeltalk/SKILL.md +5 -1
  244. package/skills/agent-channeltalk/references/authentication.md +5 -1
  245. package/skills/agent-channeltalkbot/SKILL.md +17 -3
  246. package/skills/agent-channeltalkbot/references/authentication.md +7 -5
  247. package/skills/agent-discord/SKILL.md +5 -1
  248. package/skills/agent-discord/references/authentication.md +7 -1
  249. package/skills/agent-discordbot/SKILL.md +13 -2
  250. package/skills/agent-discordbot/references/common-patterns.md +1 -1
  251. package/skills/agent-instagram/SKILL.md +7 -1
  252. package/skills/agent-instagram/references/authentication.md +6 -0
  253. package/skills/agent-kakaotalk/SKILL.md +1 -1
  254. package/skills/agent-line/SKILL.md +1 -1
  255. package/skills/agent-slack/SKILL.md +5 -1
  256. package/skills/agent-slack/references/authentication.md +7 -1
  257. package/skills/agent-slackbot/SKILL.md +56 -4
  258. package/skills/agent-slackbot/references/authentication.md +4 -0
  259. package/skills/agent-teams/SKILL.md +5 -1
  260. package/skills/agent-teams/references/authentication.md +7 -1
  261. package/skills/agent-telegram/SKILL.md +1 -1
  262. package/skills/agent-webex/SKILL.md +7 -1
  263. package/skills/agent-webex/references/authentication.md +6 -0
  264. package/skills/agent-wechatbot/SKILL.md +16 -1
  265. package/skills/agent-wechatbot/references/authentication.md +219 -0
  266. package/skills/agent-wechatbot/references/common-patterns.md +358 -0
  267. package/skills/agent-wechatbot/templates/account-summary.sh +122 -0
  268. package/skills/agent-wechatbot/templates/post-message.sh +122 -0
  269. package/skills/agent-wechatbot/templates/send-template.sh +152 -0
  270. package/skills/agent-whatsapp/SKILL.md +1 -1
  271. package/skills/agent-whatsappbot/SKILL.md +30 -1
  272. package/src/platforms/channeltalk/client.test.ts +26 -26
  273. package/src/platforms/channeltalk/commands/auth.test.ts +31 -19
  274. package/src/platforms/channeltalk/commands/auth.ts +15 -5
  275. package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
  276. package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
  277. package/src/platforms/channeltalk/commands/group.test.ts +4 -4
  278. package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
  279. package/src/platforms/channeltalk/commands/message.test.ts +17 -17
  280. package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
  281. package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
  282. package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
  283. package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
  284. package/src/platforms/channeltalk/index.test.ts +23 -23
  285. package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
  286. package/src/platforms/channeltalk/token-extractor.ts +24 -5
  287. package/src/platforms/channeltalk/types.test.ts +12 -12
  288. package/src/platforms/channeltalkbot/cli.ts +9 -0
  289. package/src/platforms/channeltalkbot/client.test.ts +14 -14
  290. package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
  291. package/src/platforms/channeltalkbot/commands/auth.ts +1 -5
  292. package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
  293. package/src/platforms/channeltalkbot/commands/bot.ts +1 -6
  294. package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
  295. package/src/platforms/channeltalkbot/commands/chat.ts +1 -6
  296. package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
  297. package/src/platforms/channeltalkbot/commands/group.ts +1 -6
  298. package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
  299. package/src/platforms/channeltalkbot/commands/manager.ts +1 -6
  300. package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
  301. package/src/platforms/channeltalkbot/commands/message.ts +1 -6
  302. package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
  303. package/src/platforms/channeltalkbot/commands/whoami.test.ts +6 -4
  304. package/src/platforms/channeltalkbot/commands/whoami.ts +1 -6
  305. package/src/platforms/channeltalkbot/credential-manager.test.ts +123 -29
  306. package/src/platforms/channeltalkbot/credential-manager.ts +37 -4
  307. package/src/platforms/channeltalkbot/index.test.ts +15 -15
  308. package/src/platforms/discord/client.test.ts +28 -28
  309. package/src/platforms/discord/commands/auth.test.ts +7 -7
  310. package/src/platforms/discord/commands/auth.ts +13 -2
  311. package/src/platforms/discord/commands/channel.test.ts +7 -7
  312. package/src/platforms/discord/commands/dm.test.ts +4 -4
  313. package/src/platforms/discord/commands/file.test.ts +4 -4
  314. package/src/platforms/discord/commands/friend.test.ts +6 -6
  315. package/src/platforms/discord/commands/member.test.ts +5 -5
  316. package/src/platforms/discord/commands/mention.test.ts +5 -5
  317. package/src/platforms/discord/commands/message.test.ts +9 -9
  318. package/src/platforms/discord/commands/note.test.ts +6 -6
  319. package/src/platforms/discord/commands/profile.test.ts +4 -4
  320. package/src/platforms/discord/commands/reaction.test.ts +5 -5
  321. package/src/platforms/discord/commands/server.test.ts +7 -7
  322. package/src/platforms/discord/commands/snapshot.test.ts +6 -6
  323. package/src/platforms/discord/commands/thread.test.ts +6 -6
  324. package/src/platforms/discord/commands/user.test.ts +5 -5
  325. package/src/platforms/discord/commands/whoami.test.ts +6 -6
  326. package/src/platforms/discord/credential-manager.test.ts +16 -16
  327. package/src/platforms/discord/ensure-auth.test.ts +8 -8
  328. package/src/platforms/discord/index.test.ts +17 -17
  329. package/src/platforms/discord/listener.test.ts +92 -34
  330. package/src/platforms/discord/listener.ts +43 -19
  331. package/src/platforms/discord/token-extractor.test.ts +53 -53
  332. package/src/platforms/discord/token-extractor.ts +30 -6
  333. package/src/platforms/discord/types.test.ts +26 -26
  334. package/src/platforms/discordbot/cli.ts +10 -0
  335. package/src/platforms/discordbot/client.test.ts +31 -31
  336. package/src/platforms/discordbot/client.ts +4 -0
  337. package/src/platforms/discordbot/commands/auth.test.ts +18 -18
  338. package/src/platforms/discordbot/commands/auth.ts +1 -5
  339. package/src/platforms/discordbot/commands/channel.test.ts +11 -11
  340. package/src/platforms/discordbot/commands/file.test.ts +7 -7
  341. package/src/platforms/discordbot/commands/message.test.ts +25 -25
  342. package/src/platforms/discordbot/commands/message.ts +1 -6
  343. package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
  344. package/src/platforms/discordbot/commands/server.test.ts +12 -12
  345. package/src/platforms/discordbot/commands/server.ts +1 -5
  346. package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
  347. package/src/platforms/discordbot/commands/thread.test.ts +10 -10
  348. package/src/platforms/discordbot/commands/user.test.ts +9 -9
  349. package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
  350. package/src/platforms/discordbot/commands/whoami.ts +1 -6
  351. package/src/platforms/discordbot/credential-manager.test.ts +28 -28
  352. package/src/platforms/discordbot/index.test.ts +82 -0
  353. package/src/platforms/discordbot/index.ts +27 -9
  354. package/src/platforms/discordbot/listener.test.ts +1002 -0
  355. package/src/platforms/discordbot/listener.ts +321 -0
  356. package/src/platforms/discordbot/types.ts +163 -0
  357. package/src/platforms/instagram/client.test.ts +18 -18
  358. package/src/platforms/instagram/commands/auth.test.ts +11 -11
  359. package/src/platforms/instagram/commands/auth.ts +9 -1
  360. package/src/platforms/instagram/commands/chat.test.ts +6 -6
  361. package/src/platforms/instagram/commands/message.test.ts +11 -11
  362. package/src/platforms/instagram/commands/shared.test.ts +12 -12
  363. package/src/platforms/instagram/commands/whoami.test.ts +3 -3
  364. package/src/platforms/instagram/credential-manager.test.ts +21 -21
  365. package/src/platforms/instagram/ensure-auth.test.ts +4 -4
  366. package/src/platforms/instagram/index.test.ts +9 -9
  367. package/src/platforms/instagram/listener.test.ts +8 -8
  368. package/src/platforms/instagram/token-extractor.test.ts +35 -35
  369. package/src/platforms/instagram/token-extractor.ts +13 -1
  370. package/src/platforms/kakaotalk/client.test.ts +33 -33
  371. package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
  372. package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
  373. package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
  374. package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
  375. package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
  376. package/src/platforms/kakaotalk/index.test.ts +15 -15
  377. package/src/platforms/kakaotalk/listener.test.ts +17 -17
  378. package/src/platforms/line/client.test.ts +17 -17
  379. package/src/platforms/line/commands/auth.test.ts +8 -8
  380. package/src/platforms/line/commands/chat.test.ts +7 -7
  381. package/src/platforms/line/commands/friend.test.ts +6 -6
  382. package/src/platforms/line/commands/message.test.ts +7 -7
  383. package/src/platforms/line/commands/whoami.test.ts +6 -6
  384. package/src/platforms/line/credential-manager.test.ts +17 -17
  385. package/src/platforms/line/index.test.ts +10 -10
  386. package/src/platforms/line/listener.test.ts +15 -15
  387. package/src/platforms/line/types.test.ts +14 -14
  388. package/src/platforms/slack/cli.test.ts +8 -8
  389. package/src/platforms/slack/client.test.ts +151 -151
  390. package/src/platforms/slack/commands/activity.test.ts +13 -13
  391. package/src/platforms/slack/commands/auth.test.ts +34 -34
  392. package/src/platforms/slack/commands/auth.ts +11 -2
  393. package/src/platforms/slack/commands/bookmark.test.ts +9 -9
  394. package/src/platforms/slack/commands/channel.test.ts +17 -17
  395. package/src/platforms/slack/commands/drafts.test.ts +7 -7
  396. package/src/platforms/slack/commands/emoji.test.ts +3 -3
  397. package/src/platforms/slack/commands/file.test.ts +12 -12
  398. package/src/platforms/slack/commands/message.test.ts +19 -19
  399. package/src/platforms/slack/commands/pin.test.ts +7 -7
  400. package/src/platforms/slack/commands/reaction.test.ts +10 -10
  401. package/src/platforms/slack/commands/reminder.test.ts +9 -9
  402. package/src/platforms/slack/commands/saved.test.ts +7 -7
  403. package/src/platforms/slack/commands/sections.test.ts +5 -5
  404. package/src/platforms/slack/commands/snapshot.test.ts +13 -13
  405. package/src/platforms/slack/commands/unread.test.ts +6 -6
  406. package/src/platforms/slack/commands/user.test.ts +10 -10
  407. package/src/platforms/slack/commands/usergroup.test.ts +15 -15
  408. package/src/platforms/slack/commands/whoami.test.ts +6 -6
  409. package/src/platforms/slack/commands/workspace.test.ts +26 -26
  410. package/src/platforms/slack/credential-manager.test.ts +14 -14
  411. package/src/platforms/slack/ensure-auth.test.ts +21 -21
  412. package/src/platforms/slack/index.test.ts +12 -12
  413. package/src/platforms/slack/listener.test.ts +17 -17
  414. package/src/platforms/slack/token-extractor-node.test.ts +2 -2
  415. package/src/platforms/slack/token-extractor.test.ts +133 -37
  416. package/src/platforms/slack/token-extractor.ts +76 -13
  417. package/src/platforms/slack/types.test.ts +21 -21
  418. package/src/platforms/slackbot/cli.ts +13 -1
  419. package/src/platforms/slackbot/client.test.ts +296 -22
  420. package/src/platforms/slackbot/client.ts +130 -2
  421. package/src/platforms/slackbot/commands/auth.test.ts +14 -14
  422. package/src/platforms/slackbot/commands/auth.ts +1 -5
  423. package/src/platforms/slackbot/commands/channel.test.ts +7 -7
  424. package/src/platforms/slackbot/commands/file.test.ts +201 -0
  425. package/src/platforms/slackbot/commands/file.ts +212 -0
  426. package/src/platforms/slackbot/commands/index.ts +1 -0
  427. package/src/platforms/slackbot/commands/message.test.ts +13 -13
  428. package/src/platforms/slackbot/commands/message.ts +22 -0
  429. package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
  430. package/src/platforms/slackbot/commands/user.test.ts +7 -7
  431. package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
  432. package/src/platforms/slackbot/commands/whoami.ts +1 -6
  433. package/src/platforms/slackbot/credential-manager.test.ts +83 -23
  434. package/src/platforms/slackbot/credential-manager.ts +32 -2
  435. package/src/platforms/slackbot/index.test.ts +59 -0
  436. package/src/platforms/slackbot/index.ts +31 -7
  437. package/src/platforms/slackbot/listener.test.ts +1012 -0
  438. package/src/platforms/slackbot/listener.ts +362 -0
  439. package/src/platforms/slackbot/types.test.ts +7 -7
  440. package/src/platforms/slackbot/types.ts +224 -1
  441. package/src/platforms/teams/client.test.ts +30 -30
  442. package/src/platforms/teams/commands/auth.test.ts +9 -9
  443. package/src/platforms/teams/commands/auth.ts +66 -7
  444. package/src/platforms/teams/commands/channel.test.ts +7 -7
  445. package/src/platforms/teams/commands/file.test.ts +4 -4
  446. package/src/platforms/teams/commands/message.test.ts +5 -5
  447. package/src/platforms/teams/commands/reaction.test.ts +4 -4
  448. package/src/platforms/teams/commands/snapshot.test.ts +7 -7
  449. package/src/platforms/teams/commands/team.test.ts +8 -8
  450. package/src/platforms/teams/commands/user.test.ts +4 -4
  451. package/src/platforms/teams/commands/whoami.test.ts +6 -6
  452. package/src/platforms/teams/credential-manager.test.ts +17 -17
  453. package/src/platforms/teams/ensure-auth.test.ts +69 -18
  454. package/src/platforms/teams/ensure-auth.ts +39 -11
  455. package/src/platforms/teams/index.test.ts +15 -15
  456. package/src/platforms/teams/token-extractor.test.ts +251 -69
  457. package/src/platforms/teams/token-extractor.ts +94 -31
  458. package/src/platforms/teams/types.test.ts +26 -26
  459. package/src/platforms/telegram/app-config.test.ts +4 -4
  460. package/src/platforms/telegram/chat-utils.test.ts +12 -12
  461. package/src/platforms/telegram/client.test.ts +4 -4
  462. package/src/platforms/telegram/commands/auth.test.ts +16 -16
  463. package/src/platforms/telegram/commands/chat.test.ts +9 -9
  464. package/src/platforms/telegram/commands/message.test.ts +6 -6
  465. package/src/platforms/telegram/commands/shared.test.ts +3 -3
  466. package/src/platforms/telegram/commands/whoami.test.ts +3 -3
  467. package/src/platforms/telegram/credential-manager.test.ts +10 -10
  468. package/src/platforms/telegram/types.test.ts +6 -6
  469. package/src/platforms/webex/app-config.test.ts +8 -8
  470. package/src/platforms/webex/cli.test.ts +5 -5
  471. package/src/platforms/webex/client.test.ts +65 -65
  472. package/src/platforms/webex/commands/auth.test.ts +18 -18
  473. package/src/platforms/webex/commands/auth.ts +13 -2
  474. package/src/platforms/webex/commands/member.test.ts +5 -5
  475. package/src/platforms/webex/commands/message.test.ts +12 -12
  476. package/src/platforms/webex/commands/snapshot.test.ts +5 -5
  477. package/src/platforms/webex/commands/space.test.ts +10 -10
  478. package/src/platforms/webex/commands/whoami.test.ts +6 -6
  479. package/src/platforms/webex/credential-manager.test.ts +22 -22
  480. package/src/platforms/webex/encryption.test.ts +4 -4
  481. package/src/platforms/webex/ensure-auth.test.ts +5 -5
  482. package/src/platforms/webex/index.test.ts +5 -5
  483. package/src/platforms/webex/markdown-to-html.test.ts +33 -33
  484. package/src/platforms/webex/token-extractor.test.ts +23 -23
  485. package/src/platforms/webex/token-extractor.ts +25 -3
  486. package/src/platforms/webex/types.test.ts +27 -27
  487. package/src/platforms/wechatbot/cli.ts +9 -0
  488. package/src/platforms/wechatbot/client.test.ts +27 -27
  489. package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
  490. package/src/platforms/wechatbot/commands/auth.ts +1 -5
  491. package/src/platforms/wechatbot/commands/message.test.ts +8 -8
  492. package/src/platforms/wechatbot/commands/message.ts +1 -6
  493. package/src/platforms/wechatbot/commands/template.test.ts +9 -9
  494. package/src/platforms/wechatbot/commands/template.ts +1 -6
  495. package/src/platforms/wechatbot/commands/user.test.ts +7 -7
  496. package/src/platforms/wechatbot/commands/user.ts +1 -6
  497. package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
  498. package/src/platforms/wechatbot/commands/whoami.ts +1 -6
  499. package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
  500. package/src/platforms/wechatbot/index.test.ts +10 -10
  501. package/src/platforms/wechatbot/types.test.ts +25 -25
  502. package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
  503. package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
  504. package/src/platforms/whatsapp/commands/message.test.ts +10 -10
  505. package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
  506. package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
  507. package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
  508. package/src/platforms/whatsapp/index.test.ts +8 -8
  509. package/src/platforms/whatsapp/types.test.ts +42 -42
  510. package/src/platforms/whatsappbot/cli.ts +9 -0
  511. package/src/platforms/whatsappbot/client.test.ts +27 -27
  512. package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
  513. package/src/platforms/whatsappbot/commands/auth.ts +1 -5
  514. package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
  515. package/src/platforms/whatsappbot/commands/message.ts +1 -6
  516. package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
  517. package/src/platforms/whatsappbot/commands/template.ts +1 -6
  518. package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
  519. package/src/platforms/whatsappbot/commands/whoami.ts +1 -6
  520. package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
  521. package/src/platforms/whatsappbot/index.test.ts +7 -7
  522. package/src/platforms/whatsappbot/types.test.ts +18 -18
  523. package/src/shared/chromium/browsers.test.ts +102 -22
  524. package/src/shared/chromium/browsers.ts +72 -3
  525. package/src/shared/chromium/cli-options.test.ts +22 -0
  526. package/src/shared/chromium/cli-options.ts +12 -0
  527. package/src/shared/chromium/cookie-reader.test.ts +13 -13
  528. package/src/shared/chromium/decryptor.test.ts +97 -32
  529. package/src/shared/chromium/decryptor.ts +27 -6
  530. package/src/shared/chromium/index.ts +3 -0
  531. package/src/shared/utils/cli-output.test.ts +57 -0
  532. package/src/shared/utils/cli-output.ts +8 -0
  533. package/src/shared/utils/concurrency.test.ts +6 -6
  534. package/src/shared/utils/derived-key-cache.test.ts +11 -11
  535. package/src/tui/app.ts +129 -20
  536. package/src/tui/utils.test.ts +31 -31
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
2
  import { existsSync, mkdtempSync, rmSync } from 'node:fs'
3
3
  import { stat } from 'node:fs/promises'
4
4
  import { tmpdir } from 'node:os'
@@ -42,14 +42,14 @@ describe('ChannelCredentialManager', () => {
42
42
  delete process.env.E2E_CHANNEL_WORKSPACE_ID
43
43
  })
44
44
 
45
- test('returns empty config when no file exists', async () => {
45
+ it('returns empty config when no file exists', async () => {
46
46
  const config = await manager.load()
47
47
 
48
48
  expect(config.current).toBeNull()
49
49
  expect(config.workspaces).toEqual({})
50
50
  })
51
51
 
52
- test('persists config to file', async () => {
52
+ it('persists config to file', async () => {
53
53
  const config = {
54
54
  current: { workspace_id: '232986' },
55
55
  workspaces: {
@@ -63,11 +63,11 @@ describe('ChannelCredentialManager', () => {
63
63
  expect(loaded).toEqual(config)
64
64
  })
65
65
 
66
- test('returns null when no credentials exist', async () => {
66
+ it('returns null when no credentials exist', async () => {
67
67
  expect(await manager.getCredentials()).toBeNull()
68
68
  })
69
69
 
70
- test('returns current workspace credentials', async () => {
70
+ it('returns current workspace credentials', async () => {
71
71
  await manager.setCredentials(WORKSPACE_A)
72
72
 
73
73
  expect(await manager.getCredentials()).toEqual({
@@ -78,7 +78,7 @@ describe('ChannelCredentialManager', () => {
78
78
  })
79
79
  })
80
80
 
81
- test('returns specific workspace by id', async () => {
81
+ it('returns specific workspace by id', async () => {
82
82
  await manager.setCredentials(WORKSPACE_A)
83
83
  await manager.setCredentials(WORKSPACE_B)
84
84
 
@@ -90,13 +90,13 @@ describe('ChannelCredentialManager', () => {
90
90
  })
91
91
  })
92
92
 
93
- test('returns null for unknown workspace id', async () => {
93
+ it('returns null for unknown workspace id', async () => {
94
94
  await manager.setCredentials(WORKSPACE_A)
95
95
 
96
96
  expect(await manager.getCredentials('missing')).toBeNull()
97
97
  })
98
98
 
99
- test('env vars take precedence when no workspace id is specified', async () => {
99
+ it('env vars take precedence when no workspace id is specified', async () => {
100
100
  await manager.setCredentials(WORKSPACE_A)
101
101
 
102
102
  process.env.E2E_CHANNEL_ACCOUNT_COOKIE = 'env-account-cookie'
@@ -111,7 +111,7 @@ describe('ChannelCredentialManager', () => {
111
111
  })
112
112
  })
113
113
 
114
- test('env vars are ignored when a workspace id is explicitly provided', async () => {
114
+ it('env vars are ignored when a workspace id is explicitly provided', async () => {
115
115
  await manager.setCredentials(WORKSPACE_A)
116
116
 
117
117
  process.env.E2E_CHANNEL_ACCOUNT_COOKIE = 'env-account-cookie'
@@ -126,7 +126,7 @@ describe('ChannelCredentialManager', () => {
126
126
  })
127
127
  })
128
128
 
129
- test('stores multiple workspaces and marks the latest current', async () => {
129
+ it('stores multiple workspaces and marks the latest current', async () => {
130
130
  await manager.setCredentials(WORKSPACE_A)
131
131
  await manager.setCredentials(WORKSPACE_B)
132
132
 
@@ -136,7 +136,7 @@ describe('ChannelCredentialManager', () => {
136
136
  expect(config.current).toEqual({ workspace_id: '232987' })
137
137
  })
138
138
 
139
- test('lists all workspaces with current flag', async () => {
139
+ it('lists all workspaces with current flag', async () => {
140
140
  await manager.setCredentials(WORKSPACE_A)
141
141
  await manager.setCredentials(WORKSPACE_B)
142
142
 
@@ -147,7 +147,7 @@ describe('ChannelCredentialManager', () => {
147
147
  expect(all.find((workspace) => workspace.workspace_id === '232987')?.is_current).toBe(true)
148
148
  })
149
149
 
150
- test('switches current workspace', async () => {
150
+ it('switches current workspace', async () => {
151
151
  await manager.setCredentials(WORKSPACE_A)
152
152
  await manager.setCredentials(WORKSPACE_B)
153
153
 
@@ -160,11 +160,11 @@ describe('ChannelCredentialManager', () => {
160
160
  })
161
161
  })
162
162
 
163
- test('returns false when setting an unknown current workspace', async () => {
163
+ it('returns false when setting an unknown current workspace', async () => {
164
164
  expect(await manager.setCurrent('missing')).toBe(false)
165
165
  })
166
166
 
167
- test('removes a workspace by id', async () => {
167
+ it('removes a workspace by id', async () => {
168
168
  await manager.setCredentials(WORKSPACE_A)
169
169
  await manager.setCredentials(WORKSPACE_B)
170
170
 
@@ -172,7 +172,7 @@ describe('ChannelCredentialManager', () => {
172
172
  expect(await manager.listAll()).toHaveLength(1)
173
173
  })
174
174
 
175
- test('clears current when current workspace is removed', async () => {
175
+ it('clears current when current workspace is removed', async () => {
176
176
  await manager.setCredentials(WORKSPACE_A)
177
177
 
178
178
  await manager.removeWorkspace(WORKSPACE_A.workspace_id)
@@ -181,11 +181,11 @@ describe('ChannelCredentialManager', () => {
181
181
  expect(config.current).toBeNull()
182
182
  })
183
183
 
184
- test('returns false when removing an unknown workspace', async () => {
184
+ it('returns false when removing an unknown workspace', async () => {
185
185
  expect(await manager.removeWorkspace('missing')).toBe(false)
186
186
  })
187
187
 
188
- test('clears all credentials', async () => {
188
+ it('clears all credentials', async () => {
189
189
  await manager.setCredentials(WORKSPACE_A)
190
190
  await manager.setCredentials(WORKSPACE_B)
191
191
 
@@ -196,7 +196,7 @@ describe('ChannelCredentialManager', () => {
196
196
  expect(config.workspaces).toEqual({})
197
197
  })
198
198
 
199
- test('saves file with secure permissions', async () => {
199
+ it('saves file with secure permissions', async () => {
200
200
  await manager.setCredentials(WORKSPACE_A)
201
201
 
202
202
  const credentialsPath = join(tempDir, 'channel-credentials.json')
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from 'bun:test'
1
+ import { afterAll, beforeEach, describe, expect, mock, it } from 'bun:test'
2
2
 
3
3
  import {
4
4
  ensureChannelAuth,
@@ -62,7 +62,7 @@ describe('ensureChannelAuth', () => {
62
62
  mockListChannels.mockImplementation(() => Promise.resolve([{ id: 'ws-1', name: 'Workspace 1' }]))
63
63
  })
64
64
 
65
- test('extracts and saves workspaces when no credentials exist', async () => {
65
+ it('extracts and saves workspaces when no credentials exist', async () => {
66
66
  mockExtract.mockImplementation(() =>
67
67
  Promise.resolve([
68
68
  {
@@ -101,7 +101,7 @@ describe('ensureChannelAuth', () => {
101
101
  expect(mockSetCurrent).toHaveBeenCalledWith('ws-1')
102
102
  })
103
103
 
104
- test('returns early when stored credentials are valid', async () => {
104
+ it('returns early when stored credentials are valid', async () => {
105
105
  mockGetCredentials.mockImplementation(() =>
106
106
  Promise.resolve({
107
107
  workspace_id: 'ws-1',
@@ -118,7 +118,7 @@ describe('ensureChannelAuth', () => {
118
118
  expect(mockSetCredentials).not.toHaveBeenCalled()
119
119
  })
120
120
 
121
- test('re-extracts when stored credentials are invalid', async () => {
121
+ it('re-extracts when stored credentials are invalid', async () => {
122
122
  mockGetCredentials.mockImplementation(() =>
123
123
  Promise.resolve({
124
124
  workspace_id: 'ws-1',
@@ -148,7 +148,7 @@ describe('ensureChannelAuth', () => {
148
148
  expect(mockSetCurrent).toHaveBeenCalledWith('ws-1')
149
149
  })
150
150
 
151
- test('returns gracefully when extractor yields no cookies', async () => {
151
+ it('returns gracefully when extractor yields no cookies', async () => {
152
152
  await ensureChannelAuth()
153
153
 
154
154
  expect(mockExtract).toHaveBeenCalledTimes(1)
@@ -1,4 +1,4 @@
1
- import { expect, test } from 'bun:test'
1
+ import { expect, it } from 'bun:test'
2
2
 
3
3
  import {
4
4
  BlockInlineAttrsSchema,
@@ -25,90 +25,90 @@ import {
25
25
  MessageBlockSchema,
26
26
  } from '@/platforms/channeltalk/index'
27
27
 
28
- test('ChannelClient is exported from barrel', () => {
28
+ it('ChannelClient is exported from barrel', () => {
29
29
  expect(typeof ChannelClient).toBe('function')
30
30
  })
31
31
 
32
- test('ChannelError is exported from barrel', () => {
32
+ it('ChannelError is exported from barrel', () => {
33
33
  expect(typeof ChannelError).toBe('function')
34
34
  })
35
35
 
36
- test('ChannelCredentialManager is exported from barrel', () => {
36
+ it('ChannelCredentialManager is exported from barrel', () => {
37
37
  expect(typeof ChannelCredentialManager).toBe('function')
38
38
  })
39
39
 
40
- test('ChannelSchema is exported from barrel', () => {
40
+ it('ChannelSchema is exported from barrel', () => {
41
41
  expect(typeof ChannelSchema.parse).toBe('function')
42
42
  })
43
43
 
44
- test('ChannelAccountSchema is exported from barrel', () => {
44
+ it('ChannelAccountSchema is exported from barrel', () => {
45
45
  expect(typeof ChannelAccountSchema.parse).toBe('function')
46
46
  })
47
47
 
48
- test('ChannelBotSchema is exported from barrel', () => {
48
+ it('ChannelBotSchema is exported from barrel', () => {
49
49
  expect(typeof ChannelBotSchema.parse).toBe('function')
50
50
  })
51
51
 
52
- test('ChannelConfigSchema is exported from barrel', () => {
52
+ it('ChannelConfigSchema is exported from barrel', () => {
53
53
  expect(typeof ChannelConfigSchema.parse).toBe('function')
54
54
  })
55
55
 
56
- test('ChannelCredentialsSchema is exported from barrel', () => {
56
+ it('ChannelCredentialsSchema is exported from barrel', () => {
57
57
  expect(typeof ChannelCredentialsSchema.parse).toBe('function')
58
58
  })
59
59
 
60
- test('ChannelDirectChatSchema is exported from barrel', () => {
60
+ it('ChannelDirectChatSchema is exported from barrel', () => {
61
61
  expect(typeof ChannelDirectChatSchema.parse).toBe('function')
62
62
  })
63
63
 
64
- test('ChannelGroupSchema is exported from barrel', () => {
64
+ it('ChannelGroupSchema is exported from barrel', () => {
65
65
  expect(typeof ChannelGroupSchema.parse).toBe('function')
66
66
  })
67
67
 
68
- test('ChannelManagerSchema is exported from barrel', () => {
68
+ it('ChannelManagerSchema is exported from barrel', () => {
69
69
  expect(typeof ChannelManagerSchema.parse).toBe('function')
70
70
  })
71
71
 
72
- test('ChannelMessageSchema is exported from barrel', () => {
72
+ it('ChannelMessageSchema is exported from barrel', () => {
73
73
  expect(typeof ChannelMessageSchema.parse).toBe('function')
74
74
  })
75
75
 
76
- test('ChannelSessionSchema is exported from barrel', () => {
76
+ it('ChannelSessionSchema is exported from barrel', () => {
77
77
  expect(typeof ChannelSessionSchema.parse).toBe('function')
78
78
  })
79
79
 
80
- test('ChannelUserChatSchema is exported from barrel', () => {
80
+ it('ChannelUserChatSchema is exported from barrel', () => {
81
81
  expect(typeof ChannelUserChatSchema.parse).toBe('function')
82
82
  })
83
83
 
84
- test('ChannelWorkspaceEntrySchema is exported from barrel', () => {
84
+ it('ChannelWorkspaceEntrySchema is exported from barrel', () => {
85
85
  expect(typeof ChannelWorkspaceEntrySchema.parse).toBe('function')
86
86
  })
87
87
 
88
- test('ChannelSearchHighlightSchema is exported from barrel', () => {
88
+ it('ChannelSearchHighlightSchema is exported from barrel', () => {
89
89
  expect(typeof ChannelSearchHighlightSchema.parse).toBe('function')
90
90
  })
91
91
 
92
- test('ChannelSearchHitSchema is exported from barrel', () => {
92
+ it('ChannelSearchHitSchema is exported from barrel', () => {
93
93
  expect(typeof ChannelSearchHitSchema.parse).toBe('function')
94
94
  })
95
95
 
96
- test('ChannelSearchResponseSchema is exported from barrel', () => {
96
+ it('ChannelSearchResponseSchema is exported from barrel', () => {
97
97
  expect(typeof ChannelSearchResponseSchema.parse).toBe('function')
98
98
  })
99
99
 
100
- test('ExtractedChannelTokenSchema is exported from barrel', () => {
100
+ it('ExtractedChannelTokenSchema is exported from barrel', () => {
101
101
  expect(typeof ExtractedChannelTokenSchema.parse).toBe('function')
102
102
  })
103
103
 
104
- test('MessageBlockSchema is exported from barrel', () => {
104
+ it('MessageBlockSchema is exported from barrel', () => {
105
105
  expect(typeof MessageBlockSchema.parse).toBe('function')
106
106
  })
107
107
 
108
- test('BlockInlineSchema is exported from barrel', () => {
108
+ it('BlockInlineSchema is exported from barrel', () => {
109
109
  expect(typeof BlockInlineSchema.parse).toBe('function')
110
110
  })
111
111
 
112
- test('BlockInlineAttrsSchema is exported from barrel', () => {
112
+ it('BlockInlineAttrsSchema is exported from barrel', () => {
113
113
  expect(typeof BlockInlineAttrsSchema.parse).toBe('function')
114
114
  })
@@ -1,4 +1,4 @@
1
- import { afterEach, describe, expect, spyOn, test } from 'bun:test'
1
+ import { afterEach, describe, expect, spyOn, it } from 'bun:test'
2
2
  import { createCipheriv, randomBytes } from 'node:crypto'
3
3
  import { existsSync, mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
4
4
  import { tmpdir } from 'node:os'
@@ -18,19 +18,19 @@ describe('ChannelTokenExtractor', () => {
18
18
  })
19
19
 
20
20
  describe('getAppDataDir', () => {
21
- test('returns null for unsupported platform', () => {
21
+ it('returns null for unsupported platform', () => {
22
22
  const extractor = new ChannelTokenExtractor('freebsd' as NodeJS.Platform)
23
23
  expect(extractor.getAppDataDir()).toBeNull()
24
24
  })
25
25
  })
26
26
 
27
27
  describe('getCookiesPath', () => {
28
- test('returns null for unsupported platform', () => {
28
+ it('returns null for unsupported platform', () => {
29
29
  const extractor = new ChannelTokenExtractor('freebsd' as NodeJS.Platform)
30
30
  expect(extractor.getCookiesPath()).toBeNull()
31
31
  })
32
32
 
33
- test('returns win32 path under AppData/Roaming/Channel Talk/Network', () => {
33
+ it('returns win32 path under AppData/Roaming/Channel Talk/Network', () => {
34
34
  // given
35
35
  const tempDir = mkdtempSync(join(tmpdir(), 'channel-win-'))
36
36
  tempDirs.push(tempDir)
@@ -58,7 +58,7 @@ describe('ChannelTokenExtractor', () => {
58
58
  })
59
59
 
60
60
  describe('getBrowserCookiesPaths', () => {
61
- test('returns browser cookie paths on macOS including Default profile', () => {
61
+ it('returns browser cookie paths on macOS including Default profile', () => {
62
62
  const extractor = new ChannelTokenExtractor('darwin')
63
63
  const paths = extractor.getBrowserCookiesPaths()
64
64
 
@@ -67,7 +67,7 @@ describe('ChannelTokenExtractor', () => {
67
67
  expect(paths).toContain(join(chromeBase, 'Default', 'Network', 'Cookies'))
68
68
  })
69
69
 
70
- test('returns browser cookie paths on Linux', () => {
70
+ it('returns browser cookie paths on Linux', () => {
71
71
  const extractor = new ChannelTokenExtractor('linux')
72
72
  const paths = extractor.getBrowserCookiesPaths()
73
73
 
@@ -75,7 +75,7 @@ describe('ChannelTokenExtractor', () => {
75
75
  expect(paths).toContain(join(chromeBase, 'Default', 'Cookies'))
76
76
  })
77
77
 
78
- test('returns browser cookie paths on Windows', () => {
78
+ it('returns browser cookie paths on Windows', () => {
79
79
  const extractor = new ChannelTokenExtractor('win32')
80
80
  const paths = extractor.getBrowserCookiesPaths()
81
81
 
@@ -84,14 +84,14 @@ describe('ChannelTokenExtractor', () => {
84
84
  expect(paths).toContain(join(chromeBase, 'Default', 'Cookies'))
85
85
  })
86
86
 
87
- test('returns empty array for unsupported platform', () => {
87
+ it('returns empty array for unsupported platform', () => {
88
88
  const extractor = new ChannelTokenExtractor('freebsd' as NodeJS.Platform)
89
89
  expect(extractor.getBrowserCookiesPaths()).toEqual([])
90
90
  })
91
91
  })
92
92
 
93
93
  describe('extract', () => {
94
- test('returns empty array when desktop cookies path does not exist', async () => {
94
+ it('returns empty array when desktop cookies path does not exist', async () => {
95
95
  class MissingPathExtractor extends ChannelTokenExtractor {
96
96
  override getCookiesPath(): string | null {
97
97
  return null
@@ -103,7 +103,7 @@ describe('ChannelTokenExtractor', () => {
103
103
  expect(await extractor.extract()).toEqual([])
104
104
  })
105
105
 
106
- test('tries desktop app before browser profiles and collects both', async () => {
106
+ it('tries desktop app before browser profiles and collects both', async () => {
107
107
  const extractor = new ChannelTokenExtractor('darwin')
108
108
 
109
109
  const desktopSpy = spyOn(extractor as any, 'extractFromDesktopApp').mockResolvedValue({
@@ -122,7 +122,7 @@ describe('ChannelTokenExtractor', () => {
122
122
  browserSpy.mockRestore()
123
123
  })
124
124
 
125
- test('includes browser profiles even when desktop extraction returns null', async () => {
125
+ it('includes browser profiles even when desktop extraction returns null', async () => {
126
126
  const extractor = new ChannelTokenExtractor('darwin')
127
127
 
128
128
  const desktopSpy = spyOn(extractor as any, 'extractFromDesktopApp').mockResolvedValue(null)
@@ -143,7 +143,7 @@ describe('ChannelTokenExtractor', () => {
143
143
  browserSpy.mockRestore()
144
144
  })
145
145
 
146
- test('extracts plaintext cookies from a real sqlite database', async () => {
146
+ it('extracts plaintext cookies from a real sqlite database', async () => {
147
147
  const tempDir = mkdtempSync(join(tmpdir(), 'channel-cookie-db-'))
148
148
  tempDirs.push(tempDir)
149
149
  const dbPath = join(tempDir, 'Cookies')
@@ -173,7 +173,7 @@ describe('ChannelTokenExtractor', () => {
173
173
  ])
174
174
  })
175
175
 
176
- test('returns token with undefined sessionCookie when only x-account is present', async () => {
176
+ it('returns token with undefined sessionCookie when only x-account is present', async () => {
177
177
  const tempDir = mkdtempSync(join(tmpdir(), 'channel-cookie-db-'))
178
178
  tempDirs.push(tempDir)
179
179
  const dbPath = join(tempDir, 'Cookies')
@@ -199,7 +199,7 @@ describe('ChannelTokenExtractor', () => {
199
199
  expect(result[0]?.sessionCookie).toBeUndefined()
200
200
  })
201
201
 
202
- test('returns empty array when x-account is missing', async () => {
202
+ it('returns empty array when x-account is missing', async () => {
203
203
  const tempDir = mkdtempSync(join(tmpdir(), 'channel-cookie-db-'))
204
204
  tempDirs.push(tempDir)
205
205
  const dbPath = join(tempDir, 'Cookies')
@@ -222,7 +222,7 @@ describe('ChannelTokenExtractor', () => {
222
222
  expect(await extractor.extract()).toEqual([])
223
223
  })
224
224
 
225
- test('decrypts AES-256-GCM encrypted cookies using master key', async () => {
225
+ it('decrypts AES-256-GCM encrypted cookies using master key', async () => {
226
226
  // given — known master key and AES-256-GCM encrypted cookie
227
227
  const masterKey = randomBytes(32)
228
228
  const accountValue = 'encrypted-account-jwt'
@@ -277,7 +277,7 @@ describe('ChannelTokenExtractor', () => {
277
277
  expect(result[0]?.sessionCookie).toBe('encrypted-session-jwt')
278
278
  })
279
279
 
280
- test('deduplicates entries with the same accountCookie from desktop and browser', async () => {
280
+ it('deduplicates entries with the same accountCookie from desktop and browser', async () => {
281
281
  const extractor = new ChannelTokenExtractor('darwin')
282
282
 
283
283
  const desktopSpy = spyOn(extractor as any, 'extractFromDesktopApp').mockResolvedValue({
@@ -299,7 +299,7 @@ describe('ChannelTokenExtractor', () => {
299
299
  browserSpy.mockRestore()
300
300
  })
301
301
 
302
- test('returns multiple distinct accounts from desktop and browser sources', async () => {
302
+ it('returns multiple distinct accounts from desktop and browser sources', async () => {
303
303
  const extractor = new ChannelTokenExtractor('darwin')
304
304
 
305
305
  const desktopSpy = spyOn(extractor as any, 'extractFromDesktopApp').mockResolvedValue({
@@ -322,7 +322,7 @@ describe('ChannelTokenExtractor', () => {
322
322
  browserSpy.mockRestore()
323
323
  })
324
324
 
325
- test('returns empty array when DPAPI decryption fails', async () => {
325
+ it('returns empty array when DPAPI decryption fails', async () => {
326
326
  // given
327
327
  const masterKey = randomBytes(32)
328
328
  const encryptAccount = encryptAESGCM('account-jwt', masterKey)
@@ -369,14 +369,14 @@ describe('ChannelTokenExtractor', () => {
369
369
  })
370
370
 
371
371
  describe('decryptDPAPI', () => {
372
- test('returns null on non-win32 platform', () => {
372
+ it('returns null on non-win32 platform', () => {
373
373
  const extractor = new ChannelTokenExtractor('darwin')
374
374
  expect(extractor.decryptDPAPI(Buffer.from('test'))).toBeNull()
375
375
  })
376
376
  })
377
377
 
378
378
  describe('decryptBrowserCookie', () => {
379
- test('decrypts v10-prefixed browser cookie using macOS keychain password (AES-128-CBC)', () => {
379
+ it('decrypts v10-prefixed browser cookie using macOS keychain password (AES-128-CBC)', () => {
380
380
  // given — AES-128-CBC encrypted cookie with macOS keychain-derived key
381
381
  const { createCipheriv, pbkdf2Sync } = require('node:crypto')
382
382
  const password = 'test-keychain-password'
@@ -400,7 +400,7 @@ describe('ChannelTokenExtractor', () => {
400
400
  execSecuritySpy.mockRestore()
401
401
  })
402
402
 
403
- test('decrypts v10-prefixed browser cookie using Linux peanuts key (AES-128-CBC)', () => {
403
+ it('decrypts v10-prefixed browser cookie using Linux peanuts key (AES-128-CBC)', () => {
404
404
  // given — AES-128-CBC encrypted cookie with Linux Chromium peanuts key
405
405
  const { createCipheriv, pbkdf2Sync } = require('node:crypto')
406
406
  const key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1')
@@ -12,6 +12,7 @@ import {
12
12
  discoverBrowserProfileDirs,
13
13
  findLocalStatePath,
14
14
  getBrowserBasePath,
15
+ getAgentBrowserProfileDirs,
15
16
  } from '@/shared/chromium'
16
17
  import type { KeychainVariant } from '@/shared/chromium'
17
18
 
@@ -29,9 +30,11 @@ export class ChannelTokenExtractor {
29
30
  private platform: NodeJS.Platform
30
31
  private decryptor: ChromiumCookieDecryptor
31
32
  private cookieReader: ChromiumCookieReader
33
+ private customBrowserProfileDirs: string[]
32
34
 
33
- constructor(platform?: NodeJS.Platform) {
35
+ constructor(platform?: NodeJS.Platform, customBrowserProfileDirs?: string[]) {
34
36
  this.platform = platform ?? process.platform
37
+ this.customBrowserProfileDirs = customBrowserProfileDirs ?? []
35
38
  this.cookieReader = new ChromiumCookieReader()
36
39
  this.decryptor = new ChromiumCookieDecryptor({ platform: this.platform })
37
40
  }
@@ -94,6 +97,11 @@ export class ChannelTokenExtractor {
94
97
  }
95
98
  }
96
99
 
100
+ for (const profileDir of getAgentBrowserProfileDirs({ customProfileDirs: this.customBrowserProfileDirs })) {
101
+ paths.push(join(profileDir, 'Cookies'))
102
+ paths.push(join(profileDir, 'Network', 'Cookies'))
103
+ }
104
+
97
105
  return paths
98
106
  }
99
107
 
@@ -105,16 +113,27 @@ export class ChannelTokenExtractor {
105
113
  const results: ExtractedChannelToken[] = []
106
114
  const seenAccounts = new Set<string>()
107
115
 
116
+ if (this.customBrowserProfileDirs.length > 0) {
117
+ for (const browserResult of await this.extractAllFromBrowserPaths()) {
118
+ if (!seenAccounts.has(browserResult.accountCookie)) {
119
+ seenAccounts.add(browserResult.accountCookie)
120
+ results.push(browserResult)
121
+ }
122
+ }
123
+ }
124
+
108
125
  const desktopResult = await this.extractFromDesktopApp()
109
126
  if (desktopResult && !seenAccounts.has(desktopResult.accountCookie)) {
110
127
  seenAccounts.add(desktopResult.accountCookie)
111
128
  results.push(desktopResult)
112
129
  }
113
130
 
114
- for (const browserResult of await this.extractAllFromBrowserPaths()) {
115
- if (!seenAccounts.has(browserResult.accountCookie)) {
116
- seenAccounts.add(browserResult.accountCookie)
117
- results.push(browserResult)
131
+ if (this.customBrowserProfileDirs.length === 0) {
132
+ for (const browserResult of await this.extractAllFromBrowserPaths()) {
133
+ if (!seenAccounts.has(browserResult.accountCookie)) {
134
+ seenAccounts.add(browserResult.accountCookie)
135
+ results.push(browserResult)
136
+ }
118
137
  }
119
138
  }
120
139
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from 'bun:test'
1
+ import { describe, expect, it } from 'bun:test'
2
2
 
3
3
  import {
4
4
  ChannelAccountSchema,
@@ -10,7 +10,7 @@ import {
10
10
  } from './types'
11
11
 
12
12
  describe('channel types', () => {
13
- test('accepts a valid workspace entry', () => {
13
+ it('accepts a valid workspace entry', () => {
14
14
  const result = ChannelWorkspaceEntrySchema.safeParse({
15
15
  workspace_id: '232986',
16
16
  workspace_name: 'Support',
@@ -23,7 +23,7 @@ describe('channel types', () => {
23
23
  expect(result.success).toBe(true)
24
24
  })
25
25
 
26
- test('accepts a workspace entry without session_cookie', () => {
26
+ it('accepts a workspace entry without session_cookie', () => {
27
27
  const result = ChannelWorkspaceEntrySchema.safeParse({
28
28
  workspace_id: '232986',
29
29
  workspace_name: 'Support',
@@ -33,7 +33,7 @@ describe('channel types', () => {
33
33
  expect(result.success).toBe(true)
34
34
  })
35
35
 
36
- test('rejects a workspace entry missing account_cookie', () => {
36
+ it('rejects a workspace entry missing account_cookie', () => {
37
37
  const result = ChannelWorkspaceEntrySchema.safeParse({
38
38
  workspace_id: '232986',
39
39
  workspace_name: 'Support',
@@ -42,7 +42,7 @@ describe('channel types', () => {
42
42
  expect(result.success).toBe(false)
43
43
  })
44
44
 
45
- test('accepts a valid config', () => {
45
+ it('accepts a valid config', () => {
46
46
  const result = ChannelConfigSchema.safeParse({
47
47
  current: { workspace_id: '232986' },
48
48
  workspaces: {
@@ -58,7 +58,7 @@ describe('channel types', () => {
58
58
  expect(result.success).toBe(true)
59
59
  })
60
60
 
61
- test('accepts a valid account', () => {
61
+ it('accepts a valid account', () => {
62
62
  const result = ChannelAccountSchema.safeParse({
63
63
  id: '493041',
64
64
  name: 'Devxoul',
@@ -72,7 +72,7 @@ describe('channel types', () => {
72
72
  expect(result.success).toBe(true)
73
73
  })
74
74
 
75
- test('rejects an invalid account', () => {
75
+ it('rejects an invalid account', () => {
76
76
  const result = ChannelAccountSchema.safeParse({
77
77
  id: '493041',
78
78
  name: 'Devxoul',
@@ -86,7 +86,7 @@ describe('channel types', () => {
86
86
  expect(result.success).toBe(false)
87
87
  })
88
88
 
89
- test('accepts a valid message with blocks', () => {
89
+ it('accepts a valid message with blocks', () => {
90
90
  const result = ChannelMessageSchema.safeParse({
91
91
  id: 'msg_1',
92
92
  channelId: '232986',
@@ -99,7 +99,7 @@ describe('channel types', () => {
99
99
  expect(result.success).toBe(true)
100
100
  })
101
101
 
102
- test('rejects an invalid message block payload', () => {
102
+ it('rejects an invalid message block payload', () => {
103
103
  const result = ChannelMessageSchema.safeParse({
104
104
  id: 'msg_1',
105
105
  blocks: [{ type: 'text', value: 123 }],
@@ -108,7 +108,7 @@ describe('channel types', () => {
108
108
  expect(result.success).toBe(false)
109
109
  })
110
110
 
111
- test('accepts a valid group', () => {
111
+ it('accepts a valid group', () => {
112
112
  const result = ChannelGroupSchema.safeParse({
113
113
  id: 'group_1',
114
114
  channelId: '232986',
@@ -120,7 +120,7 @@ describe('channel types', () => {
120
120
  expect(result.success).toBe(true)
121
121
  })
122
122
 
123
- test('rejects an invalid group', () => {
123
+ it('rejects an invalid group', () => {
124
124
  const result = ChannelGroupSchema.safeParse({
125
125
  id: 'group_1',
126
126
  channelId: '232986',
@@ -131,7 +131,7 @@ describe('channel types', () => {
131
131
  expect(result.success).toBe(false)
132
132
  })
133
133
 
134
- test('stores the code on ChannelError', () => {
134
+ it('stores the code on ChannelError', () => {
135
135
  const error = new ChannelError('boom', 'CHANNEL_FAILED')
136
136
 
137
137
  expect(error).toBeInstanceOf(Error)
@@ -23,6 +23,15 @@ program
23
23
  .option('--pretty', 'Pretty-print JSON output')
24
24
  .option('--workspace <id>', 'Workspace ID to use')
25
25
  .option('--bot <name>', 'Bot name to use for sending messages')
26
+ .hook('preAction', (thisCmd, actionCmd) => {
27
+ for (const [key, value] of Object.entries(thisCmd.opts())) {
28
+ if (value === undefined) continue
29
+ const source = actionCmd.getOptionValueSource(key)
30
+ if (source === undefined || source === 'default') {
31
+ actionCmd.setOptionValue(key, value)
32
+ }
33
+ }
34
+ })
26
35
 
27
36
  program.addCommand(authCommand)
28
37
  program.addCommand(whoamiCommand)