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,6 +1,6 @@
1
1
  import { Command } from 'commander'
2
2
 
3
- import { formatOutput } from '@/shared/utils/output'
3
+ import { cliOutput } from '@/shared/utils/cli-output'
4
4
 
5
5
  import { WhatsAppBotClient } from '../client'
6
6
  import { WhatsAppBotCredentialManager } from '../credential-manager'
@@ -43,11 +43,6 @@ export async function whoamiAction(options: WhoamiOptions): Promise<WhoamiResult
43
43
  }
44
44
  }
45
45
 
46
- function cliOutput(result: WhoamiResult, pretty?: boolean): void {
47
- console.log(formatOutput(result, pretty))
48
- if (result.error) process.exit(1)
49
- }
50
-
51
46
  export const whoamiCommand = new Command('whoami')
52
47
  .description('Show current authenticated bot')
53
48
  .option('--account <id>', 'Account ID to use')
@@ -1,4 +1,4 @@
1
- import { afterAll, describe, expect, test } from 'bun:test'
1
+ import { afterAll, describe, expect, it } from 'bun:test'
2
2
  import { existsSync, rmSync } from 'node:fs'
3
3
  import { join } from 'node:path'
4
4
 
@@ -22,7 +22,7 @@ afterAll(() => {
22
22
  })
23
23
 
