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 { unlinkSync } from 'node:fs'
3
3
 
4
4
  import { TeamsClient } from './client'
@@ -54,17 +54,17 @@ describe('TeamsClient', () => {
54
54
  }
55
55
 
56
56
  describe('login', () => {
57
- test('requires token', async () => {
57
+ it('requires token', async () => {
58
58
  await expect(new TeamsClient().login({ token: '', region: 'emea' })).rejects.toThrow(TeamsError)
59
59
  await expect(new TeamsClient().login({ token: '', region: 'emea' })).rejects.toThrow('Token is required')
60
60
  })
61
61
 
62
- test('accepts valid token', async () => {
62
+ it('accepts valid token', async () => {
63
63
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
64
64
  expect(client).toBeInstanceOf(TeamsClient)
65
65
  })
66
66
 
67
- test('accepts token with expiry time', async () => {
67
+ it('accepts token with expiry time', async () => {
68
68
  const expiresAt = new Date(Date.now() + 3600000).toISOString()
69
69
  const client = await new TeamsClient().login({ token: 'test-token', tokenExpiresAt: expiresAt, region: 'emea' })
70
70
  expect(client).toBeInstanceOf(TeamsClient)
@@ -72,7 +72,7 @@ describe('TeamsClient', () => {
72
72
  })
73
73
 
74
74
  describe('token expiry', () => {
75
- test('throws when token is expired', async () => {
75
+ it('throws when token is expired', async () => {
76
76
  const expiredAt = new Date(Date.now() - 1000).toISOString()
77
77
  const client = await new TeamsClient().login({
78
78
  token: 'expired-token',
@@ -84,7 +84,7 @@ describe('TeamsClient', () => {
84
84
  await expect(client.testAuth()).rejects.toThrow('Token has expired')
85
85
  })
86
86
 
87
- test('works when token is not expired', async () => {
87
+ it('works when token is not expired', async () => {
88
88
  const expiresAt = new Date(Date.now() + 3600000).toISOString()
89
89
  mockResponse({
90
90
  userDetails: JSON.stringify({ name: 'Test User' }),
@@ -100,7 +100,7 @@ describe('TeamsClient', () => {
100
100
  })
101
101
 
102
102
  describe('testAuth', () => {
103
- test('returns current user info', async () => {
103
+ it('returns current user info', async () => {
104
104
  mockResponse({
105
105
  userDetails: JSON.stringify({ name: 'Test User' }),
106
106
  locale: 'en-us',
@@ -118,7 +118,7 @@ describe('TeamsClient', () => {
118
118
  })
119
119
  })
120
120
 
121
- test('throws TeamsError on API error', async () => {
121
+ it('throws TeamsError on API error', async () => {
122
122
  mockResponse({ message: 'Unauthorized', code: 'unauthorized' }, 401)
123
123
 
124
124
  const client = await new TeamsClient().login({ token: 'bad-token', region: 'emea' })
@@ -127,7 +127,7 @@ describe('TeamsClient', () => {
127
127
  })
128
128
 
129
129
  describe('listTeams', () => {
130
- test('returns list of teams from conversations', async () => {
130
+ it('returns list of teams from conversations', async () => {
131
131
  mockResponse({
132
132
  conversations: [
133
133
  {
@@ -170,7 +170,7 @@ describe('TeamsClient', () => {
170
170
  })
171
171
 
172
172
  describe('getTeam', () => {
173
- test('returns team info', async () => {
173
+ it('returns team info', async () => {
174
174
  mockResponse({ id: '111', name: 'Test Team', description: 'A test team' })
175
175
 
176
176
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -183,7 +183,7 @@ describe('TeamsClient', () => {
183
183
  })
184
184
 
185
185
  describe('listChannels', () => {
186
- test('returns list of channels for team', async () => {
186
+ it('returns list of channels for team', async () => {
187
187
  mockResponse([
188
188
  { id: 'ch1', team_id: '111', name: 'General', type: 'standard' },
189
189
  { id: 'ch2', team_id: '111', name: 'Random', type: 'standard' },
@@ -199,7 +199,7 @@ describe('TeamsClient', () => {
199
199
  })
200
200
 
201
201
  describe('getChannel', () => {
202
- test('returns channel info', async () => {
202
+ it('returns channel info', async () => {
203
203
  mockResponse({ id: 'ch1', team_id: '111', name: 'General', type: 'standard' })
204
204
 
205
205
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -212,7 +212,7 @@ describe('TeamsClient', () => {
212
212
  })
213
213
 
214
214
  describe('sendMessage', () => {
215
- test('sends message to channel', async () => {
215
+ it('sends message to channel', async () => {
216
216
  mockResponse({
217
217
  id: 'msg1',
218
218
  channel_id: 'ch1',
@@ -232,7 +232,7 @@ describe('TeamsClient', () => {
232
232
  })
233
233
 
234
234
  describe('getMessages', () => {
235
- test('returns messages from channel', async () => {
235
+ it('returns messages from channel', async () => {
236
236
  mockResponse([
237
237
  {
238
238
  id: 'msg1',
@@ -253,7 +253,7 @@ describe('TeamsClient', () => {
253
253
  )
254
254
  })
255
255
 
256
- test('uses default limit of 50', async () => {
256
+ it('uses default limit of 50', async () => {
257
257
  mockResponse([])
258
258
 
259
259
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -266,7 +266,7 @@ describe('TeamsClient', () => {
266
266
  })
267
267
 
268
268
  describe('getMessage', () => {
269
- test('returns single message', async () => {
269
+ it('returns single message', async () => {
270
270
  mockResponse({
271
271
  id: 'msg1',
272
272
  channel_id: 'ch1',
@@ -286,7 +286,7 @@ describe('TeamsClient', () => {
286
286
  })
287
287
 
288
288
  describe('deleteMessage', () => {
289
- test('deletes message', async () => {
289
+ it('deletes message', async () => {
290
290
  mockResponse(null, 204)
291
291
 
292
292
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -300,7 +300,7 @@ describe('TeamsClient', () => {
300
300
  })
301
301
 
302
302
  describe('addReaction', () => {
303
- test('adds reaction to message', async () => {
303
+ it('adds reaction to message', async () => {
304
304
  mockResponse(null, 204)
305
305
 
306
306
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -315,7 +315,7 @@ describe('TeamsClient', () => {
315
315
  })
316
316
 
317
317
  describe('removeReaction', () => {
318
- test('removes reaction from message', async () => {
318
+ it('removes reaction from message', async () => {
319
319
  mockResponse(null, 204)
320
320
 
321
321
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -329,7 +329,7 @@ describe('TeamsClient', () => {
329
329
  })
330
330
 
331
331
  describe('listUsers', () => {
332
- test('returns list of team members', async () => {
332
+ it('returns list of team members', async () => {
333
333
  mockResponse([
334
334
  { id: 'u1', displayName: 'User 1', email: 'user1@example.com' },
335
335
  { id: 'u2', displayName: 'User 2', email: 'user2@example.com' },
@@ -345,7 +345,7 @@ describe('TeamsClient', () => {
345
345
  })
346
346
 
347
347
  describe('getUser', () => {
348
- test('returns user info', async () => {
348
+ it('returns user info', async () => {
349
349
  mockResponse({ id: 'u1', displayName: 'Test User', email: 'test@example.com' })
350
350
 
351
351
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -358,7 +358,7 @@ describe('TeamsClient', () => {
358
358
  })
359
359
 
360
360
  describe('uploadFile', () => {
361
- test('uploads file to channel', async () => {
361
+ it('uploads file to channel', async () => {
362
362
  const tempFile = '/tmp/test-teams-upload.txt'
363
363
  await Bun.write(tempFile, 'test content')
364
364
 
@@ -379,7 +379,7 @@ describe('TeamsClient', () => {
379
379
  })
380
380
 
381
381
  describe('listFiles', () => {
382
- test('returns files from channel', async () => {
382
+ it('returns files from channel', async () => {
383
383
  mockResponse([
384
384
  { id: 'file1', name: 'doc.pdf', size: 1024, url: 'https://example.com/doc.pdf' },
385
385
  { id: 'file2', name: 'image.png', size: 2048, url: 'https://example.com/image.png' },
@@ -395,7 +395,7 @@ describe('TeamsClient', () => {
395
395
  })
396
396
 
397
397
  describe('rate limiting', () => {
398
- test('waits when bucket is exhausted before making request', async () => {
398
+ it('waits when bucket is exhausted before making request', async () => {
399
399
  mockResponse({ userDetails: JSON.stringify({ name: 'User 1' }), locale: 'en-us' }, 200, {
400
400
  'X-RateLimit-Remaining': '0',
401
401
  'X-RateLimit-Reset': String(Date.now() / 1000 + 0.1),
@@ -416,7 +416,7 @@ describe('TeamsClient', () => {
416
416
  expect(fetchCalls.length).toBe(2)
417
417
  })
418
418
 
419
- test('retries on 429 with Retry-After header', async () => {
419
+ it('retries on 429 with Retry-After header', async () => {
420
420
  mockResponse({ message: 'Rate limited' }, 429, { 'Retry-After': '0.1' })
421
421
  mockResponse({ userDetails: JSON.stringify({ name: 'User' }), locale: 'en-us' })
422
422
 
@@ -427,7 +427,7 @@ describe('TeamsClient', () => {
427
427
  expect(fetchCalls.length).toBe(2)
428
428
  })
429
429
 
430
- test('throws after max retries exceeded', async () => {
430
+ it('throws after max retries exceeded', async () => {
431
431
  for (let i = 0; i <= 3; i++) {
432
432
  mockResponse({ message: 'Rate limited' }, 429, { 'Retry-After': '0.01' })
433
433
  }
@@ -439,7 +439,7 @@ describe('TeamsClient', () => {
439
439
  })
440
440
 
441
441
  describe('retry logic', () => {
442
- test('retries on 500 server error', async () => {
442
+ it('retries on 500 server error', async () => {
443
443
  mockResponse({ message: 'Internal Server Error' }, 500)
444
444
  mockResponse({ userDetails: JSON.stringify({ name: 'User' }), locale: 'en-us' })
445
445
 
@@ -450,7 +450,7 @@ describe('TeamsClient', () => {
450
450
  expect(fetchCalls.length).toBe(2)
451
451
  })
452
452
 
453
- test('does not retry on 4xx client errors (except 429)', async () => {
453
+ it('does not retry on 4xx client errors (except 429)', async () => {
454
454
  mockResponse({ message: 'Not Found' }, 404)
455
455
 
456
456
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
@@ -458,7 +458,7 @@ describe('TeamsClient', () => {
458
458
  expect(fetchCalls.length).toBe(1)
459
459
  })
460
460
 
461
- test('exponential backoff increases delay', async () => {
461
+ it('exponential backoff increases delay', async () => {
462
462
  mockResponse({ message: 'Error' }, 500)
463
463
  mockResponse({ message: 'Error' }, 500)
464
464
  mockResponse({ userDetails: JSON.stringify({ name: 'User' }), locale: 'en-us' })
@@ -474,7 +474,7 @@ describe('TeamsClient', () => {
474
474
  })
475
475
 
476
476
  describe('bucket key normalization', () => {
477
- test('normalizes team and channel IDs in routes', async () => {
477
+ it('normalizes team and channel IDs in routes', async () => {
478
478
  mockResponse([])
479
479
  mockResponse([])
480
480
 
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, expect, spyOn, it } from 'bun:test'
2
2
 
3
3
  import { TeamsClient } from '../client'
4
4
  import { TeamsCredentialManager } from '../credential-manager'
@@ -16,7 +16,7 @@ let clientGetRegionSpy: ReturnType<typeof spyOn>
16
16
 
17
17
  beforeEach(() => {
18
18
  extractorExtractSpy = spyOn(TeamsTokenExtractor.prototype, 'extract').mockResolvedValue([
19
- { token: 'test-skype-token-123', accountType: 'work' as const },
19
+ { token: 'test-skype-token-123', accountType: 'work' as const, accountTypeKnown: true },
20
20
  ])
21
21
 
22
22
  clientTestAuthSpy = spyOn(TeamsClient.prototype, 'testAuth').mockResolvedValue({
@@ -54,7 +54,7 @@ afterEach(() => {
54
54
  clientGetRegionSpy?.mockRestore()
55
55
  })
56
56
 
57
- test('extract: calls TeamsTokenExtractor', async () => {
57
+ it('extract: calls TeamsTokenExtractor', async () => {
58
58
  const extractor = new TeamsTokenExtractor()
59
59
  const result = await extractor.extract()
60
60
  expect(result).toHaveLength(1)
@@ -62,7 +62,7 @@ test('extract: calls TeamsTokenExtractor', async () => {
62
62
  expect(result[0].accountType).toBe('work')
63
63
  })
64
64
 
65
- test('extract: validates token with TeamsClient', async () => {
65
+ it('extract: validates token with TeamsClient', async () => {
66
66
  const client = await new TeamsClient().login({ token: 'test-skype-token-123', region: 'emea' })
67
67
  const authInfo = await client.testAuth()
68
68
  expect(authInfo).toBeDefined()
@@ -70,31 +70,31 @@ test('extract: validates token with TeamsClient', async () => {
70
70
  expect(authInfo.displayName).toBe('Test User')
71
71
  })
72
72
 
73
- test('extract: discovers teams', async () => {
73
+ it('extract: discovers teams', async () => {
74
74
  const client = await new TeamsClient().login({ token: 'test-skype-token-123', region: 'emea' })
75
75
  const teams = await client.listTeams()
76
76
  expect(teams).toHaveLength(2)
77
77
  expect(teams[0].id).toBe('team-1')
78
78
  })
79
79
 
80
- test('logout: clears credentials', async () => {
80
+ it('logout: clears credentials', async () => {
81
81
  const credManager = new TeamsCredentialManager()
82
82
  await credManager.clearCredentials()
83
83
  expect(credManager.clearCredentials).toHaveBeenCalled()
84
84
  })
85
85
 
86
- test('status: returns auth state when not authenticated', async () => {
86
+ it('status: returns auth state when not authenticated', async () => {
87
87
  const credManager = new TeamsCredentialManager()
88
88
  const config = await credManager.loadConfig()
89
89
  expect(config).toBeNull()
90
90
  })
91
91
 
92
- test('status: checks token expiry', async () => {
92
+ it('status: checks token expiry', async () => {
93
93
  const credManager = new TeamsCredentialManager()
94
94
  const isExpired = await credManager.isTokenExpired()
95
95
  expect(isExpired).toBe(false)
96
96
  })
97
97
 
98
- test('no-token message mentions desktop app and browser fallback', () => {
98
+ it('no-token message mentions desktop app and browser fallback', () => {
99
99
  expect(getNoTeamsTokenFoundMessage()).toContain('desktop app or a supported Chromium browser')
100
100
  })
@@ -1,5 +1,6 @@
1
1
  import { Command } from 'commander'
2
2
 
3
+ import { collectBrowserProfileOption } from '@/shared/chromium'
3
4
  import { handleError } from '@/shared/utils/error-handler'
4
5
  import { formatOutput } from '@/shared/utils/output'
5
6
  import { debug } from '@/shared/utils/stderr'
@@ -9,7 +10,46 @@ import { TeamsCredentialManager } from '../credential-manager'
9
10
  import { TeamsTokenExtractor } from '../token-extractor'
10
11
  import type { TeamsAccount, TeamsAccountType, TeamsConfig } from '../types'
11
12
 
12
- export async function extractAction(options: { pretty?: boolean; debug?: boolean; token?: string }): Promise<void> {
13
+ interface ValidatedTeamsToken {
14
+ client: TeamsClient
15
+ accountType: TeamsAccountType
16
+ authInfo: { id: string; displayName: string }
17
+ }
18
+
19
+ async function validateTokenWithProbe(
20
+ token: string,
21
+ accountType: TeamsAccountType,
22
+ accountTypeKnown: boolean,
23
+ debugLog?: (msg: string) => void,
24
+ ): Promise<ValidatedTeamsToken> {
25
+ const primaryTypes: TeamsAccountType[] = [accountType]
26
+ if (!accountTypeKnown) {
27
+ primaryTypes.push(accountType === 'work' ? 'personal' : 'work')
28
+ }
29
+
30
+ let lastError: Error | null = null
31
+ for (const candidateType of primaryTypes) {
32
+ try {
33
+ const client = await new TeamsClient().login({ token, accountType: candidateType })
34
+ const authInfo = await client.testAuth()
35
+ if (candidateType !== accountType) {
36
+ debugLog?.(`[debug] Reclassified ${accountType} → ${candidateType} via API probe`)
37
+ }
38
+ return { client, accountType: candidateType, authInfo }
39
+ } catch (error) {
40
+ lastError = error as Error
41
+ debugLog?.(`[debug] Probe ${candidateType} failed: ${lastError.message}`)
42
+ }
43
+ }
44
+ throw lastError ?? new Error('Token validation failed')
45
+ }
46
+
47
+ export async function extractAction(options: {
48
+ pretty?: boolean
49
+ debug?: boolean
50
+ token?: string
51
+ browserProfile?: string[]
52
+ }): Promise<void> {
13
53
  try {
14
54
  if (options.token) {
15
55
  await extractManualToken(options.token, options)
@@ -17,7 +57,7 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
17
57
  }
18
58
 
19
59
  const debugLog = options.debug ? (msg: string) => debug(`[debug] ${msg}`) : undefined
20
- const extractor = new TeamsTokenExtractor(undefined, undefined, debugLog)
60
+ const extractor = new TeamsTokenExtractor(undefined, undefined, debugLog, options.browserProfile)
21
61
 
22
62
  if (process.platform === 'darwin') {
23
63
  console.log('')
@@ -67,20 +107,33 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
67
107
  teams: string[]
68
108
  }> = []
69
109
 
70
- for (const { token, accountType } of extracted) {
110
+ for (const { token, accountType: extractedType, accountTypeKnown } of extracted) {
71
111
  if (options.debug) {
72
- debug(`[debug] Validating ${accountType} account token...`)
112
+ const label = accountTypeKnown ? extractedType : `${extractedType} (probing)`
113
+ debug(`[debug] Validating ${label} account token...`)
73
114
  }
74
115
 
75
116
  try {
76
- const client = await new TeamsClient().login({ token, accountType })
77
- const authInfo = await client.testAuth()
117
+ const debugLog = options.debug ? (msg: string) => debug(msg) : undefined
118
+ const { client, accountType, authInfo } = await validateTokenWithProbe(
119
+ token,
120
+ extractedType,
121
+ accountTypeKnown,
122
+ debugLog,
123
+ )
78
124
  const teams = await client.listTeams()
79
125
 
80
126
  if (options.debug) {
81
127
  debug(`[debug] ✓ ${accountType}: ${authInfo.displayName} (${teams.length} team(s))`)
82
128
  }
83
129
 
130
+ if (config.accounts[accountType]) {
131
+ if (options.debug) {
132
+ debug(`[debug] Skipping duplicate ${accountType} account`)
133
+ }
134
+ continue
135
+ }
136
+
84
137
  const teamMap: Record<string, { team_id: string; team_name: string }> = {}
85
138
  for (const team of teams) {
86
139
  teamMap[team.id] = { team_id: team.id, team_name: team.name }
@@ -110,7 +163,7 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
110
163
  const errorMessage = (error as Error).message
111
164
  const is401 = errorMessage.includes('401') || errorMessage.includes('Unauthorized')
112
165
  if (options.debug) {
113
- debug(`[debug] ✗ ${accountType}: ${errorMessage}`)
166
+ debug(`[debug] ✗ ${extractedType}: ${errorMessage}`)
114
167
  }
115
168
  if (extracted.length === 1) {
116
169
  console.log(
@@ -380,6 +433,12 @@ export const authCommand = new Command('auth')
380
433
  .option('--pretty', 'Pretty print JSON output')
381
434
  .option('--debug', 'Show debug output for troubleshooting')
382
435
  .option('--token <token>', 'Manually provide a token (bypasses auto-extraction)')
436
+ .option(
437
+ '--browser-profile <path>',
438
+ 'Additional Chromium profile/user-data directory to scan (repeatable, comma-separated supported)',
439
+ collectBrowserProfileOption,
440
+ [],
441
+ )
383
442
  .action(extractAction),
384
443
  )
385
444
  .addCommand(
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, expect, spyOn, it } from 'bun:test'
2
2
 
3
3
  import { TeamsClient } from '../client'
4
4
  import { TeamsCredentialManager } from '../credential-manager'
@@ -65,7 +65,7 @@ afterEach(() => {
65
65
  credManagerLoadConfigSpy?.mockRestore()
66
66
  })
67
67
 
68
- test('list: returns channels from team', async () => {
68
+ it('list: returns channels from team', async () => {
69
69
  // given
70
70
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
71
71
 
@@ -78,7 +78,7 @@ test('list: returns channels from team', async () => {
78
78
  expect(channels[1].name).toBe('Announcements')
79
79
  })
80
80
 
81
- test('list: includes channel metadata', async () => {
81
+ it('list: includes channel metadata', async () => {
82
82
  // given
83
83
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
84
84
  const channels = await client.listChannels('team-1')
@@ -93,7 +93,7 @@ test('list: includes channel metadata', async () => {
93
93
  expect(channel.team_id).toBe('team-1')
94
94
  })
95
95
 
96
- test('info: returns channel details', async () => {
96
+ it('info: returns channel details', async () => {
97
97
  // given
98
98
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
99
99
 
@@ -106,7 +106,7 @@ test('info: returns channel details', async () => {
106
106
  expect(channel.type).toBe('standard')
107
107
  })
108
108
 
109
- test('info: throws error for non-existent channel', async () => {
109
+ it('info: throws error for non-existent channel', async () => {
110
110
  // given
111
111
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
112
112
 
@@ -119,7 +119,7 @@ test('info: throws error for non-existent channel', async () => {
119
119
  }
120
120
  })
121
121
 
122
- test('history: returns messages', async () => {
122
+ it('history: returns messages', async () => {
123
123
  // given
124
124
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
125
125
 
@@ -134,7 +134,7 @@ test('history: returns messages', async () => {
134
134
  expect(messages[1].author.displayName).toBe('Bob')
135
135
  })
136
136
 
137
- test('history: includes message metadata', async () => {
137
+ it('history: includes message metadata', async () => {
138
138
  // given
139
139
  const client = await new TeamsClient().login({ token: 'test-token', region: 'emea' })
140
140
  const messages = await client.getMessages('team-1', 'ch-1', 50)
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, expect, mock, spyOn, it } from 'bun:test'
2
2
 
3
3
  import { TeamsClient } from '../client'
4
4
  import { TeamsCredentialManager } from '../credential-manager'
@@ -55,7 +55,7 @@ afterEach(() => {
55
55
  console.log = originalConsoleLog
56
56
  })
57
57
 
58
- test('upload: sends multipart request and returns file info', async () => {
58
+ it('upload: sends multipart request and returns file info', async () => {
59
59
  const consoleSpy = mock((_msg: string) => {})
60
60
  console.log = consoleSpy
61
61
 
@@ -67,7 +67,7 @@ test('upload: sends multipart request and returns file info', async () => {
67
67
  expect(output).toContain('test.pdf')
68
68
  })
69
69
 
70
- test('list: returns files in channel', async () => {
70
+ it('list: returns files in channel', async () => {
71
71
  const consoleSpy = mock((_msg: string) => {})
72
72
  console.log = consoleSpy
73
73
 
@@ -79,7 +79,7 @@ test('list: returns files in channel', async () => {
79
79
  expect(output).toContain('file_124')
80
80
  })
81
81
 
82
- test('info: returns single file details', async () => {
82
+ it('info: returns single file details', async () => {
83
83
  const consoleSpy = mock((_msg: string) => {})
84
84
  console.log = consoleSpy
85
85
 
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, expect, mock, spyOn, it } from 'bun:test'
2
2
 
3
3
  import { TeamsClient } from '../client'
4
4
  import { TeamsCredentialManager } from '../credential-manager'
@@ -69,7 +69,7 @@ afterEach(() => {
69
69
  console.log = originalConsoleLog
70
70
  })
71
71
 
72
- test('send: returns message with id', async () => {
72
+ it('send: returns message with id', async () => {
73
73
  const consoleSpy = mock((_msg: string) => {})
74
74
  console.log = consoleSpy
75
75
 
@@ -80,7 +80,7 @@ test('send: returns message with id', async () => {
80
80
  expect(output).toContain('msg_123')
81
81
  })
82
82
 
83
- test('list: returns array of messages', async () => {
83
+ it('list: returns array of messages', async () => {
84
84
  const consoleSpy = mock((_msg: string) => {})
85
85
  console.log = consoleSpy
86
86
 
@@ -92,7 +92,7 @@ test('list: returns array of messages', async () => {
92
92
  expect(output).toContain('msg_124')
93
93
  })
94
94
 
95
- test('get: returns single message', async () => {
95
+ it('get: returns single message', async () => {
96
96
  const consoleSpy = mock((_msg: string) => {})
97
97
  console.log = consoleSpy
98
98
 
@@ -103,7 +103,7 @@ test('get: returns single message', async () => {
103
103
  expect(output).toContain('msg_123')
104
104
  })
105
105
 
106
- test('delete: returns success', async () => {
106
+ it('delete: returns success', async () => {
107
107
  const consoleSpy = mock((_msg: string) => {})
108
108
  console.log = consoleSpy
109
109
 
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, expect, spyOn, it } from 'bun:test'
2
2
 
3
3
  import { TeamsClient } from '../client'
4
4
  import { TeamsCredentialManager } from '../credential-manager'
@@ -31,7 +31,7 @@ afterEach(() => {
31
31
  processExitSpy.mockRestore()
32
32
  })
33
33
 
34
- test('add: sends correct POST request with emoji', async () => {
34
+ it('add: sends correct POST request with emoji', async () => {
35
35
  try {
36
36
  await addAction('team123', 'ch123', 'msg123', 'like', { pretty: false })
37
37
  } catch {}
@@ -45,7 +45,7 @@ test('add: sends correct POST request with emoji', async () => {
45
45
  expect(output.emoji).toBe('like')
46
46
  })
47
47
 
48
- test('remove: sends correct DELETE request with emoji', async () => {
48
+ it('remove: sends correct DELETE request with emoji', async () => {
49
49
  try {
50
50
  await removeAction('team123', 'ch123', 'msg123', 'like', { pretty: false })
51
51
  } catch {}
@@ -59,7 +59,7 @@ test('remove: sends correct DELETE request with emoji', async () => {
59
59
  expect(output.emoji).toBe('like')
60
60
  })
61
61
 
62
- test('add: handles missing token gracefully', async () => {
62
+ it('add: handles missing token gracefully', async () => {
63
63
  getTokenWithExpirySpy.mockImplementation(() => Promise.resolve(null))
64
64
 
65
65
  try {
@@ -1,35 +1,35 @@
1
- import { expect, test } from 'bun:test'
1
+ import { expect, it } from 'bun:test'
2
2
 
3
3
  import { snapshotCommand } from './snapshot'
4
4
 
5
- test('snapshot: command is defined', () => {
5
+ it('snapshot: command is defined', () => {
6
6
  expect(snapshotCommand).toBeDefined()
7
7
  expect(snapshotCommand.name()).toBe('snapshot')
8
8
  })
9
9
 
10
- test('snapshot: command has correct description', () => {
10
+ it('snapshot: command has correct description', () => {
11
11
  expect(snapshotCommand.description()).toContain('team overview')
12
12
  })
13
13
 
14
- test('snapshot: command has --channels-only option', () => {
14
+ it('snapshot: command has --channels-only option', () => {
15
15
  const options = snapshotCommand.options
16
16
  const channelsOnlyOption = options.find((opt) => opt.long === '--channels-only')
17
17
  expect(channelsOnlyOption).toBeDefined()
18
18
  })
19
19
 
20
- test('snapshot: command has --users-only option', () => {
20
+ it('snapshot: command has --users-only option', () => {
21
21
  const options = snapshotCommand.options
22
22
  const usersOnlyOption = options.find((opt) => opt.long === '--users-only')
23
23
  expect(usersOnlyOption).toBeDefined()
24
24
  })
25
25
 
26
- test('snapshot: command has --limit option', () => {
26
+ it('snapshot: command has --limit option', () => {
27
27
  const options = snapshotCommand.options
28
28
  const limitOption = options.find((opt) => opt.long === '--limit')
29
29
  expect(limitOption).toBeDefined()
30
30
  })
31
31
 
32
- test('snapshot: command has --team-id option', () => {
32
+ it('snapshot: command has --team-id option', () => {
33
33
  const options = snapshotCommand.options
34
34
  const teamIdOption = options.find((opt) => opt.long === '--team-id')
35
35
  expect(teamIdOption).toBeDefined()