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, mock, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, mock, it } from 'bun:test'
2
2
  import { mkdtemp, rm, writeFile } from 'node:fs/promises'
3
3
  import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
@@ -18,11 +18,11 @@ describe('WebexCredentialManager', () => {
18
18
  await rm(tempDir, { recursive: true, force: true })
19
19
  })
20
20
 
21
- test('loadConfig returns null when no file exists', async () => {
21
+ it('loadConfig returns null when no file exists', async () => {
22
22
  expect(await credManager.loadConfig()).toBeNull()
23
23
  })
24
24
 
25
- test('saveConfig + loadConfig round trip with OAuth tokens', async () => {
25
+ it('saveConfig and loadConfig round-trip OAuth tokens', async () => {
26
26
  const config = {
27
27
  accessToken: 'test-access-token',
28
28
  refreshToken: 'test-refresh-token',
@@ -33,7 +33,7 @@ describe('WebexCredentialManager', () => {
33
33
  expect(loaded).toEqual(config)
34
34
  })
35
35
 
36
- test('getToken returns accessToken when not expired', async () => {
36
+ it('getToken returns accessToken when not expired', async () => {
37
37
  await credManager.saveConfig({
38
38
  accessToken: 'valid-token',
39
39
  refreshToken: 'refresh',
@@ -43,7 +43,7 @@ describe('WebexCredentialManager', () => {
43
43
  expect(token).toBe('valid-token')
44
44
  })
45
45
 
46
- test('getToken returns null when expired and no refresh available', async () => {
46
+ it('getToken returns null when expired and no refresh available', async () => {
47
47
  await credManager.saveConfig({
48
48
  accessToken: 'expired-token',
49
49
  refreshToken: 'bad-refresh',
@@ -53,7 +53,7 @@ describe('WebexCredentialManager', () => {
53
53
  expect(token).toBeNull()
54
54
  })
55
55
 
56
- test('getToken auto-refreshes expired token', async () => {
56
+ it('getToken auto-refreshes expired token', async () => {
57
57
  const originalFetch = globalThis.fetch
58
58
  globalThis.fetch = mock(() =>
59
59
  Promise.resolve(
@@ -87,7 +87,7 @@ describe('WebexCredentialManager', () => {
87
87
  globalThis.fetch = originalFetch
88
88
  })
89
89
 
90
- test('requestDeviceCode calls device authorize endpoint', async () => {
90
+ it('requestDeviceCode calls device authorize endpoint', async () => {
91
91
  const originalFetch = globalThis.fetch
92
92
  globalThis.fetch = mock(() =>
93
93
  Promise.resolve(
@@ -114,7 +114,7 @@ describe('WebexCredentialManager', () => {
114
114
  globalThis.fetch = originalFetch
115
115
  })
116
116
 
117
- test('requestDeviceCode throws on failure', async () => {
117
+ it('requestDeviceCode throws on failure', async () => {
118
118
  const originalFetch = globalThis.fetch
119
119
  globalThis.fetch = mock(() =>
120
120
  Promise.resolve(new Response('{"error":"invalid_client"}', { status: 400 })),
@@ -125,7 +125,7 @@ describe('WebexCredentialManager', () => {
125
125
  globalThis.fetch = originalFetch
126
126
  })
127
127
 
128
- test('pollDeviceToken polls until authorized', async () => {
128
+ it('pollDeviceToken polls until authorized', async () => {
129
129
  const originalFetch = globalThis.fetch
130
130
  let callCount = 0
131
131
  globalThis.fetch = mock(() => {
@@ -152,7 +152,7 @@ describe('WebexCredentialManager', () => {
152
152
  globalThis.fetch = originalFetch
153
153
  })
154
154
 
155
- test('clearCredentials removes the file', async () => {
155
+ it('clearCredentials removes the file', async () => {
156
156
  await credManager.saveConfig({
157
157
  accessToken: 'token',
158
158
  refreshToken: 'refresh',
@@ -162,11 +162,11 @@ describe('WebexCredentialManager', () => {
162
162
  expect(await credManager.loadConfig()).toBeNull()
163
163
  })
164
164
 
165
- test('clearCredentials does nothing when no file', async () => {
165
+ it('clearCredentials does nothing when no file', async () => {
166
166
  await credManager.clearCredentials() // Should not throw
167
167
  })
168
168
 
169
- test('credentials file has 0o600 permissions', async () => {
169
+ it('saves credentials file with 0o600 permissions', async () => {
170
170
  await credManager.saveConfig({
171
171
  accessToken: 'token',
172
172
  refreshToken: 'refresh',
@@ -179,7 +179,7 @@ describe('WebexCredentialManager', () => {
179
179
  expect(mode).toBe(0o600)
180
180
  })
181
181
 
182
- test('pollDeviceToken with undefined clientSecret uses empty Basic auth', async () => {
182
+ it('pollDeviceToken with undefined clientSecret uses empty Basic auth', async () => {
183
183
  const originalFetch = globalThis.fetch
184
184
  let capturedAuth: string | null = null
185
185
  globalThis.fetch = mock((url: string, init?: RequestInit) => {
@@ -202,7 +202,7 @@ describe('WebexCredentialManager', () => {
202
202
  globalThis.fetch = originalFetch
203
203
  })
204
204
 
205
- test('pollDeviceToken does not auto-save config', async () => {
205
+ it('pollDeviceToken does not auto-save config', async () => {
206
206
  const originalFetch = globalThis.fetch
207
207
  globalThis.fetch = mock(() =>
208
208
  Promise.resolve(
@@ -225,7 +225,7 @@ describe('WebexCredentialManager', () => {
225
225
  globalThis.fetch = originalFetch
226
226
  })
227
227
 
228
- test('getToken returns null when expired and no client credentials available', async () => {
228
+ it('getToken returns null when expired and no client credentials available', async () => {
229
229
  await credManager.saveConfig({
230
230
  accessToken: 'expired-token',
231
231
  refreshToken: 'valid-refresh',
@@ -236,7 +236,7 @@ describe('WebexCredentialManager', () => {
236
236
  expect(token).toBeNull()
237
237
  })
238
238
 
239
- test('getToken returns manual token without attempting refresh', async () => {
239
+ it('getToken returns manual token without attempting refresh', async () => {
240
240
  await credManager.saveConfig({
241
241
  accessToken: 'my-bot-token',
242
242
  refreshToken: '',
@@ -248,7 +248,7 @@ describe('WebexCredentialManager', () => {
248
248
  expect(token).toBe('my-bot-token')
249
249
  })
250
250
 
251
- test('getToken uses stored clientId/clientSecret for refresh', async () => {
251
+ it('getToken uses stored clientId/clientSecret for refresh', async () => {
252
252
  const originalFetch = globalThis.fetch
253
253
  globalThis.fetch = mock(() =>
254
254
  Promise.resolve(
@@ -277,7 +277,7 @@ describe('WebexCredentialManager', () => {
277
277
  globalThis.fetch = originalFetch
278
278
  })
279
279
 
280
- test('saveConfig persists clientId and clientSecret', async () => {
280
+ it('saveConfig persists clientId and clientSecret', async () => {
281
281
  await credManager.saveConfig({
282
282
  accessToken: 'token',
283
283
  refreshToken: 'refresh',
@@ -291,7 +291,7 @@ describe('WebexCredentialManager', () => {
291
291
  expect(loaded?.clientSecret).toBe('my-client-secret')
292
292
  })
293
293
 
294
- test('getToken tries refresh for expired extracted tokens', async () => {
294
+ it('getToken tries refresh for expired extracted tokens', async () => {
295
295
  const originalFetch = globalThis.fetch
296
296
  globalThis.fetch = mock(() =>
297
297
  Promise.resolve(
@@ -323,7 +323,7 @@ describe('WebexCredentialManager', () => {
323
323
  globalThis.fetch = originalFetch
324
324
  })
325
325
 
326
- test('getToken returns expired extracted token when refresh fails', async () => {
326
+ it('getToken returns expired extracted token when refresh fails', async () => {
327
327
  const originalFetch = globalThis.fetch
328
328
  globalThis.fetch = mock(() =>
329
329
  Promise.resolve(new Response('{"error":"invalid_grant"}', { status: 400 })),
@@ -342,7 +342,7 @@ describe('WebexCredentialManager', () => {
342
342
  globalThis.fetch = originalFetch
343
343
  })
344
344
 
345
- test('getToken returns non-expired extracted token without refresh', async () => {
345
+ it('getToken returns non-expired extracted token without refresh', async () => {
346
346
  await credManager.saveConfig({
347
347
  accessToken: 'valid-extracted-token',
348
348
  refreshToken: 'refresh',
@@ -354,7 +354,7 @@ describe('WebexCredentialManager', () => {
354
354
  expect(token).toBe('valid-extracted-token')
355
355
  })
356
356
 
357
- test('loadConfig backward compat — old config without clientId/clientSecret', async () => {
357
+ it('loadConfig handles old config without clientId/clientSecret', async () => {
358
358
  // Write raw JSON without clientId/clientSecret fields
359
359
  const credPath = join(tempDir, 'webex-credentials.json')
360
360
  await writeFile(
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from 'bun:test'
1
+ import { describe, expect, it } from 'bun:test'
2
2
 
3
3
  import * as jose from 'node-jose'
4
4
 
@@ -23,7 +23,7 @@ const createKeyring = async (keyUri: string) => {
23
23
  describe('WebexEncryptionService', () => {
24
24
  const keyUri = 'kms://kms-aore.wbx2.com/keys/7819829b-5e0d-4139-9cad-1b6fe7aee533'
25
25
 
26
- test('encryptText emits JWE with alg, enc, and kid JOSE headers', async () => {
26
+ it('encryptText emits JWE with alg, enc, and kid JOSE headers', async () => {
27
27
  const service = await createKeyring(keyUri)
28
28
 
29
29
  const jwe = await service.encryptText(keyUri, 'hello world')
@@ -35,7 +35,7 @@ describe('WebexEncryptionService', () => {
35
35
  expect(header.kid).toBe(keyUri)
36
36
  })
37
37
 
38
- test('encryptText returns null when key is unknown', async () => {
38
+ it('encryptText returns null when key is unknown', async () => {
39
39
  const service = await createKeyring(keyUri)
40
40
 
41
41
  const jwe = await service.encryptText('kms://other/keys/missing', 'hello')
@@ -43,7 +43,7 @@ describe('WebexEncryptionService', () => {
43
43
  expect(jwe).toBeNull()
44
44
  })
45
45
 
46
- test('decryptText round-trips plaintext encrypted by encryptText', async () => {
46
+ it('decryptText round-trips plaintext encrypted by encryptText', async () => {
47
47
  const service = await createKeyring(keyUri)
48
48
 
49
49
  const jwe = await service.encryptText(keyUri, 'round trip')
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, spyOn, it } from 'bun:test'
2
2
 
3
3
  import { WebexClient } from './client'
4
4
  import { WebexCredentialManager } from './credential-manager'
@@ -33,7 +33,7 @@ afterEach(() => {
33
33
  })
34
34
 
35
35
  describe('ensureWebexAuth', () => {
36
- test('does nothing when no config stored', async () => {
36
+ it('does nothing when no config stored', async () => {
37
37
  // given
38
38
  loadConfigSpy.mockResolvedValue(null)
39
39
 
@@ -45,7 +45,7 @@ describe('ensureWebexAuth', () => {
45
45
  expect(testAuthSpy).not.toHaveBeenCalled()
46
46
  })
47
47
 
48
- test('validates token when stored', async () => {
48
+ it('validates token when stored', async () => {
49
49
  // given
50
50
  loadConfigSpy.mockResolvedValue({
51
51
  accessToken: 'test-webex-token',
@@ -65,7 +65,7 @@ describe('ensureWebexAuth', () => {
65
65
  expect(testAuthSpy).toHaveBeenCalled()
66
66
  })
67
67
 
68
- test('does not throw when token validation fails', async () => {
68
+ it('does not throw when token validation fails', async () => {
69
69
  // given
70
70
  loadConfigSpy.mockResolvedValue({
71
71
  accessToken: 'invalid-token',
@@ -79,7 +79,7 @@ describe('ensureWebexAuth', () => {
79
79
  await expect(ensureWebexAuth()).resolves.toBeUndefined()
80
80
  })
81
81
 
82
- test('does not throw when credential manager fails', async () => {
82
+ it('does not throw when credential manager fails', async () => {
83
83
  // given
84
84
  getTokenSpy.mockRejectedValue(new Error('Disk read error'))
85
85
 
@@ -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 * as webex from './index'
4
4
 
5
5
  describe('webex barrel exports', () => {
6
- test('exports WebexClient', () => {
6
+ it('exports WebexClient', () => {
7
7
  expect(webex.WebexClient).toBeDefined()
8
8
  })
9
9
 
10
- test('exports WebexCredentialManager', () => {
10
+ it('exports WebexCredentialManager', () => {
11
11
  expect(webex.WebexCredentialManager).toBeDefined()
12
12
  })
13
13
 
14
- test('exports WebexError', () => {
14
+ it('exports WebexError', () => {
15
15
  expect(webex.WebexError).toBeDefined()
16
16
  })
17
17
 
18
- test('exports Zod schemas', () => {
18
+ it('exports Zod schemas', () => {
19
19
  expect(webex.WebexSpaceSchema).toBeDefined()
20
20
  expect(webex.WebexMessageSchema).toBeDefined()
21
21
  expect(webex.WebexPersonSchema).toBeDefined()
@@ -1,141 +1,141 @@
1
- import { describe, expect, test } from 'bun:test'
1
+ import { describe, expect, it } from 'bun:test'
2
2
 
3
3
  import { markdownToHtml, stripMarkdown } from './markdown-to-html'
4
4
 
5
5
  describe('markdownToHtml', () => {
6
- test('converts bold text', () => {
6
+ it('converts bold text', () => {
7
7
  expect(markdownToHtml('**bold**')).toBe('<strong>bold</strong>')
8
8
  })
9
9
 
10
- test('converts italic text', () => {
10
+ it('converts italic text', () => {
11
11
  expect(markdownToHtml('_italic_')).toBe('<em>italic</em>')
12
12
  })
13
13
 
14
- test('does not italicize mid-word underscores', () => {
14
+ it('does not italicize mid-word underscores', () => {
15
15
  expect(markdownToHtml('some_variable_name')).toBe('some_variable_name')
16
16
  })
17
17
 
18
- test('converts bold and italic text', () => {
18
+ it('converts bold and italic text', () => {
19
19
  expect(markdownToHtml('***both***')).toBe('<strong><em>both</em></strong>')
20
20
  })
21
21
 
22
- test('converts inline code', () => {
22
+ it('converts inline code', () => {
23
23
  expect(markdownToHtml('Use `code` here')).toBe('Use <code>code</code> here')
24
24
  })
25
25
 
26
- test('converts code blocks with language', () => {
26
+ it('converts code blocks with language', () => {
27
27
  expect(markdownToHtml('```ts\nconst x = 1 < 2\n```')).toBe(
28
28
  '<pre><code class="language-ts">const x = 1 &lt; 2</code></pre>',
29
29
  )
30
30
  })
31
31
 
32
- test('converts code blocks without language', () => {
32
+ it('converts code blocks without language', () => {
33
33
  expect(markdownToHtml('```\nconst x = 1 & 2\n```')).toBe('<pre><code>const x = 1 &amp; 2</code></pre>')
34
34
  })
35
35
 
36
- test('does not process markdown inside code blocks', () => {
36
+ it('does not process markdown inside code blocks', () => {
37
37
  expect(markdownToHtml('```\n**bold** _italic_\n```')).toBe('<pre><code>**bold** _italic_</code></pre>')
38
38
  })
39
39
 
40
- test('converts links', () => {
40
+ it('converts links', () => {
41
41
  expect(markdownToHtml('[Webex](https://example.com?a=1&b=2)')).toBe(
42
42
  '<a href="https://example.com?a=1&amp;b=2">Webex</a>',
43
43
  )
44
44
  })
45
45
 
46
- test('strips unsafe javascript: URLs to plain text', () => {
46
+ it('strips unsafe javascript: URLs to plain text', () => {
47
47
  expect(markdownToHtml('[click](javascript:void)')).toBe('click')
48
48
  })
49
49
 
50
- test('strips unsafe data: URLs to plain text', () => {
50
+ it('strips unsafe data: URLs to plain text', () => {
51
51
  expect(markdownToHtml('[x](data:text/html,payload)')).toBe('x')
52
52
  })
53
53
 
54
- test('allows mailto: links', () => {
54
+ it('allows mailto: links', () => {
55
55
  expect(markdownToHtml('[email](mailto:a@b.com)')).toBe('<a href="mailto:a@b.com">email</a>')
56
56
  })
57
57
 
58
- test('escapes quotes in URLs to prevent attribute breakout', () => {
58
+ it('escapes quotes in URLs to prevent attribute breakout', () => {
59
59
  expect(markdownToHtml('[x](https://a.com?q="test")')).toBe('<a href="https://a.com?q=&quot;test&quot;">x</a>')
60
60
  })
61
61
 
62
- test('converts unordered lists', () => {
62
+ it('converts unordered lists', () => {
63
63
  expect(markdownToHtml('- one\n- two')).toBe('<ul><li>one</li><li>two</li></ul>')
64
64
  })
65
65
 
66
- test('converts ordered lists', () => {
66
+ it('converts ordered lists', () => {
67
67
  expect(markdownToHtml('1. one\n2. two')).toBe('<ol><li>one</li><li>two</li></ol>')
68
68
  })
69
69
 
70
- test('converts blockquotes', () => {
70
+ it('converts blockquotes', () => {
71
71
  expect(markdownToHtml('> one\n> two')).toBe('<blockquote>one<br/>two</blockquote>')
72
72
  })
73
73
 
74
- test('converts headings', () => {
74
+ it('converts headings', () => {
75
75
  expect(markdownToHtml('# one\n###### six')).toBe('<h1>one</h1><br/><br/><h6>six</h6>')
76
76
  })
77
77
 
78
- test('converts horizontal rules', () => {
78
+ it('converts horizontal rules', () => {
79
79
  expect(markdownToHtml('before\n---\nafter')).toBe('before<br/><br/><hr><br/><br/>after')
80
80
  })
81
81
 
82
- test('converts paragraph newlines to br', () => {
82
+ it('converts paragraph newlines to br', () => {
83
83
  expect(markdownToHtml('one\ntwo')).toBe('one<br/>two')
84
84
  })
85
85
 
86
- test('supports nested formatting', () => {
86
+ it('supports nested formatting', () => {
87
87
  expect(markdownToHtml('**bold _and italic_**')).toBe('<strong>bold <em>and italic</em></strong>')
88
88
  })
89
89
 
90
- test('escapes html special characters in text', () => {
90
+ it('escapes html special characters in text', () => {
91
91
  expect(markdownToHtml('5 < 7 & 8 > 3')).toBe('5 &lt; 7 &amp; 8 &gt; 3')
92
92
  })
93
93
 
94
- test('separates multiple paragraphs with br', () => {
94
+ it('separates multiple paragraphs with br', () => {
95
95
  expect(markdownToHtml('first\n\nsecond')).toBe('first<br/><br/>second')
96
96
  })
97
97
 
98
- test('renders mixed content', () => {
98
+ it('renders mixed content', () => {
99
99
  expect(markdownToHtml('Hello **team**\n\n- one\n- two\n\n```js\nconst x = 1\n```')).toBe(
100
100
  'Hello <strong>team</strong><br/><br/><ul><li>one</li><li>two</li></ul><br/><br/><pre><code class="language-js">const x = 1</code></pre>',
101
101
  )
102
102
  })
103
103
 
104
- test('returns empty string for empty input', () => {
104
+ it('returns empty string for empty input', () => {
105
105
  expect(markdownToHtml('')).toBe('')
106
106
  })
107
107
 
108
- test('returns plain text when there is no markdown', () => {
108
+ it('returns plain text when there is no markdown', () => {
109
109
  expect(markdownToHtml('hello world')).toBe('hello world')
110
110
  })
111
111
 
112
- test('preserves whitespace-only input', () => {
112
+ it('preserves whitespace-only input', () => {
113
113
  expect(markdownToHtml(' ')).toBe(' ')
114
114
  })
115
115
  })
116
116
 
117
117
  describe('stripMarkdown', () => {
118
- test('strips inline markdown syntax', () => {
118
+ it('strips inline markdown syntax', () => {
119
119
  expect(stripMarkdown('**bold** _italic_ `code`')).toBe('bold italic code')
120
120
  })
121
121
 
122
- test('strips links to their labels', () => {
122
+ it('strips links to their labels', () => {
123
123
  expect(stripMarkdown('[Webex](https://example.com)')).toBe('Webex')
124
124
  })
125
125
 
126
- test('strips block markdown syntax', () => {
126
+ it('strips block markdown syntax', () => {
127
127
  expect(stripMarkdown('# Title\n> quote\n- item\n1. first\n---')).toBe('Title\nquote\nitem\nfirst\n')
128
128
  })
129
129
 
130
- test('keeps code block content', () => {
130
+ it('keeps code block content', () => {
131
131
  expect(stripMarkdown('```ts\nconst x = 1\n```')).toBe('const x = 1')
132
132
  })
133
133
 
134
- test('handles nested formatting', () => {
134
+ it('handles nested formatting', () => {
135
135
  expect(stripMarkdown('**bold _and italic_**')).toBe('bold and italic')
136
136
  })
137
137
 
138
- test('returns plain text unchanged', () => {
138
+ it('returns plain text unchanged', () => {
139
139
  expect(stripMarkdown('hello world')).toBe('hello world')
140
140
  })
141
141
  })
@@ -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 { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3
3
  import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
@@ -49,7 +49,7 @@ describe('WebexTokenExtractor', () => {
49
49
  })
50
50
 
51
51
  describe('getBrowserProfileDirs', () => {
52
- test('returns correct paths for darwin', () => {
52
+ it('returns correct paths for darwin', () => {
53
53
  const extractor = new WebexTokenExtractor('darwin')
54
54
  const dirs = extractor.getBrowserProfileDirs()
55
55
 
@@ -60,12 +60,12 @@ describe('WebexTokenExtractor', () => {
60
60
  }
61
61
  })
62
62
 
63
- test('returns empty array for unsupported platform', () => {
63
+ it('returns empty array for unsupported platform', () => {
64
64
  const extractor = new WebexTokenExtractor('freebsd' as NodeJS.Platform)
65
65
  expect(extractor.getBrowserProfileDirs()).toEqual([])
66
66
  })
67
67
 
68
- test('discovers Default and Profile N directories', () => {
68
+ it('discovers Default and Profile N directories', () => {
69
69
  const defaultDir = createLevelDBDir(tempDir, 'Default')
70
70
  const profile1Dir = createLevelDBDir(tempDir, 'Profile 1')
71
71
  const profile2Dir = createLevelDBDir(tempDir, 'Profile 2')
@@ -78,7 +78,7 @@ describe('WebexTokenExtractor', () => {
78
78
  expect(dirs).toContain(profile2Dir)
79
79
  })
80
80
 
81
- test('skips non-profile directories', () => {
81
+ it('skips non-profile directories', () => {
82
82
  createLevelDBDir(tempDir, 'Default')
83
83
  mkdirSync(join(tempDir, 'Extensions', 'Local Storage', 'leveldb'), { recursive: true })
84
84
  mkdirSync(join(tempDir, 'Crashpad'), { recursive: true })
@@ -90,14 +90,14 @@ describe('WebexTokenExtractor', () => {
90
90
  expect(dirs[0]).toContain('Default')
91
91
  })
92
92
 
93
- test('returns empty when base dir does not exist', () => {
93
+ it('returns empty when base dir does not exist', () => {
94
94
  const extractor = new WebexTokenExtractor('darwin', undefined, join(tempDir, 'nonexistent'))
95
95
  expect(extractor.getBrowserProfileDirs()).toEqual([])
96
96
  })
97
97
  })
98
98
 
99
99
  describe('extract', () => {
100
- test('finds token from .log file', async () => {
100
+ it('finds token from .log file', async () => {
101
101
  const leveldbDir = createLevelDBDir(tempDir)
102
102
  const webexJson = makeWebexStorageJson()
103
103
  const entry = `_https://web.webex.com\x00webex-storage${webexJson}`
@@ -113,7 +113,7 @@ describe('WebexTokenExtractor', () => {
113
113
  expect(result!.deviceUrl).toBe('https://wdm-r.wbx2.com/wdm/api/v1/devices/test-device-id')
114
114
  })
115
115
 
116
- test('finds token from .ldb file', async () => {
116
+ it('finds token from .ldb file', async () => {
117
117
  const leveldbDir = createLevelDBDir(tempDir)
118
118
  const webexJson = makeWebexStorageJson()
119
119
  writeFileSync(join(leveldbDir, '000005.ldb'), `\x00\x00${webexJson}\x00\x00`)
@@ -125,12 +125,12 @@ describe('WebexTokenExtractor', () => {
125
125
  expect(result!.accessToken).toBe('ZDI3MGEyYzQtNmFlNS00NDNh_PF84_1eb65fdf-userId_orgId')
126
126
  })
127
127
 
128
- test('returns null when no browser dirs exist', async () => {
128
+ it('returns null when no browser dirs exist', async () => {
129
129
  const extractor = new WebexTokenExtractor('darwin', undefined, join(tempDir, 'nonexistent'))
130
130
  expect(await extractor.extract()).toBeNull()
131
131
  })
132
132
 
133
- test('returns null when LevelDB has no webex-storage data', async () => {
133
+ it('returns null when LevelDB has no webex-storage data', async () => {
134
134
  const leveldbDir = createLevelDBDir(tempDir)
135
135
  writeFileSync(join(leveldbDir, '000003.log'), 'some random data without webex tokens')
136
136
 
@@ -138,7 +138,7 @@ describe('WebexTokenExtractor', () => {
138
138
  expect(await extractor.extract()).toBeNull()
139
139
  })
140
140
 
141
- test('handles malformed JSON gracefully', async () => {
141
+ it('handles malformed JSON gracefully', async () => {
142
142
  const leveldbDir = createLevelDBDir(tempDir)
143
143
  writeFileSync(join(leveldbDir, '000003.log'), '{"Credentials": {"@": {"supertoken": {broken json')
144
144
 
@@ -146,7 +146,7 @@ describe('WebexTokenExtractor', () => {
146
146
  expect(await extractor.extract()).toBeNull()
147
147
  })
148
148
 
149
- test('extracts all fields from nested Credentials structure', async () => {
149
+ it('extracts all fields from nested Credentials structure', async () => {
150
150
  const expires = Date.now() + 7200000
151
151
  const leveldbDir = createLevelDBDir(tempDir)
152
152
  const webexJson = makeWebexStorageJson({
@@ -167,7 +167,7 @@ describe('WebexTokenExtractor', () => {
167
167
  expect(result!.deviceUrl).toBe('https://wdm-a.wbx2.com/wdm/api/v1/devices/abc-123')
168
168
  })
169
169
 
170
- test('extracts deviceUrl when Device field is present', async () => {
170
+ it('extracts deviceUrl when Device field is present', async () => {
171
171
  const leveldbDir = createLevelDBDir(tempDir)
172
172
  const webexJson = makeWebexStorageJson({
173
173
  deviceUrl: 'https://wdm-eu.wbx2.com/wdm/api/v1/devices/eu-device-id',
@@ -181,7 +181,7 @@ describe('WebexTokenExtractor', () => {
181
181
  expect(result!.deviceUrl).toBe('https://wdm-eu.wbx2.com/wdm/api/v1/devices/eu-device-id')
182
182
  })
183
183
 
184
- test('returns token without deviceUrl when Device field is absent', async () => {
184
+ it('returns token without deviceUrl when Device field is absent', async () => {
185
185
  const leveldbDir = createLevelDBDir(tempDir)
186
186
  const webexJson = JSON.stringify({
187
187
  Credentials: {
@@ -204,7 +204,7 @@ describe('WebexTokenExtractor', () => {
204
204
  expect(result!.deviceUrl).toBeUndefined()
205
205
  })
206
206
 
207
- test('skips profiles without leveldb directory', async () => {
207
+ it('skips profiles without leveldb directory', async () => {
208
208
  mkdirSync(join(tempDir, 'Default', 'Local Storage'), { recursive: true })
209
209
  const profile1Dir = createLevelDBDir(tempDir, 'Profile 1')
210
210
  const webexJson = makeWebexStorageJson()
@@ -216,7 +216,7 @@ describe('WebexTokenExtractor', () => {
216
216
  expect(result).not.toBeNull()
217
217
  })
218
218
 
219
- test('prefers token with latest expiry across profiles', async () => {
219
+ it('prefers token with latest expiry across profiles', async () => {
220
220
  const dir1 = createLevelDBDir(tempDir, 'Default')
221
221
  const dir2 = createLevelDBDir(tempDir, 'Profile 1')
222
222
 
@@ -238,7 +238,7 @@ describe('WebexTokenExtractor', () => {
238
238
  expect(result!.accessToken).toBe('fresh-token-longer-than-twenty-chars-xxx')
239
239
  })
240
240
 
241
- test('returns first token when all have same expiry', async () => {
241
+ it('returns first token when all have same expiry', async () => {
242
242
  const dir1 = createLevelDBDir(tempDir, 'Default')
243
243
  const dir2 = createLevelDBDir(tempDir, 'Profile 1')
244
244
 
@@ -261,7 +261,7 @@ describe('WebexTokenExtractor', () => {
261
261
  expect(result!.accessToken).toBe('first-valid-token-longer-than-twenty-chars')
262
262
  })
263
263
 
264
- test('prefers .log files over .ldb files in same directory', async () => {
264
+ it('prefers .log files over .ldb files in same directory', async () => {
265
265
  const leveldbDir = createLevelDBDir(tempDir)
266
266
 
267
267
  const logToken = makeWebexStorageJson({ accessToken: 'from-log-file-token-at-least-twenty-chars' })
@@ -276,7 +276,7 @@ describe('WebexTokenExtractor', () => {
276
276
  expect(result!.accessToken).toBe('from-log-file-token-at-least-twenty-chars')
277
277
  })
278
278
 
279
- test('rejects tokens shorter than 20 characters', async () => {
279
+ it('rejects tokens shorter than 20 characters', async () => {
280
280
  const leveldbDir = createLevelDBDir(tempDir)
281
281
  const webexJson = makeWebexStorageJson({ accessToken: 'short' })
282
282
  writeFileSync(join(leveldbDir, '000003.log'), webexJson)
@@ -285,7 +285,7 @@ describe('WebexTokenExtractor', () => {
285
285
  expect(await extractor.extract()).toBeNull()
286
286
  })
287
287
 
288
- test('handles binary framing around JSON', async () => {
288
+ it('handles binary framing around JSON', async () => {
289
289
  const leveldbDir = createLevelDBDir(tempDir)
290
290
  const webexJson = makeWebexStorageJson()
291
291
  const binaryFrame = Buffer.concat([
@@ -303,7 +303,7 @@ describe('WebexTokenExtractor', () => {
303
303
  expect(result!.accessToken).toBe('ZDI3MGEyYzQtNmFlNS00NDNh_PF84_1eb65fdf-userId_orgId')
304
304
  })
305
305
 
306
- test('handles supertoken at top level', async () => {
306
+ it('handles supertoken at top level', async () => {
307
307
  const leveldbDir = createLevelDBDir(tempDir)
308
308
  const directJson = JSON.stringify({
309
309
  supertoken: {
@@ -321,7 +321,7 @@ describe('WebexTokenExtractor', () => {
321
321
  expect(result!.accessToken).toBe('direct-supertoken-access-value-at-least-twenty')
322
322
  })
323
323
 
324
- test('handles expires_in instead of expires', async () => {
324
+ it('handles expires_in instead of expires', async () => {
325
325
  const leveldbDir = createLevelDBDir(tempDir)
326
326
  const now = Date.now()
327
327
  const webexJson = JSON.stringify({
@@ -345,7 +345,7 @@ describe('WebexTokenExtractor', () => {
345
345
  expect(result!.expiresAt).toBeLessThanOrEqual(now + 3700000)
346
346
  })
347
347
 
348
- test('calls debug log when provided', async () => {
348
+ it('calls debug log when provided', async () => {
349
349
  const logs: string[] = []
350
350
  const extractor = new WebexTokenExtractor('darwin', (msg) => logs.push(msg), join(tempDir, 'nonexistent'))
351
351
  await extractor.extract()