24
24
  describe('WhatsAppBotCredentialManager', () => {
25
- test('load returns default config when file does not exist', async () => {
25
+ it('load returns default config when file does not exist', async () => {
26
26
  const manager = setup()
27
27
  const config = await manager.load()
28
28
 
@@ -32,7 +32,7 @@ describe('WhatsAppBotCredentialManager', () => {
32
32
  })
33
33
  })
34
34
 
35
- test('save creates file with correct permissions', async () => {
35
+ it('save creates file with correct permissions', async () => {
36
36
  const testConfigDir = join(
37
37
  import.meta.dir,
38
38
  `.test-whatsappbot-config-${Date.now()}-${Math.random().toString(36).slice(2)}`,
@@ -61,13 +61,13 @@ describe('WhatsAppBotCredentialManager', () => {
61
61
  expect(loaded).toEqual(config)
62
62
  })
63
63
 
64
- test('getCredentials returns null when not configured', async () => {
64
+ it('getCredentials returns null when not configured', async () => {
65
65
  const manager = setup()
66
66
  const creds = await manager.getCredentials()
67
67
  expect(creds).toBeNull()
68
68
  })
69
69
 
70
- test('getCredentials returns credentials from env vars when E2E env vars are set', async () => {
70
+ it('getCredentials returns credentials from env vars when E2E env vars are set', async () => {
71
71
  const originalAccessToken = process.env.E2E_WHATSAPPBOT_ACCESS_TOKEN
72
72
  const originalPhoneNumberId = process.env.E2E_WHATSAPPBOT_PHONE_NUMBER_ID
73
73
 
@@ -96,7 +96,7 @@ describe('WhatsAppBotCredentialManager', () => {
96
96
  }
97
97
  })
98
98
 
99
- test('getCredentials ignores env vars when accountId is provided', async () => {
99
+ it('getCredentials ignores env vars when accountId is provided', async () => {
100
100
  const originalAccessToken = process.env.E2E_WHATSAPPBOT_ACCESS_TOKEN
101
101
  const originalPhoneNumberId = process.env.E2E_WHATSAPPBOT_PHONE_NUMBER_ID
102
102
 
@@ -121,7 +121,7 @@ describe('WhatsAppBotCredentialManager', () => {
121
121
  }
122
122
  })
123
123
 
124
- test('getCredentials returns specific account by accountId', async () => {
124
+ it('getCredentials returns specific account by accountId', async () => {
125
125
  const manager = setup()
126
126
  await manager.setCredentials({
127
127
  phone_number_id: 'phone-1',
@@ -142,13 +142,13 @@ describe('WhatsAppBotCredentialManager', () => {
142
142
  })
143
143
  })
144
144
 
145
- test('getCredentials returns null for nonexistent accountId', async () => {
145
+ it('getCredentials returns null for nonexistent accountId', async () => {
146
146
  const manager = setup()
147
147
  const creds = await manager.getCredentials('nonexistent')
148
148
  expect(creds).toBeNull()
149
149
  })
150
150
 
151
- test('setCredentials saves and sets as current', async () => {
151
+ it('setCredentials saves and sets as current', async () => {
152
152
  const manager = setup()
153
153
  await manager.setCredentials({
154
154
  phone_number_id: '123456789',
@@ -167,7 +167,7 @@ describe('WhatsAppBotCredentialManager', () => {
167
167
  expect(config.current).toEqual({ account_id: '123456789' })
168
168
  })
169
169
 
170
- test('removeAccount deletes account and adjusts current', async () => {
170
+ it('removeAccount deletes account and adjusts current', async () => {
171
171
  const manager = setup()
172
172
  await manager.setCredentials({
173
173
  phone_number_id: '123456789',
@@ -186,13 +186,13 @@ describe('WhatsAppBotCredentialManager', () => {
186
186
  expect(config.accounts['123456789']).toBeUndefined()
187
187
  })
188
188
 
189
- test('removeAccount returns false for non-existent account', async () => {
189
+ it('removeAccount returns false for non-existent account', async () => {
190
190
  const manager = setup()
191
191
  const removed = await manager.removeAccount('nonexistent')
192
192
  expect(removed).toBe(false)
193
193
  })
194
194
 
195
- test('removeAccount does not clear current when a different account is removed', async () => {
195
+ it('removeAccount does not clear current when a different account is removed', async () => {
196
196
  const manager = setup()
197
197
  await manager.setCredentials({
198
198
  phone_number_id: 'phone-1',
@@ -212,7 +212,7 @@ describe('WhatsAppBotCredentialManager', () => {
212
212
  expect(config.current).toEqual({ account_id: 'phone-2' })
213
213
  })
214
214
 
215
- test('setCurrent switches active account', async () => {
215
+ it('setCurrent switches active account', async () => {
216
216
  const manager = setup()
217
217
  await manager.setCredentials({
218
218
  phone_number_id: 'phone-1',
@@ -232,13 +232,13 @@ describe('WhatsAppBotCredentialManager', () => {
232
232
  expect(config.current).toEqual({ account_id: 'phone-1' })
233
233
  })
234
234
 
235
- test('setCurrent returns false for non-existent account', async () => {
235
+ it('setCurrent returns false for non-existent account', async () => {
236
236
  const manager = setup()
237
237
  const result = await manager.setCurrent('nonexistent')
238
238
  expect(result).toBe(false)
239
239
  })
240
240
 
241
- test('listAll returns all accounts with is_current flag', async () => {
241
+ it('listAll returns all accounts with is_current flag', async () => {
242
242
  const manager = setup()
243
243
  await manager.setCredentials({
244
244
  phone_number_id: 'phone-1',
@@ -261,13 +261,13 @@ describe('WhatsAppBotCredentialManager', () => {
261
261
  expect(phone2?.is_current).toBe(true)
262
262
  })
263
263
 
264
- test('listAll returns empty array when no accounts', async () => {
264
+ it('listAll returns empty array when no accounts', async () => {
265
265
  const manager = setup()
266
266
  const accounts = await manager.listAll()
267
267
  expect(accounts).toHaveLength(0)
268
268
  })
269
269
 
270
- test('clearCredentials resets everything', async () => {
270
+ it('clearCredentials resets everything', async () => {
271
271
  const manager = setup()
272
272
  await manager.setCredentials({
273
273
  phone_number_id: '123456789',
@@ -282,7 +282,7 @@ describe('WhatsAppBotCredentialManager', () => {
282
282
  expect(config.accounts).toEqual({})
283
283
  })
284
284
 
285
- test('round-trip: set → get → remove → get null', async () => {
285
+ it('completes round-trip: set → get → remove → get null', async () => {
286
286
  const manager = setup()
287
287
 
288
288
  await manager.setCredentials({
@@ -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
  WhatsAppBotAccountEntrySchema,
@@ -9,26 +9,26 @@ import {
9
9
  WhatsAppBotError,
10
10
  } from '@/platforms/whatsappbot/index'
11
11
 
12
- test('WhatsAppBotClient is exported from barrel', () => {
12
+ it('WhatsAppBotClient is exported from barrel', () => {
13
13
  expect(typeof WhatsAppBotClient).toBe('function')
14
14
  })
15
15
 
16
- test('WhatsAppBotCredentialManager is exported from barrel', () => {
16
+ it('WhatsAppBotCredentialManager is exported from barrel', () => {
17
17
  expect(typeof WhatsAppBotCredentialManager).toBe('function')
18
18
  })
19
19
 
20
- test('WhatsAppBotError is exported from barrel', () => {
20
+ it('WhatsAppBotError is exported from barrel', () => {
21
21
  expect(typeof WhatsAppBotError).toBe('function')
22
22
  })
23
23
 
24
- test('WhatsAppBotAccountEntrySchema is exported from barrel', () => {
24
+ it('WhatsAppBotAccountEntrySchema is exported from barrel', () => {
25
25
  expect(typeof WhatsAppBotAccountEntrySchema.parse).toBe('function')
26
26
  })
27
27
 
28
- test('WhatsAppBotConfigSchema is exported from barrel', () => {
28
+ it('WhatsAppBotConfigSchema is exported from barrel', () => {
29
29
  expect(typeof WhatsAppBotConfigSchema.parse).toBe('function')
30
30
  })
31
31
 
32
- test('WhatsAppBotCredentialsSchema is exported from barrel', () => {
32
+ it('WhatsAppBotCredentialsSchema is exported from barrel', () => {
33
33
  expect(typeof WhatsAppBotCredentialsSchema.parse).toBe('function')
34
34
  })
@@ -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
  WhatsAppBotAccountEntrySchema,
@@ -7,7 +7,7 @@ import {
7
7
  WhatsAppBotError,
8
8
  } from '@/platforms/whatsappbot/types'
9
9
 
10
- test('WhatsAppBotAccountEntrySchema validates correct data', () => {
10
+ it('WhatsAppBotAccountEntrySchema validates correct data', () => {
11
11
  const result = WhatsAppBotAccountEntrySchema.safeParse({
12
12
  phone_number_id: '123456789',
13
13
  account_name: 'Test Business',
@@ -16,7 +16,7 @@ test('WhatsAppBotAccountEntrySchema validates correct data', () => {
16
16
  expect(result.success).toBe(true)
17
17
  })
18
18
 
19
- test('WhatsAppBotAccountEntrySchema rejects missing phone_number_id', () => {
19
+ it('WhatsAppBotAccountEntrySchema rejects missing phone_number_id', () => {
20
20
  const result = WhatsAppBotAccountEntrySchema.safeParse({
21
21
  account_name: 'Test Business',
22
22
  access_token: 'EAAtest123',
@@ -24,7 +24,7 @@ test('WhatsAppBotAccountEntrySchema rejects missing phone_number_id', () => {
24
24
  expect(result.success).toBe(false)
25
25
  })
26
26
 
27
- test('WhatsAppBotAccountEntrySchema rejects missing account_name', () => {
27
+ it('WhatsAppBotAccountEntrySchema rejects missing account_name', () => {
28
28
  const result = WhatsAppBotAccountEntrySchema.safeParse({
29
29
  phone_number_id: '123456789',
30
30
  access_token: 'EAAtest123',
@@ -32,7 +32,7 @@ test('WhatsAppBotAccountEntrySchema rejects missing account_name', () => {
32
32
  expect(result.success).toBe(false)
33
33
  })
34
34
 
35
- test('WhatsAppBotAccountEntrySchema rejects missing access_token', () => {
35
+ it('WhatsAppBotAccountEntrySchema rejects missing access_token', () => {
36
36
  const result = WhatsAppBotAccountEntrySchema.safeParse({
37
37
  phone_number_id: '123456789',
38
38
  account_name: 'Test Business',
@@ -40,7 +40,7 @@ test('WhatsAppBotAccountEntrySchema rejects missing access_token', () => {
40
40
  expect(result.success).toBe(false)
41
41
  })
42
42
 
43
- test('WhatsAppBotConfigSchema validates with current account', () => {
43
+ it('WhatsAppBotConfigSchema validates with current account', () => {
44
44
  const result = WhatsAppBotConfigSchema.safeParse({
45
45
  current: { account_id: '123456789' },
46
46
  accounts: {
@@ -54,7 +54,7 @@ test('WhatsAppBotConfigSchema validates with current account', () => {
54
54
  expect(result.success).toBe(true)
55
55
  })
56
56
 
57
- test('WhatsAppBotConfigSchema validates with current null and empty accounts', () => {
57
+ it('WhatsAppBotConfigSchema validates with current null and empty accounts', () => {
58
58
  const result = WhatsAppBotConfigSchema.safeParse({
59
59
  current: null,
60
60
  accounts: {},
@@ -62,7 +62,7 @@ test('WhatsAppBotConfigSchema validates with current null and empty accounts', (
62
62
  expect(result.success).toBe(true)
63
63
  })
64
64
 
65
- test('WhatsAppBotConfigSchema validates with multiple accounts', () => {
65
+ it('WhatsAppBotConfigSchema validates with multiple accounts', () => {
66
66
  const result = WhatsAppBotConfigSchema.safeParse({
67
67
  current: { account_id: 'phone-1' },
68
68
  accounts: {
@@ -73,21 +73,21 @@ test('WhatsAppBotConfigSchema validates with multiple accounts', () => {
73
73
  expect(result.success).toBe(true)
74
74
  })
75
75
 
76
- test('WhatsAppBotConfigSchema rejects missing accounts field', () => {
76
+ it('WhatsAppBotConfigSchema rejects missing accounts field', () => {
77
77
  const result = WhatsAppBotConfigSchema.safeParse({
78
78
  current: null,
79
79
  })
80
80
  expect(result.success).toBe(false)
81
81
  })
82
82
 
83
- test('WhatsAppBotConfigSchema rejects missing current field', () => {
83
+ it('WhatsAppBotConfigSchema rejects missing current field', () => {
84
84
  const result = WhatsAppBotConfigSchema.safeParse({
85
85
  accounts: {},
86
86
  })
87
87
  expect(result.success).toBe(false)
88
88
  })
89
89
 
90
- test('WhatsAppBotCredentialsSchema validates correct data', () => {
90
+ it('WhatsAppBotCredentialsSchema validates correct data', () => {
91
91
  const result = WhatsAppBotCredentialsSchema.safeParse({
92
92
  phone_number_id: '123456789',
93
93
  account_name: 'Test Business',
@@ -96,7 +96,7 @@ test('WhatsAppBotCredentialsSchema validates correct data', () => {
96
96
  expect(result.success).toBe(true)
97
97
  })
98
98
 
99
- test('WhatsAppBotCredentialsSchema rejects missing phone_number_id', () => {
99
+ it('WhatsAppBotCredentialsSchema rejects missing phone_number_id', () => {
100
100
  const result = WhatsAppBotCredentialsSchema.safeParse({
101
101
  account_name: 'Test Business',
102
102
  access_token: 'EAAtest123',
@@ -104,7 +104,7 @@ test('WhatsAppBotCredentialsSchema rejects missing phone_number_id', () => {
104
104
  expect(result.success).toBe(false)
105
105
  })
106
106
 
107
- test('WhatsAppBotCredentialsSchema rejects missing account_name', () => {
107
+ it('WhatsAppBotCredentialsSchema rejects missing account_name', () => {
108
108
  const result = WhatsAppBotCredentialsSchema.safeParse({
109
109
  phone_number_id: '123456789',
110
110
  access_token: 'EAAtest123',
@@ -112,7 +112,7 @@ test('WhatsAppBotCredentialsSchema rejects missing account_name', () => {
112
112
  expect(result.success).toBe(false)
113
113
  })
114
114
 
115
- test('WhatsAppBotCredentialsSchema rejects missing access_token', () => {
115
+ it('WhatsAppBotCredentialsSchema rejects missing access_token', () => {
116
116
  const result = WhatsAppBotCredentialsSchema.safeParse({
117
117
  phone_number_id: '123456789',
118
118
  account_name: 'Test Business',
@@ -120,22 +120,22 @@ test('WhatsAppBotCredentialsSchema rejects missing access_token', () => {
120
120
  expect(result.success).toBe(false)
121
121
  })
122
122
 
123
- test('WhatsAppBotError has correct name', () => {
123
+ it('WhatsAppBotError has correct name', () => {
124
124
  const error = new WhatsAppBotError('Test error', 'TEST_CODE')
125
125
  expect(error.name).toBe('WhatsAppBotError')
126
126
  })
127
127
 
128
- test('WhatsAppBotError has correct message', () => {
128
+ it('WhatsAppBotError has correct message', () => {
129
129
  const error = new WhatsAppBotError('Test error', 'TEST_CODE')
130
130
  expect(error.message).toBe('Test error')
131
131
  })
132
132
 
133
- test('WhatsAppBotError has correct code', () => {
133
+ it('WhatsAppBotError has correct code', () => {
134
134
  const error = new WhatsAppBotError('Test error', 'TEST_CODE')
135
135
  expect(error.code).toBe('TEST_CODE')
136
136
  })
137
137
 
138
- test('WhatsAppBotError is instance of Error', () => {
138
+ it('WhatsAppBotError is instance of Error', () => {
139
139
  const error = new WhatsAppBotError('Test error', 'TEST_CODE')
140
140
  expect(error instanceof Error).toBe(true)
141
141
  })
@@ -1,4 +1,4 @@
1
- import { afterEach, describe, expect, test } from 'bun:test'
1
+ import { afterEach, describe, expect, it } from 'bun:test'
2
2
  import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3
3
  import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
@@ -8,6 +8,7 @@ import {
8
8
  CHROMIUM_BROWSERS,
9
9
  discoverBrowserProfileDirs,
10
10
  findLocalStatePath,
11
+ getAgentBrowserProfileDirs,
11
12
  getBrowserBasePath,
12
13
  } from './browsers'
13
14
 
@@ -26,34 +27,34 @@ describe('browsers', () => {
26
27
  })
27
28
 
28
29
  describe('CHROMIUM_BROWSERS', () => {
29
- test('has 7 browsers', () => {
30
+ it('has 7 browsers', () => {
30
31
  expect(CHROMIUM_BROWSERS).toHaveLength(7)
31
32
  })
32
33
 
33
- test('includes major supported browsers', () => {
34
+ it('includes major supported browsers', () => {
34
35
  const browserNames = CHROMIUM_BROWSERS.map((browser) => browser.name)
35
36
 
36
37
  expect(browserNames).toEqual(expect.arrayContaining(['Chrome', 'Edge', 'Arc', 'Brave', 'Vivaldi', 'Chromium']))
37
38
  })
38
39
 
39
- test('Arc has empty linux path', () => {
40
+ it('Arc has empty linux path', () => {
40
41
  expect(CHROMIUM_BROWSERS.find((browser) => browser.name === 'Arc')?.linux).toBe('')
41
42
  })
42
43
  })
43
44
 
44
45
  describe('BROWSER_KEYCHAIN_VARIANTS', () => {
45
- test('has 7 keychain variants', () => {
46
+ it('has 7 keychain variants', () => {
46
47
  expect(BROWSER_KEYCHAIN_VARIANTS).toHaveLength(7)
47
48
  })
48
49
 
49
- test('each variant has service and account properties', () => {
50
+ it('each variant has service and account properties', () => {
50
51
  for (const variant of BROWSER_KEYCHAIN_VARIANTS) {
51
52
  expect(variant.service).toBeString()
52
53
  expect(variant.account).toBeString()
53
54
  }
54
55
  })
55
56
 
56
- test('includes known safe storage services', () => {
57
+ it('includes known safe storage services', () => {
57
58
  const services = BROWSER_KEYCHAIN_VARIANTS.map((variant) => variant.service)
58
59
 
59
60
  expect(services).toEqual(expect.arrayContaining(['Chrome Safe Storage', 'Microsoft Edge Safe Storage']))
@@ -61,7 +62,7 @@ describe('browsers', () => {
61
62
  })
62
63
 
63
64
  describe('getBrowserBasePath', () => {
64
- test('returns darwin path with Library/Application Support prefix', () => {
65
+ it('returns darwin path with Library/Application Support prefix', () => {
65
66
  // given
66
67
  const chrome = CHROMIUM_BROWSERS.find((browser) => browser.name === 'Chrome')!
67
68
 
@@ -74,7 +75,7 @@ describe('browsers', () => {
74
75
  expect(path).toEndWith(join('Google', 'Chrome'))
75
76
  })
76
77
 
77
- test('returns linux path with .config prefix', () => {
78
+ it('returns linux path with .config prefix', () => {
78
79
  // given
79
80
  const chrome = CHROMIUM_BROWSERS.find((browser) => browser.name === 'Chrome')!
80
81
 
@@ -86,7 +87,7 @@ describe('browsers', () => {
86
87
  expect(path).toContain(join('.config', 'google-chrome'))
87
88
  })
88
89
 
89
- test('returns win32 path with LOCALAPPDATA prefix', () => {
90
+ it('returns win32 path with LOCALAPPDATA prefix', () => {
90
91
  // given
91
92
  const localAppData = mkdtempSync(join(tmpdir(), 'browser-localappdata-'))
92
93
  tempDirs.push(localAppData)
@@ -100,7 +101,7 @@ describe('browsers', () => {
100
101
  expect(path).toBe(join(localAppData, 'Google', 'Chrome', 'User Data'))
101
102
  })
102
103
 
103
- test('returns null for unsupported platform', () => {
104
+ it('returns null for unsupported platform', () => {
104
105
  // given
105
106
  const chrome = CHROMIUM_BROWSERS.find((browser) => browser.name === 'Chrome')!
106
107
 
@@ -111,7 +112,7 @@ describe('browsers', () => {
111
112
  expect(path).toBeNull()
112
113
  })
113
114
 
114
- test('returns null when browser has empty path for platform', () => {
115
+ it('returns null when browser has empty path for platform', () => {
115
116
  // given
116
117
  const arc = CHROMIUM_BROWSERS.find((browser) => browser.name === 'Arc')!
117
118
 
@@ -124,7 +125,7 @@ describe('browsers', () => {
124
125
  })
125
126
 
126
127
  describe('discoverBrowserProfileDirs', () => {
127
- test('always includes Default dir even when base does not exist', () => {
128
+ it('always includes Default dir even when base does not exist', () => {
128
129
  // given
129
130
  const browserBase = join(tmpdir(), `missing-browser-base-${Date.now()}-${Math.random().toString(36).slice(2)}`)
130
131
 
@@ -135,7 +136,7 @@ describe('browsers', () => {
135
136
  expect(dirs).toEqual([join(browserBase, 'Default')])
136
137
  })
137
138
 
138
- test('discovers Profile 1 and Profile 2 dirs when they exist', () => {
139
+ it('discovers Profile 1 and Profile 2 dirs when they exist', () => {
139
140
  // given
140
141
  const browserBase = mkdtempSync(join(tmpdir(), 'browser-profiles-'))
141
142
  tempDirs.push(browserBase)
@@ -153,7 +154,7 @@ describe('browsers', () => {
153
154
  ])
154
155
  })
155
156
 
156
- test('ignores non-profile directories', () => {
157
+ it('ignores non-profile directories', () => {
157
158
  // given
158
159
  const browserBase = mkdtempSync(join(tmpdir(), 'browser-non-profile-'))
159
160
  tempDirs.push(browserBase)
@@ -168,7 +169,7 @@ describe('browsers', () => {
168
169
  expect(dirs).toEqual([join(browserBase, 'Default'), join(browserBase, 'Profile 1')])
169
170
  })
170
171
 
171
- test('ignores files that match profile pattern', () => {
172
+ it('ignores files that match profile pattern', () => {
172
173
  // given
173
174
  const browserBase = mkdtempSync(join(tmpdir(), 'browser-profile-files-'))
174
175
  tempDirs.push(browserBase)
@@ -182,7 +183,7 @@ describe('browsers', () => {
182
183
  expect(dirs).toEqual([join(browserBase, 'Default'), join(browserBase, 'Profile 2')])
183
184
  })
184
185
 
185
- test('returns only Default when base directory is empty', () => {
186
+ it('returns only Default when base directory is empty', () => {
186
187
  // given
187
188
  const browserBase = mkdtempSync(join(tmpdir(), 'browser-empty-'))
188
189
  tempDirs.push(browserBase)
@@ -195,8 +196,87 @@ describe('browsers', () => {
195
196
  })
196
197
  })
197
198
 
199
+ describe('getAgentBrowserProfileDirs', () => {
200
+ it('includes profile dirs from env and config files', () => {
201
+ // given
202
+ const homeDir = mkdtempSync(join(tmpdir(), 'agent-browser-home-'))
203
+ const projectDir = mkdtempSync(join(tmpdir(), 'agent-browser-project-'))
204
+ const customConfigDir = mkdtempSync(join(tmpdir(), 'agent-browser-custom-'))
205
+ tempDirs.push(homeDir, projectDir, customConfigDir)
206
+
207
+ mkdirSync(join(homeDir, '.agent-browser'))
208
+ writeFileSync(join(homeDir, '.agent-browser', 'config.json'), JSON.stringify({ profile: './global-profile' }))
209
+ writeFileSync(join(projectDir, 'agent-browser.json'), JSON.stringify({ profile: './project-profile' }))
210
+ const customConfigPath = join(customConfigDir, 'custom-agent-browser.json')
211
+ writeFileSync(customConfigPath, JSON.stringify({ profile: './custom-profile' }))
212
+
213
+ // when
214
+ const dirs = getAgentBrowserProfileDirs({
215
+ cwd: projectDir,
216
+ env: {
217
+ AGENT_BROWSER_CONFIG: customConfigPath,
218
+ AGENT_BROWSER_PROFILE: join(projectDir, 'env-profile'),
219
+ },
220
+ homeDir,
221
+ customProfileDirs: ['./cli-profile', join(projectDir, 'second-cli-profile')],
222
+ })
223
+
224
+ // then
225
+ expect(dirs).toEqual([
226
+ join(projectDir, 'cli-profile'),
227
+ join(projectDir, 'cli-profile', 'Default'),
228
+ join(projectDir, 'second-cli-profile'),
229
+ join(projectDir, 'second-cli-profile', 'Default'),
230
+ join(projectDir, 'env-profile'),
231
+ join(projectDir, 'env-profile', 'Default'),
232
+ join(homeDir, '.agent-browser', 'global-profile'),
233
+ join(homeDir, '.agent-browser', 'global-profile', 'Default'),
234
+ join(projectDir, 'project-profile'),
235
+ join(projectDir, 'project-profile', 'Default'),
236
+ join(customConfigDir, 'custom-profile'),
237
+ join(customConfigDir, 'custom-profile', 'Default'),
238
+ ])
239
+ })
240
+
241
+ it('expands existing agent-browser profile bases with numbered Chromium profiles', () => {
242
+ // given
243
+ const homeDir = mkdtempSync(join(tmpdir(), 'agent-browser-expand-home-'))
244
+ const projectDir = mkdtempSync(join(tmpdir(), 'agent-browser-expand-project-'))
245
+ const profileBase = join(projectDir, 'browser-data')
246
+ tempDirs.push(homeDir, projectDir)
247
+ mkdirSync(join(profileBase, 'Profile 1'), { recursive: true })
248
+ mkdirSync(join(profileBase, 'Profile 2'))
249
+ writeFileSync(join(projectDir, 'agent-browser.json'), JSON.stringify({ profile: './browser-data' }))
250
+
251
+ // when
252
+ const dirs = getAgentBrowserProfileDirs({ cwd: projectDir, env: {}, homeDir })
253
+
254
+ // then
255
+ expect(dirs).toEqual([
256
+ profileBase,
257
+ join(profileBase, 'Default'),
258
+ join(profileBase, 'Profile 1'),
259
+ join(profileBase, 'Profile 2'),
260
+ ])
261
+ })
262
+
263
+ it('ignores malformed agent-browser configs', () => {
264
+ // given
265
+ const homeDir = mkdtempSync(join(tmpdir(), 'agent-browser-malformed-home-'))
266
+ const projectDir = mkdtempSync(join(tmpdir(), 'agent-browser-malformed-project-'))
267
+ tempDirs.push(homeDir, projectDir)
268
+ writeFileSync(join(projectDir, 'agent-browser.json'), '{')
269
+
270
+ // when
271
+ const dirs = getAgentBrowserProfileDirs({ cwd: projectDir, env: {}, homeDir })
272
+
273
+ // then
274
+ expect(dirs).toEqual([])
275
+ })
276
+ })
277
+
198
278
  describe('findLocalStatePath', () => {
199
- test('returns null when no Local State exists at any level', () => {
279
+ it('returns null when no Local State exists at any level', () => {
200
280
  // given
201
281
  const rootDir = mkdtempSync(join(tmpdir(), 'browser-local-state-missing-'))
202
282
  tempDirs.push(rootDir)
@@ -210,7 +290,7 @@ describe('browsers', () => {
210
290
  expect(path).toBeNull()
211
291
  })
212
292
 
213
- test('finds Local State 2 levels up from cookie path', () => {
293
+ it('finds Local State 2 levels up from cookie path', () => {
214
294
  // given
215
295
  const rootDir = mkdtempSync(join(tmpdir(), 'browser-local-state-two-'))
216
296
  tempDirs.push(rootDir)
@@ -226,7 +306,7 @@ describe('browsers', () => {
226
306
  expect(path).toBe(join(profileDir, 'Local State'))
227
307
  })
228
308
 
229
- test('finds Local State 3 levels up from cookie path', () => {
309
+ it('finds Local State 3 levels up from cookie path', () => {
230
310
  // given
231
311
  const rootDir = mkdtempSync(join(tmpdir(), 'browser-local-state-three-'))
232
312
  tempDirs.push(rootDir)
@@ -242,7 +322,7 @@ describe('browsers', () => {
242
322
  expect(path).toBe(join(browserDir, 'Local State'))
243
323
  })
244
324
 
245
- test('returns null for path with too few segments', () => {
325
+ it('returns null for path with too few segments', () => {
246
326
  // given
247
327
  const cookiePath = 'Cookies'
248
328
 
@@ -253,7 +333,7 @@ describe('browsers', () => {
253
333
  expect(path).toBeNull()
254
334
  })
255
335
 
256
- test('finds the first match when multiple levels could match', () => {
336
+ it('finds the first match when multiple levels could match', () => {
257
337
  // given
258
338
  const rootDir = mkdtempSync(join(tmpdir(), 'browser-local-state-first-'))
259
339
  tempDirs.push(rootDir)