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
@@ -11,6 +11,7 @@ import {
11
11
  discoverBrowserProfileDirs,
12
12
  findLocalStatePath,
13
13
  getBrowserBasePath,
14
+ getAgentBrowserProfileDirs,
14
15
  } from '@/shared/chromium'
15
16
  import type { KeychainVariant } from '@/shared/chromium'
16
17
  import { DerivedKeyCache } from '@/shared/utils/derived-key-cache'
@@ -20,11 +21,17 @@ import type { TeamsAccountType } from './types'
20
21
  export interface ExtractedTeamsToken {
21
22
  token: string
22
23
  accountType: TeamsAccountType
24
+ // False when the account type was guessed from the cookie path and needs to be
25
+ // confirmed against the Teams API (e.g. browser profiles, which don't encode
26
+ // work vs personal in the path). True for desktop paths that reliably encode
27
+ // the account type (WV2Profile_tfw vs WV2Profile_tfl).
28
+ accountTypeKnown: boolean
23
29
  }
24
30
 
25
31
  interface TeamsCookiePath {
26
32
  path: string
27
33
  accountType: TeamsAccountType
34
+ accountTypeKnown: boolean
28
35
  }
29
36
 
30
37
  const TEAMS_PROCESS_NAMES: Record<string, string> = {
@@ -56,10 +63,17 @@ export class TeamsTokenExtractor {
56
63
  private decryptor: ChromiumCookieDecryptor
57
64
  private cookieReader: ChromiumCookieReader
58
65
  private debugLog: ((message: string) => void) | null
59
-
60
- constructor(platform?: NodeJS.Platform, keyCache?: DerivedKeyCache, debugLog?: (message: string) => void) {
66
+ private customBrowserProfileDirs: string[]
67
+
68
+ constructor(
69
+ platform?: NodeJS.Platform,
70
+ keyCache?: DerivedKeyCache,
71
+ debugLog?: (message: string) => void,
72
+ customBrowserProfileDirs?: string[],
73
+ ) {
61
74
  this.platform = platform ?? process.platform
62
75
  this.debugLog = debugLog ?? null
76
+ this.customBrowserProfileDirs = customBrowserProfileDirs ?? []
63
77
 
64
78
  const resolvedKeyCache = keyCache ?? new DerivedKeyCache()
65
79
  this.decryptor = new ChromiumCookieDecryptor({
@@ -91,15 +105,28 @@ export class TeamsTokenExtractor {
91
105
  'EBWebView',
92
106
  )
93
107
  return [
94
- { path: join(ebWebViewBase, 'WV2Profile_tfw', 'Cookies'), accountType: 'work' },
95
- { path: join(ebWebViewBase, 'WV2Profile_tfw', 'Network', 'Cookies'), accountType: 'work' },
96
- { path: join(ebWebViewBase, 'WV2Profile_tfl', 'Cookies'), accountType: 'personal' },
97
- { path: join(ebWebViewBase, 'WV2Profile_tfl', 'Network', 'Cookies'), accountType: 'personal' },
98
- { path: join(ebWebViewBase, 'Default', 'Cookies'), accountType: 'work' },
99
- { path: join(ebWebViewBase, 'Default', 'Network', 'Cookies'), accountType: 'work' },
108
+ { path: join(ebWebViewBase, 'WV2Profile_tfw', 'Cookies'), accountType: 'work', accountTypeKnown: true },
109
+ {
110
+ path: join(ebWebViewBase, 'WV2Profile_tfw', 'Network', 'Cookies'),
111
+ accountType: 'work',
112
+ accountTypeKnown: true,
113
+ },
114
+ {
115
+ path: join(ebWebViewBase, 'WV2Profile_tfl', 'Cookies'),
116
+ accountType: 'personal',
117
+ accountTypeKnown: true,
118
+ },
119
+ {
120
+ path: join(ebWebViewBase, 'WV2Profile_tfl', 'Network', 'Cookies'),
121
+ accountType: 'personal',
122
+ accountTypeKnown: true,
123
+ },
124
+ { path: join(ebWebViewBase, 'Default', 'Cookies'), accountType: 'work', accountTypeKnown: false },
125
+ { path: join(ebWebViewBase, 'Default', 'Network', 'Cookies'), accountType: 'work', accountTypeKnown: false },
100
126
  {
101
127
  path: join(homedir(), 'Library', 'Application Support', 'Microsoft', 'Teams', 'Cookies'),
102
128
  accountType: 'work',
129
+ accountTypeKnown: false,
103
130
  },
104
131
  ]
105
132
  }
@@ -108,6 +135,7 @@ export class TeamsTokenExtractor {
108
135
  {
109
136
  path: join(homedir(), '.config', 'Microsoft', 'Microsoft Teams', 'Cookies'),
110
137
  accountType: 'work',
138
+ accountTypeKnown: false,
111
139
  },
112
140
  ]
113
141
  case 'win32': {
@@ -123,13 +151,25 @@ export class TeamsTokenExtractor {
123
151
  'EBWebView',
124
152
  )
125
153
  return [
126
- { path: join(ebWebViewBase, 'WV2Profile_tfw', 'Cookies'), accountType: 'work' },
127
- { path: join(ebWebViewBase, 'WV2Profile_tfw', 'Network', 'Cookies'), accountType: 'work' },
128
- { path: join(ebWebViewBase, 'WV2Profile_tfl', 'Cookies'), accountType: 'personal' },
129
- { path: join(ebWebViewBase, 'WV2Profile_tfl', 'Network', 'Cookies'), accountType: 'personal' },
130
- { path: join(ebWebViewBase, 'Default', 'Cookies'), accountType: 'work' },
131
- { path: join(ebWebViewBase, 'Default', 'Network', 'Cookies'), accountType: 'work' },
132
- { path: join(appdata, 'Microsoft', 'Teams', 'Cookies'), accountType: 'work' },
154
+ { path: join(ebWebViewBase, 'WV2Profile_tfw', 'Cookies'), accountType: 'work', accountTypeKnown: true },
155
+ {
156
+ path: join(ebWebViewBase, 'WV2Profile_tfw', 'Network', 'Cookies'),
157
+ accountType: 'work',
158
+ accountTypeKnown: true,
159
+ },
160
+ {
161
+ path: join(ebWebViewBase, 'WV2Profile_tfl', 'Cookies'),
162
+ accountType: 'personal',
163
+ accountTypeKnown: true,
164
+ },
165
+ {
166
+ path: join(ebWebViewBase, 'WV2Profile_tfl', 'Network', 'Cookies'),
167
+ accountType: 'personal',
168
+ accountTypeKnown: true,
169
+ },
170
+ { path: join(ebWebViewBase, 'Default', 'Cookies'), accountType: 'work', accountTypeKnown: false },
171
+ { path: join(ebWebViewBase, 'Default', 'Network', 'Cookies'), accountType: 'work', accountTypeKnown: false },
172
+ { path: join(appdata, 'Microsoft', 'Teams', 'Cookies'), accountType: 'work', accountTypeKnown: false },
133
173
  ]
134
174
  }
135
175
  default:
@@ -145,11 +185,16 @@ export class TeamsTokenExtractor {
145
185
  if (!browserBase) continue
146
186
 
147
187
  for (const profileDir of discoverBrowserProfileDirs(browserBase)) {
148
- paths.push({ path: join(profileDir, 'Cookies'), accountType: 'work' })
149
- paths.push({ path: join(profileDir, 'Network', 'Cookies'), accountType: 'work' })
188
+ paths.push({ path: join(profileDir, 'Cookies'), accountType: 'work', accountTypeKnown: false })
189
+ paths.push({ path: join(profileDir, 'Network', 'Cookies'), accountType: 'work', accountTypeKnown: false })
150
190
  }
151
191
  }
152
192
 
193
+ for (const profileDir of getAgentBrowserProfileDirs({ customProfileDirs: this.customBrowserProfileDirs })) {
194
+ paths.push({ path: join(profileDir, 'Cookies'), accountType: 'work', accountTypeKnown: false })
195
+ paths.push({ path: join(profileDir, 'Network', 'Cookies'), accountType: 'work', accountTypeKnown: false })
196
+ }
197
+
153
198
  return paths
154
199
  }
155
200
 
@@ -189,8 +234,13 @@ export class TeamsTokenExtractor {
189
234
  }
190
235
 
191
236
  isValidSkypeToken(token: string): boolean {
192
- if (!token || token.length === 0) return false
193
- return token.length >= 50
237
+ if (!token || token.length < 50) return false
238
+ // Real skype tokens are JWT-shaped or long base64url-ish strings. Reject anything
239
+ // containing XML/CLIXML artifacts (e.g. leaked PowerShell progress stream) or
240
+ // other non-token characters up front to stop garbage from being reported as valid.
241
+ if (/[<>{}\s"'`]/.test(token)) return false
242
+ if (token.startsWith('eyJ')) return /^[A-Za-z0-9._-]+$/.test(token)
243
+ return /^[A-Za-z0-9._~+/=-]+$/.test(token)
194
244
  }
195
245
 
196
246
  isEncryptedValue(value: Buffer): boolean {
@@ -208,12 +258,13 @@ export class TeamsTokenExtractor {
208
258
 
209
259
  private async extractFromCookiesDB(): Promise<ExtractedTeamsToken[]> {
210
260
  const results: ExtractedTeamsToken[] = []
211
- const seenAccountTypes = new Set<TeamsAccountType>()
261
+ const seenKnownAccountTypes = new Set<TeamsAccountType>()
262
+ const seenTokens = new Set<string>()
212
263
  const allPaths = this.getTeamsCookiesPaths()
213
264
 
214
265
  this.debug(`Scanning ${allPaths.length} candidate cookie path(s)`)
215
266
 
216
- for (const { path: dbPath, accountType } of allPaths) {
267
+ for (const { path: dbPath, accountType, accountTypeKnown } of allPaths) {
217
268
  if (!dbPath) continue
218
269
 
219
270
  if (!existsSync(dbPath)) {
@@ -221,22 +272,34 @@ export class TeamsTokenExtractor {
221
272
  continue
222
273
  }
223
274
 
224
- if (seenAccountTypes.has(accountType)) {
275
+ if (accountTypeKnown && seenKnownAccountTypes.has(accountType)) {
225
276
  this.debug(` [skip] ${dbPath} (already have ${accountType} account)`)
226
277
  continue
227
278
  }
228
279
 
229
- this.debug(` [try] ${dbPath} (${accountType})`)
280
+ const typeLabel = accountTypeKnown ? accountType : `${accountType}?`
281
+ this.debug(` [try] ${dbPath} (${typeLabel})`)
230
282
 
231
283
  const token = await this.copyAndExtract(dbPath)
232
- if (token && this.isValidSkypeToken(token)) {
233
- this.debug(` [ok] Extracted valid token (${token.length} chars)`)
234
- results.push({ token, accountType })
235
- seenAccountTypes.add(accountType)
236
- } else if (token) {
237
- this.debug(` [fail] Token too short (${token.length} chars, need >=50)`)
238
- } else {
239
- this.debug(` [fail] No token extracted`)
284
+ if (!token || !this.isValidSkypeToken(token)) {
285
+ if (token) {
286
+ this.debug(` [fail] Token too short (${token.length} chars, need >=50)`)
287
+ } else {
288
+ this.debug(` [fail] No token extracted`)
289
+ }
290
+ continue
291
+ }
292
+
293
+ if (seenTokens.has(token)) {
294
+ this.debug(` [skip] Duplicate token (already extracted from another path)`)
295
+ continue
296
+ }
297
+
298
+ this.debug(` [ok] Extracted valid token (${token.length} chars)`)
299
+ results.push({ token, accountType, accountTypeKnown })
300
+ seenTokens.add(token)
301
+ if (accountTypeKnown) {
302
+ seenKnownAccountTypes.add(accountType)
240
303
  }
241
304
  }
242
305
 
@@ -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
  TeamsChannelSchema,
@@ -13,7 +13,7 @@ import {
13
13
  } from './types'
14
14
 
15
15
  // TeamsTeamSchema tests
16
- test('TeamsTeamSchema validates correct team', () => {
16
+ it('TeamsTeamSchema validates correct team', () => {
17
17
  const result = TeamsTeamSchema.safeParse({
18
18
  id: '19:abc123@thread.tacv2',
19
19
  name: 'Test Team',
@@ -21,7 +21,7 @@ test('TeamsTeamSchema validates correct team', () => {
21
21
  expect(result.success).toBe(true)
22
22
  })
23
23
 
24
- test('TeamsTeamSchema validates team with optional description', () => {
24
+ it('TeamsTeamSchema validates team with optional description', () => {
25
25
  const result = TeamsTeamSchema.safeParse({
26
26
  id: '19:abc123@thread.tacv2',
27
27
  name: 'Test Team',
@@ -30,14 +30,14 @@ test('TeamsTeamSchema validates team with optional description', () => {
30
30
  expect(result.success).toBe(true)
31
31
  })
32
32
 
33
- test('TeamsTeamSchema rejects missing id', () => {
33
+ it('TeamsTeamSchema rejects missing id', () => {
34
34
  const result = TeamsTeamSchema.safeParse({
35
35
  name: 'Test Team',
36
36
  })
37
37
  expect(result.success).toBe(false)
38
38
  })
39
39
 
40
- test('TeamsTeamSchema rejects missing name', () => {
40
+ it('TeamsTeamSchema rejects missing name', () => {
41
41
  const result = TeamsTeamSchema.safeParse({
42
42
  id: '19:abc123@thread.tacv2',
43
43
  })
@@ -45,7 +45,7 @@ test('TeamsTeamSchema rejects missing name', () => {
45
45
  })
46
46
 
47
47
  // TeamsChannelSchema tests
48
- test('TeamsChannelSchema validates correct channel', () => {
48
+ it('TeamsChannelSchema validates correct channel', () => {
49
49
  const result = TeamsChannelSchema.safeParse({
50
50
  id: '19:channel123@thread.tacv2',
51
51
  team_id: '19:abc123@thread.tacv2',
@@ -55,7 +55,7 @@ test('TeamsChannelSchema validates correct channel', () => {
55
55
  expect(result.success).toBe(true)
56
56
  })
57
57
 
58
- test('TeamsChannelSchema rejects missing required fields', () => {
58
+ it('TeamsChannelSchema rejects missing required fields', () => {
59
59
  const result = TeamsChannelSchema.safeParse({
60
60
  id: '19:channel123@thread.tacv2',
61
61
  name: 'General',
@@ -64,7 +64,7 @@ test('TeamsChannelSchema rejects missing required fields', () => {
64
64
  })
65
65
 
66
66
  // TeamsMessageSchema tests
67
- test('TeamsMessageSchema validates correct message', () => {
67
+ it('TeamsMessageSchema validates correct message', () => {
68
68
  const result = TeamsMessageSchema.safeParse({
69
69
  id: '1234567890123',
70
70
  channel_id: '19:channel123@thread.tacv2',
@@ -78,7 +78,7 @@ test('TeamsMessageSchema validates correct message', () => {
78
78
  expect(result.success).toBe(true)
79
79
  })
80
80
 
81
- test('TeamsMessageSchema rejects missing required fields', () => {
81
+ it('TeamsMessageSchema rejects missing required fields', () => {
82
82
  const result = TeamsMessageSchema.safeParse({
83
83
  id: '1234567890123',
84
84
  channel_id: '19:channel123@thread.tacv2',
@@ -88,7 +88,7 @@ test('TeamsMessageSchema rejects missing required fields', () => {
88
88
  })
89
89
 
90
90
  // TeamsUserSchema tests
91
- test('TeamsUserSchema validates correct user', () => {
91
+ it('TeamsUserSchema validates correct user', () => {
92
92
  const result = TeamsUserSchema.safeParse({
93
93
  id: 'user123',
94
94
  displayName: 'Test User',
@@ -96,7 +96,7 @@ test('TeamsUserSchema validates correct user', () => {
96
96
  expect(result.success).toBe(true)
97
97
  })
98
98
 
99
- test('TeamsUserSchema validates user with optional fields', () => {
99
+ it('TeamsUserSchema validates user with optional fields', () => {
100
100
  const result = TeamsUserSchema.safeParse({
101
101
  id: 'user123',
102
102
  displayName: 'Test User',
@@ -106,7 +106,7 @@ test('TeamsUserSchema validates user with optional fields', () => {
106
106
  expect(result.success).toBe(true)
107
107
  })
108
108
 
109
- test('TeamsUserSchema rejects missing required fields', () => {
109
+ it('TeamsUserSchema rejects missing required fields', () => {
110
110
  const result = TeamsUserSchema.safeParse({
111
111
  id: 'user123',
112
112
  })
@@ -114,7 +114,7 @@ test('TeamsUserSchema rejects missing required fields', () => {
114
114
  })
115
115
 
116
116
  // TeamsReactionSchema tests
117
- test('TeamsReactionSchema validates correct reaction', () => {
117
+ it('TeamsReactionSchema validates correct reaction', () => {
118
118
  const result = TeamsReactionSchema.safeParse({
119
119
  emoji: 'like',
120
120
  count: 5,
@@ -122,7 +122,7 @@ test('TeamsReactionSchema validates correct reaction', () => {
122
122
  expect(result.success).toBe(true)
123
123
  })
124
124
 
125
- test('TeamsReactionSchema rejects missing required fields', () => {
125
+ it('TeamsReactionSchema rejects missing required fields', () => {
126
126
  const result = TeamsReactionSchema.safeParse({
127
127
  emoji: 'like',
128
128
  })
@@ -130,7 +130,7 @@ test('TeamsReactionSchema rejects missing required fields', () => {
130
130
  })
131
131
 
132
132
  // TeamsFileSchema tests
133
- test('TeamsFileSchema validates correct file', () => {
133
+ it('TeamsFileSchema validates correct file', () => {
134
134
  const result = TeamsFileSchema.safeParse({
135
135
  id: 'file123',
136
136
  name: 'document.pdf',
@@ -140,7 +140,7 @@ test('TeamsFileSchema validates correct file', () => {
140
140
  expect(result.success).toBe(true)
141
141
  })
142
142
 
143
- test('TeamsFileSchema validates file with optional contentType', () => {
143
+ it('TeamsFileSchema validates file with optional contentType', () => {
144
144
  const result = TeamsFileSchema.safeParse({
145
145
  id: 'file123',
146
146
  name: 'document.pdf',
@@ -151,7 +151,7 @@ test('TeamsFileSchema validates file with optional contentType', () => {
151
151
  expect(result.success).toBe(true)
152
152
  })
153
153
 
154
- test('TeamsFileSchema rejects missing required fields', () => {
154
+ it('TeamsFileSchema rejects missing required fields', () => {
155
155
  const result = TeamsFileSchema.safeParse({
156
156
  id: 'file123',
157
157
  name: 'document.pdf',
@@ -160,14 +160,14 @@ test('TeamsFileSchema rejects missing required fields', () => {
160
160
  })
161
161
 
162
162
  // TeamsCredentialsSchema tests
163
- test('TeamsCredentialsSchema validates correct credentials', () => {
163
+ it('TeamsCredentialsSchema validates correct credentials', () => {
164
164
  const result = TeamsCredentialsSchema.safeParse({
165
165
  token: 'skypetoken_value',
166
166
  })
167
167
  expect(result.success).toBe(true)
168
168
  })
169
169
 
170
- test('TeamsCredentialsSchema validates credentials with cookie', () => {
170
+ it('TeamsCredentialsSchema validates credentials with cookie', () => {
171
171
  const result = TeamsCredentialsSchema.safeParse({
172
172
  token: 'skypetoken_value',
173
173
  cookie: 'skypetoken_asm_value',
@@ -175,13 +175,13 @@ test('TeamsCredentialsSchema validates credentials with cookie', () => {
175
175
  expect(result.success).toBe(true)
176
176
  })
177
177
 
178
- test('TeamsCredentialsSchema rejects missing token', () => {
178
+ it('TeamsCredentialsSchema rejects missing token', () => {
179
179
  const result = TeamsCredentialsSchema.safeParse({})
180
180
  expect(result.success).toBe(false)
181
181
  })
182
182
 
183
183
  // TeamsConfigSchema tests
184
- test('TeamsConfigSchema validates correct config', () => {
184
+ it('TeamsConfigSchema validates correct config', () => {
185
185
  const result = TeamsConfigSchema.safeParse({
186
186
  current_account: 'work',
187
187
  accounts: {
@@ -196,7 +196,7 @@ test('TeamsConfigSchema validates correct config', () => {
196
196
  expect(result.success).toBe(true)
197
197
  })
198
198
 
199
- test('TeamsConfigSchema validates config with multiple accounts', () => {
199
+ it('TeamsConfigSchema validates config with multiple accounts', () => {
200
200
  const result = TeamsConfigSchema.safeParse({
201
201
  current_account: 'work',
202
202
  accounts: {
@@ -225,7 +225,7 @@ test('TeamsConfigSchema validates config with multiple accounts', () => {
225
225
  expect(result.success).toBe(true)
226
226
  })
227
227
 
228
- test('TeamsConfigSchema rejects invalid region', () => {
228
+ it('TeamsConfigSchema rejects invalid region', () => {
229
229
  const result = TeamsConfigSchema.safeParse({
230
230
  current_account: 'work',
231
231
  accounts: {
@@ -241,7 +241,7 @@ test('TeamsConfigSchema rejects invalid region', () => {
241
241
  expect(result.success).toBe(false)
242
242
  })
243
243
 
244
- test('TeamsConfigSchema rejects missing required fields', () => {
244
+ it('TeamsConfigSchema rejects missing required fields', () => {
245
245
  const result = TeamsConfigSchema.safeParse({
246
246
  current_account: null,
247
247
  })
@@ -249,14 +249,14 @@ test('TeamsConfigSchema rejects missing required fields', () => {
249
249
  })
250
250
 
251
251
  // TeamsError tests
252
- test('TeamsError has correct name and code', () => {
252
+ it('TeamsError has correct name and code', () => {
253
253
  const error = new TeamsError('Test error', 'TEST_CODE')
254
254
  expect(error.name).toBe('TeamsError')
255
255
  expect(error.message).toBe('Test error')
256
256
  expect(error.code).toBe('TEST_CODE')
257
257
  })
258
258
 
259
- test('TeamsError is instance of Error', () => {
259
+ it('TeamsError is instance of Error', () => {
260
260
  const error = new TeamsError('Test error', 'TEST_CODE')
261
261
  expect(error instanceof Error).toBe(true)
262
262
  })
@@ -1,4 +1,4 @@
1
- import { beforeEach, describe, expect, test } from 'bun:test'
1
+ import { beforeEach, describe, expect, it } from 'bun:test'
2
2
 
3
3
  import { getTelegramAppCredentials } from './app-config'
4
4
 
@@ -16,7 +16,7 @@ describe('telegram app config', () => {
16
16
  }
17
17
  })
18
18
 
19
- test('returns env credentials when provided', () => {
19
+ it('returns env credentials when provided', () => {
20
20
  process.env.AGENT_TELEGRAM_API_ID = '12345'
21
21
  process.env.AGENT_TELEGRAM_API_HASH = 'secret'
22
22
 
@@ -27,11 +27,11 @@ describe('telegram app config', () => {
27
27
  })
28
28
  })
29
29
 
30
- test('returns none when nothing is configured', () => {
30
+ it('returns none when nothing is configured', () => {
31
31
  expect(getTelegramAppCredentials()).toEqual({ source: 'none' })
32
32
  })
33
33
 
34
- test('rejects malformed api_id like "123abc"', () => {
34
+ it('rejects malformed api_id like "123abc"', () => {
35
35
  const prev = process.env.AGENT_TELEGRAM_API_ID
36
36
  process.env.AGENT_TELEGRAM_API_ID = '123abc'
37
37
  process.env.AGENT_TELEGRAM_API_HASH = 'abc123'
@@ -1,21 +1,21 @@
1
- import { describe, expect, test } from 'bun:test'
1
+ import { describe, expect, it } from 'bun:test'
2
2
 
3
3
  import { findFuzzyChats, mergeChats, normalizeChatSearchText } from './chat-utils'
4
4
 
5
5
  describe('normalizeChatSearchText', () => {
6
- test('lowercases and strips spaces', () => {
6
+ it('lowercases and strips spaces', () => {
7
7
  expect(normalizeChatSearchText('Hello World')).toBe('helloworld')
8
8
  })
9
9
 
10
- test('strips special chars', () => {
10
+ it('strips special chars', () => {
11
11
  expect(normalizeChatSearchText('ops-alerts!')).toBe('opsalerts')
12
12
  })
13
13
 
14
- test('handles empty string', () => {
14
+ it('handles empty string', () => {
15
15
  expect(normalizeChatSearchText('')).toBe('')
16
16
  })
17
17
 
18
- test('preserves unicode letters and digits', () => {
18
+ it('preserves unicode letters and digits', () => {
19
19
  const result = normalizeChatSearchText('안녕 World 123')
20
20
  expect(result).toContain('안녕')
21
21
  expect(result).toContain('world')
@@ -30,26 +30,26 @@ describe('findFuzzyChats', () => {
30
30
  { id: 3, title: 'ops-team', type: 'group' },
31
31
  ] as any[]
32
32
 
33
- test('finds partial matches case-insensitively', () => {
33
+ it('finds partial matches case-insensitively', () => {
34
34
  const result = findFuzzyChats(chats, 'ops', 10)
35
35
  expect(result.map((c) => c.id)).toContain(1)
36
36
  expect(result.map((c) => c.id)).toContain(3)
37
37
  })
38
38
 
39
- test('returns empty for no matches', () => {
39
+ it('returns empty for no matches', () => {
40
40
  expect(findFuzzyChats(chats, 'zzz', 10)).toHaveLength(0)
41
41
  })
42
42
 
43
- test('returns empty for empty query', () => {
43
+ it('returns empty for empty query', () => {
44
44
  expect(findFuzzyChats(chats, '', 10)).toHaveLength(0)
45
45
  })
46
46
 
47
- test('respects limit', () => {
47
+ it('respects limit', () => {
48
48
  const result = findFuzzyChats(chats, 'o', 1)
49
49
  expect(result).toHaveLength(1)
50
50
  })
51
51
 
52
- test('does not match chats with empty normalized title', () => {
52
+ it('does not match chats with empty normalized title', () => {
53
53
  const chats = [{ id: 99, title: '---', type: 'group' }] as any[]
54
54
  expect(findFuzzyChats(chats, 'ops', 10)).toHaveLength(0)
55
55
  })
@@ -62,13 +62,13 @@ describe('mergeChats', () => {
62
62
  { id: 2, title: 'B', type: 'group' },
63
63
  ] as any[]
64
64
 
65
- test('deduplicates by id', () => {
65
+ it('deduplicates by id', () => {
66
66
  const result = mergeChats(a, b)
67
67
  expect(result).toHaveLength(2)
68
68
  expect(result.map((c) => c.id)).toEqual([1, 2])
69
69
  })
70
70
 
71
- test('primary takes precedence order', () => {
71
+ it('gives primary array precedence in order', () => {
72
72
  const result = mergeChats(a, b)
73
73
  expect(result[0].id).toBe(1)
74
74
  })
@@ -1,4 +1,4 @@
1
- import { describe, expect, mock, test } from 'bun:test'
1
+ import { describe, expect, mock, it } from 'bun:test'
2
2
 
3
3
  import { TelegramTdlibClient } from './client'
4
4
  import type { TelegramAccount, TelegramAccountPaths } from './types'
@@ -46,7 +46,7 @@ function pushAuthReady(events: any[], extra: string) {
46
46
  }
47
47
 
48
48
  describe('listChats', () => {
49
- test('loads chats across multiple loadChats calls until 404', async () => {
49
+ it('loads chats across multiple loadChats calls until 404', async () => {
50
50
  let loadChatsCallCount = 0
51
51
  const allChatIds = [1, 2, 3, 4, 5]
52
52
 
@@ -116,7 +116,7 @@ describe('listChats', () => {
116
116
  expect(loadChatsCallCount).toBe(3)
117
117
  })
118
118
 
119
- test('stops loading when enough chats are cached before 404', async () => {
119
+ it('stops loading when enough chats are cached before 404', async () => {
120
120
  let loadChatsCallCount = 0
121
121
 
122
122
  const { client } = createMockClient((request, events) => {
@@ -164,7 +164,7 @@ describe('listChats', () => {
164
164
  })
165
165
 
166
166
  describe('sendMessage confirmation', () => {
167
- test('returns confirmed message id when updateMessageSendSucceeded arrives', async () => {
167
+ it('returns confirmed message id when updateMessageSendSucceeded arrives', async () => {
168
168
  const tempId = 100
169
169
  const serverId = 999
170
170
  const events: any[] = []