agent-messenger 2.3.0 → 2.5.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 (438) hide show
  1. package/.claude-plugin/README.md +16 -16
  2. package/.claude-plugin/marketplace.json +29 -29
  3. package/.claude-plugin/plugin.json +5 -5
  4. package/.github/workflows/release.yml +0 -12
  5. package/CONTRIBUTING.md +1 -1
  6. package/README.md +11 -8
  7. package/bun.lock +70 -110
  8. package/bunfig.toml +3 -0
  9. package/dist/package.json +11 -3
  10. package/dist/src/platforms/channeltalk/cli.d.ts.map +1 -1
  11. package/dist/src/platforms/channeltalk/cli.js +2 -1
  12. package/dist/src/platforms/channeltalk/cli.js.map +1 -1
  13. package/dist/src/platforms/channeltalk/commands/index.d.ts +1 -0
  14. package/dist/src/platforms/channeltalk/commands/index.d.ts.map +1 -1
  15. package/dist/src/platforms/channeltalk/commands/index.js +1 -0
  16. package/dist/src/platforms/channeltalk/commands/index.js.map +1 -1
  17. package/dist/src/platforms/channeltalk/commands/whoami.d.ts +22 -0
  18. package/dist/src/platforms/channeltalk/commands/whoami.d.ts.map +1 -0
  19. package/dist/src/platforms/channeltalk/commands/whoami.js +40 -0
  20. package/dist/src/platforms/channeltalk/commands/whoami.js.map +1 -0
  21. package/dist/src/platforms/channeltalkbot/cli.d.ts.map +1 -1
  22. package/dist/src/platforms/channeltalkbot/cli.js +2 -1
  23. package/dist/src/platforms/channeltalkbot/cli.js.map +1 -1
  24. package/dist/src/platforms/channeltalkbot/commands/index.d.ts +1 -0
  25. package/dist/src/platforms/channeltalkbot/commands/index.d.ts.map +1 -1
  26. package/dist/src/platforms/channeltalkbot/commands/index.js +1 -0
  27. package/dist/src/platforms/channeltalkbot/commands/index.js.map +1 -1
  28. package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts +13 -0
  29. package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts.map +1 -0
  30. package/dist/src/platforms/channeltalkbot/commands/whoami.js +31 -0
  31. package/dist/src/platforms/channeltalkbot/commands/whoami.js.map +1 -0
  32. package/dist/src/platforms/discord/cli.d.ts.map +1 -1
  33. package/dist/src/platforms/discord/cli.js +2 -1
  34. package/dist/src/platforms/discord/cli.js.map +1 -1
  35. package/dist/src/platforms/discord/commands/index.d.ts +1 -0
  36. package/dist/src/platforms/discord/commands/index.d.ts.map +1 -1
  37. package/dist/src/platforms/discord/commands/index.js +1 -0
  38. package/dist/src/platforms/discord/commands/index.js.map +1 -1
  39. package/dist/src/platforms/discord/commands/whoami.d.ts +6 -0
  40. package/dist/src/platforms/discord/commands/whoami.d.ts.map +1 -0
  41. package/dist/src/platforms/discord/commands/whoami.js +33 -0
  42. package/dist/src/platforms/discord/commands/whoami.js.map +1 -0
  43. package/dist/src/platforms/discordbot/cli.d.ts.map +1 -1
  44. package/dist/src/platforms/discordbot/cli.js +2 -1
  45. package/dist/src/platforms/discordbot/cli.js.map +1 -1
  46. package/dist/src/platforms/discordbot/client.js +2 -2
  47. package/dist/src/platforms/discordbot/client.js.map +1 -1
  48. package/dist/src/platforms/discordbot/commands/index.d.ts +1 -0
  49. package/dist/src/platforms/discordbot/commands/index.d.ts.map +1 -1
  50. package/dist/src/platforms/discordbot/commands/index.js +1 -0
  51. package/dist/src/platforms/discordbot/commands/index.js.map +1 -1
  52. package/dist/src/platforms/discordbot/commands/whoami.d.ts +14 -0
  53. package/dist/src/platforms/discordbot/commands/whoami.d.ts.map +1 -0
  54. package/dist/src/platforms/discordbot/commands/whoami.js +32 -0
  55. package/dist/src/platforms/discordbot/commands/whoami.js.map +1 -0
  56. package/dist/src/platforms/instagram/cli.d.ts.map +1 -1
  57. package/dist/src/platforms/instagram/cli.js +2 -1
  58. package/dist/src/platforms/instagram/cli.js.map +1 -1
  59. package/dist/src/platforms/instagram/client.d.ts +6 -0
  60. package/dist/src/platforms/instagram/client.d.ts.map +1 -1
  61. package/dist/src/platforms/instagram/client.js +12 -0
  62. package/dist/src/platforms/instagram/client.js.map +1 -1
  63. package/dist/src/platforms/instagram/commands/index.d.ts +1 -0
  64. package/dist/src/platforms/instagram/commands/index.d.ts.map +1 -1
  65. package/dist/src/platforms/instagram/commands/index.js +1 -0
  66. package/dist/src/platforms/instagram/commands/index.js.map +1 -1
  67. package/dist/src/platforms/instagram/commands/whoami.d.ts +7 -0
  68. package/dist/src/platforms/instagram/commands/whoami.d.ts.map +1 -0
  69. package/dist/src/platforms/instagram/commands/whoami.js +19 -0
  70. package/dist/src/platforms/instagram/commands/whoami.js.map +1 -0
  71. package/dist/src/platforms/kakaotalk/cli.d.ts.map +1 -1
  72. package/dist/src/platforms/kakaotalk/cli.js +2 -1
  73. package/dist/src/platforms/kakaotalk/cli.js.map +1 -1
  74. package/dist/src/platforms/kakaotalk/client.d.ts +2 -1
  75. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  76. package/dist/src/platforms/kakaotalk/client.js +225 -23
  77. package/dist/src/platforms/kakaotalk/client.js.map +1 -1
  78. package/dist/src/platforms/kakaotalk/commands/index.d.ts +1 -0
  79. package/dist/src/platforms/kakaotalk/commands/index.d.ts.map +1 -1
  80. package/dist/src/platforms/kakaotalk/commands/index.js +1 -0
  81. package/dist/src/platforms/kakaotalk/commands/index.js.map +1 -1
  82. package/dist/src/platforms/kakaotalk/commands/whoami.d.ts +3 -0
  83. package/dist/src/platforms/kakaotalk/commands/whoami.d.ts.map +1 -0
  84. package/dist/src/platforms/kakaotalk/commands/whoami.js +19 -0
  85. package/dist/src/platforms/kakaotalk/commands/whoami.js.map +1 -0
  86. package/dist/src/platforms/kakaotalk/index.d.ts +2 -2
  87. package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
  88. package/dist/src/platforms/kakaotalk/index.js +1 -1
  89. package/dist/src/platforms/kakaotalk/index.js.map +1 -1
  90. package/dist/src/platforms/kakaotalk/protocol/session.d.ts +4 -2
  91. package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
  92. package/dist/src/platforms/kakaotalk/protocol/session.js +27 -7
  93. package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
  94. package/dist/src/platforms/kakaotalk/protocol/types.d.ts +17 -0
  95. package/dist/src/platforms/kakaotalk/protocol/types.d.ts.map +1 -1
  96. package/dist/src/platforms/kakaotalk/protocol/types.js.map +1 -1
  97. package/dist/src/platforms/kakaotalk/types.d.ts +28 -0
  98. package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
  99. package/dist/src/platforms/kakaotalk/types.js +14 -0
  100. package/dist/src/platforms/kakaotalk/types.js.map +1 -1
  101. package/dist/src/platforms/line/cli.js +2 -2
  102. package/dist/src/platforms/line/cli.js.map +1 -1
  103. package/dist/src/platforms/line/client.d.ts.map +1 -1
  104. package/dist/src/platforms/line/client.js +9 -36
  105. package/dist/src/platforms/line/client.js.map +1 -1
  106. package/dist/src/platforms/line/commands/auth.d.ts.map +1 -1
  107. package/dist/src/platforms/line/commands/auth.js +9 -47
  108. package/dist/src/platforms/line/commands/auth.js.map +1 -1
  109. package/dist/src/platforms/line/commands/index.d.ts +1 -1
  110. package/dist/src/platforms/line/commands/index.d.ts.map +1 -1
  111. package/dist/src/platforms/line/commands/index.js +1 -1
  112. package/dist/src/platforms/line/commands/index.js.map +1 -1
  113. package/dist/src/platforms/line/commands/whoami.d.ts +3 -0
  114. package/dist/src/platforms/line/commands/whoami.d.ts.map +1 -0
  115. package/dist/src/platforms/line/commands/{profile.js → whoami.js} +5 -5
  116. package/dist/src/platforms/line/commands/whoami.js.map +1 -0
  117. package/dist/src/platforms/slack/cli.d.ts.map +1 -1
  118. package/dist/src/platforms/slack/cli.js +2 -1
  119. package/dist/src/platforms/slack/cli.js.map +1 -1
  120. package/dist/src/platforms/slack/commands/index.d.ts +1 -0
  121. package/dist/src/platforms/slack/commands/index.d.ts.map +1 -1
  122. package/dist/src/platforms/slack/commands/index.js +1 -0
  123. package/dist/src/platforms/slack/commands/index.js.map +1 -1
  124. package/dist/src/platforms/slack/commands/whoami.d.ts +6 -0
  125. package/dist/src/platforms/slack/commands/whoami.d.ts.map +1 -0
  126. package/dist/src/platforms/slack/commands/whoami.js +39 -0
  127. package/dist/src/platforms/slack/commands/whoami.js.map +1 -0
  128. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  129. package/dist/src/platforms/slackbot/cli.js +2 -1
  130. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  131. package/dist/src/platforms/slackbot/commands/index.d.ts +1 -0
  132. package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -1
  133. package/dist/src/platforms/slackbot/commands/index.js +1 -0
  134. package/dist/src/platforms/slackbot/commands/index.js.map +1 -1
  135. package/dist/src/platforms/slackbot/commands/whoami.d.ts +14 -0
  136. package/dist/src/platforms/slackbot/commands/whoami.d.ts.map +1 -0
  137. package/dist/src/platforms/slackbot/commands/whoami.js +32 -0
  138. package/dist/src/platforms/slackbot/commands/whoami.js.map +1 -0
  139. package/dist/src/platforms/teams/cli.d.ts.map +1 -1
  140. package/dist/src/platforms/teams/cli.js +2 -1
  141. package/dist/src/platforms/teams/cli.js.map +1 -1
  142. package/dist/src/platforms/teams/commands/index.d.ts +1 -0
  143. package/dist/src/platforms/teams/commands/index.d.ts.map +1 -1
  144. package/dist/src/platforms/teams/commands/index.js +1 -0
  145. package/dist/src/platforms/teams/commands/index.js.map +1 -1
  146. package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -1
  147. package/dist/src/platforms/teams/commands/reaction.js +2 -0
  148. package/dist/src/platforms/teams/commands/reaction.js.map +1 -1
  149. package/dist/src/platforms/teams/commands/whoami.d.ts +6 -0
  150. package/dist/src/platforms/teams/commands/whoami.d.ts.map +1 -0
  151. package/dist/src/platforms/teams/commands/whoami.js +30 -0
  152. package/dist/src/platforms/teams/commands/whoami.js.map +1 -0
  153. package/dist/src/platforms/telegram/cli.d.ts.map +1 -1
  154. package/dist/src/platforms/telegram/cli.js +2 -1
  155. package/dist/src/platforms/telegram/cli.js.map +1 -1
  156. package/dist/src/platforms/telegram/commands/index.d.ts +1 -0
  157. package/dist/src/platforms/telegram/commands/index.d.ts.map +1 -1
  158. package/dist/src/platforms/telegram/commands/index.js +1 -0
  159. package/dist/src/platforms/telegram/commands/index.js.map +1 -1
  160. package/dist/src/platforms/telegram/commands/whoami.d.ts +7 -0
  161. package/dist/src/platforms/telegram/commands/whoami.d.ts.map +1 -0
  162. package/dist/src/platforms/telegram/commands/whoami.js +27 -0
  163. package/dist/src/platforms/telegram/commands/whoami.js.map +1 -0
  164. package/dist/src/platforms/webex/cli.d.ts.map +1 -1
  165. package/dist/src/platforms/webex/cli.js +2 -1
  166. package/dist/src/platforms/webex/cli.js.map +1 -1
  167. package/dist/src/platforms/webex/commands/index.d.ts +1 -0
  168. package/dist/src/platforms/webex/commands/index.d.ts.map +1 -1
  169. package/dist/src/platforms/webex/commands/index.js +1 -0
  170. package/dist/src/platforms/webex/commands/index.js.map +1 -1
  171. package/dist/src/platforms/webex/commands/message.js +1 -1
  172. package/dist/src/platforms/webex/commands/message.js.map +1 -1
  173. package/dist/src/platforms/webex/commands/whoami.d.ts +6 -0
  174. package/dist/src/platforms/webex/commands/whoami.d.ts.map +1 -0
  175. package/dist/src/platforms/webex/commands/whoami.js +30 -0
  176. package/dist/src/platforms/webex/commands/whoami.js.map +1 -0
  177. package/dist/src/platforms/wechatbot/cli.d.ts +5 -0
  178. package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -0
  179. package/dist/src/platforms/wechatbot/cli.js +19 -0
  180. package/dist/src/platforms/wechatbot/cli.js.map +1 -0
  181. package/dist/src/platforms/wechatbot/client.d.ts +36 -0
  182. package/dist/src/platforms/wechatbot/client.d.ts.map +1 -0
  183. package/dist/src/platforms/wechatbot/client.js +208 -0
  184. package/dist/src/platforms/wechatbot/client.js.map +1 -0
  185. package/dist/src/platforms/wechatbot/commands/auth.d.ts +28 -0
  186. package/dist/src/platforms/wechatbot/commands/auth.d.ts.map +1 -0
  187. package/dist/src/platforms/wechatbot/commands/auth.js +164 -0
  188. package/dist/src/platforms/wechatbot/commands/auth.js.map +1 -0
  189. package/dist/src/platforms/wechatbot/commands/index.d.ts +6 -0
  190. package/dist/src/platforms/wechatbot/commands/index.d.ts.map +1 -0
  191. package/dist/src/platforms/wechatbot/commands/index.js +6 -0
  192. package/dist/src/platforms/wechatbot/commands/index.js.map +1 -0
  193. package/dist/src/platforms/wechatbot/commands/message.d.ts +18 -0
  194. package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -0
  195. package/dist/src/platforms/wechatbot/commands/message.js +80 -0
  196. package/dist/src/platforms/wechatbot/commands/message.js.map +1 -0
  197. package/dist/src/platforms/wechatbot/commands/shared.d.ts +9 -0
  198. package/dist/src/platforms/wechatbot/commands/shared.d.ts.map +1 -0
  199. package/dist/src/platforms/wechatbot/commands/shared.js +13 -0
  200. package/dist/src/platforms/wechatbot/commands/shared.js.map +1 -0
  201. package/dist/src/platforms/wechatbot/commands/template.d.ts +19 -0
  202. package/dist/src/platforms/wechatbot/commands/template.d.ts.map +1 -0
  203. package/dist/src/platforms/wechatbot/commands/template.js +76 -0
  204. package/dist/src/platforms/wechatbot/commands/template.js.map +1 -0
  205. package/dist/src/platforms/wechatbot/commands/user.d.ts +20 -0
  206. package/dist/src/platforms/wechatbot/commands/user.d.ts.map +1 -0
  207. package/dist/src/platforms/wechatbot/commands/user.js +53 -0
  208. package/dist/src/platforms/wechatbot/commands/user.js.map +1 -0
  209. package/dist/src/platforms/wechatbot/commands/whoami.d.ts +12 -0
  210. package/dist/src/platforms/wechatbot/commands/whoami.d.ts.map +1 -0
  211. package/dist/src/platforms/wechatbot/commands/whoami.js +33 -0
  212. package/dist/src/platforms/wechatbot/commands/whoami.js.map +1 -0
  213. package/dist/src/platforms/wechatbot/credential-manager.d.ts +17 -0
  214. package/dist/src/platforms/wechatbot/credential-manager.d.ts.map +1 -0
  215. package/dist/src/platforms/wechatbot/credential-manager.js +121 -0
  216. package/dist/src/platforms/wechatbot/credential-manager.js.map +1 -0
  217. package/dist/src/platforms/wechatbot/index.d.ts +5 -0
  218. package/dist/src/platforms/wechatbot/index.d.ts.map +1 -0
  219. package/dist/src/platforms/wechatbot/index.js +4 -0
  220. package/dist/src/platforms/wechatbot/index.js.map +1 -0
  221. package/dist/src/platforms/wechatbot/types.d.ts +94 -0
  222. package/dist/src/platforms/wechatbot/types.d.ts.map +1 -0
  223. package/dist/src/platforms/wechatbot/types.js +54 -0
  224. package/dist/src/platforms/wechatbot/types.js.map +1 -0
  225. package/dist/src/platforms/whatsapp/cli.d.ts.map +1 -1
  226. package/dist/src/platforms/whatsapp/cli.js +2 -1
  227. package/dist/src/platforms/whatsapp/cli.js.map +1 -1
  228. package/dist/src/platforms/whatsapp/client.d.ts +9 -0
  229. package/dist/src/platforms/whatsapp/client.d.ts.map +1 -1
  230. package/dist/src/platforms/whatsapp/client.js +143 -21
  231. package/dist/src/platforms/whatsapp/client.js.map +1 -1
  232. package/dist/src/platforms/whatsapp/commands/auth.d.ts.map +1 -1
  233. package/dist/src/platforms/whatsapp/commands/auth.js +133 -60
  234. package/dist/src/platforms/whatsapp/commands/auth.js.map +1 -1
  235. package/dist/src/platforms/whatsapp/commands/index.d.ts +1 -0
  236. package/dist/src/platforms/whatsapp/commands/index.d.ts.map +1 -1
  237. package/dist/src/platforms/whatsapp/commands/index.js +1 -0
  238. package/dist/src/platforms/whatsapp/commands/index.js.map +1 -1
  239. package/dist/src/platforms/whatsapp/commands/shared.js +2 -2
  240. package/dist/src/platforms/whatsapp/commands/shared.js.map +1 -1
  241. package/dist/src/platforms/whatsapp/commands/whoami.d.ts +7 -0
  242. package/dist/src/platforms/whatsapp/commands/whoami.d.ts.map +1 -0
  243. package/dist/src/platforms/whatsapp/commands/whoami.js +19 -0
  244. package/dist/src/platforms/whatsapp/commands/whoami.js.map +1 -0
  245. package/dist/src/platforms/whatsapp/credential-manager.d.ts.map +1 -1
  246. package/dist/src/platforms/whatsapp/credential-manager.js +14 -8
  247. package/dist/src/platforms/whatsapp/credential-manager.js.map +1 -1
  248. package/dist/src/platforms/whatsapp/ensure-auth.js +2 -2
  249. package/dist/src/platforms/whatsapp/ensure-auth.js.map +1 -1
  250. package/dist/src/platforms/whatsappbot/cli.d.ts.map +1 -1
  251. package/dist/src/platforms/whatsappbot/cli.js +2 -1
  252. package/dist/src/platforms/whatsappbot/cli.js.map +1 -1
  253. package/dist/src/platforms/whatsappbot/commands/index.d.ts +1 -0
  254. package/dist/src/platforms/whatsappbot/commands/index.d.ts.map +1 -1
  255. package/dist/src/platforms/whatsappbot/commands/index.js +1 -0
  256. package/dist/src/platforms/whatsappbot/commands/index.js.map +1 -1
  257. package/dist/src/platforms/whatsappbot/commands/whoami.d.ts +17 -0
  258. package/dist/src/platforms/whatsappbot/commands/whoami.d.ts.map +1 -0
  259. package/dist/src/platforms/whatsappbot/commands/whoami.js +39 -0
  260. package/dist/src/platforms/whatsappbot/commands/whoami.js.map +1 -0
  261. package/dist/src/shared/utils/qr.d.ts +15 -0
  262. package/dist/src/shared/utils/qr.d.ts.map +1 -0
  263. package/dist/src/shared/utils/qr.js +74 -0
  264. package/dist/src/shared/utils/qr.js.map +1 -0
  265. package/dist/src/tui/adapters/whatsapp-adapter.d.ts.map +1 -1
  266. package/dist/src/tui/adapters/whatsapp-adapter.js +20 -15
  267. package/dist/src/tui/adapters/whatsapp-adapter.js.map +1 -1
  268. package/docs/content/docs/agent-skills.mdx +4 -4
  269. package/docs/content/docs/cli/channeltalk.mdx +12 -1
  270. package/docs/content/docs/cli/channeltalkbot.mdx +10 -1
  271. package/docs/content/docs/cli/discord.mdx +11 -1
  272. package/docs/content/docs/cli/discordbot.mdx +10 -1
  273. package/docs/content/docs/cli/instagram.mdx +12 -1
  274. package/docs/content/docs/cli/kakaotalk.mdx +25 -1
  275. package/docs/content/docs/cli/line.mdx +5 -5
  276. package/docs/content/docs/cli/meta.json +1 -0
  277. package/docs/content/docs/cli/slack.mdx +11 -1
  278. package/docs/content/docs/cli/slackbot.mdx +10 -1
  279. package/docs/content/docs/cli/teams.mdx +11 -1
  280. package/docs/content/docs/cli/telegram.mdx +11 -0
  281. package/docs/content/docs/cli/webex.mdx +11 -1
  282. package/docs/content/docs/cli/wechatbot.mdx +188 -0
  283. package/docs/content/docs/cli/whatsapp.mdx +37 -8
  284. package/docs/content/docs/cli/whatsappbot.mdx +10 -1
  285. package/docs/content/docs/sdk/meta.json +1 -1
  286. package/docs/content/docs/sdk/wechatbot.mdx +282 -0
  287. package/docs/content/docs/tui.mdx +1 -1
  288. package/docs/src/app/page.tsx +5 -5
  289. package/package.json +11 -3
  290. package/skills/agent-channeltalk/SKILL.md +12 -1
  291. package/skills/agent-channeltalkbot/SKILL.md +10 -1
  292. package/skills/agent-discord/SKILL.md +11 -1
  293. package/skills/agent-discordbot/SKILL.md +10 -1
  294. package/skills/agent-instagram/SKILL.md +12 -1
  295. package/skills/agent-kakaotalk/SKILL.md +30 -1
  296. package/skills/agent-kakaotalk/references/common-patterns.md +1 -1
  297. package/skills/agent-line/SKILL.md +11 -15
  298. package/skills/agent-line/references/authentication.md +13 -4
  299. package/skills/agent-slack/SKILL.md +11 -1
  300. package/skills/agent-slackbot/SKILL.md +10 -1
  301. package/skills/agent-teams/SKILL.md +11 -1
  302. package/skills/agent-telegram/SKILL.md +6 -1
  303. package/skills/agent-webex/SKILL.md +11 -1
  304. package/skills/agent-wechatbot/SKILL.md +394 -0
  305. package/skills/agent-whatsapp/SKILL.md +63 -15
  306. package/skills/agent-whatsapp/references/authentication.md +36 -6
  307. package/skills/agent-whatsappbot/SKILL.md +10 -1
  308. package/src/platforms/channeltalk/cli.ts +2 -0
  309. package/src/platforms/channeltalk/commands/index.ts +1 -0
  310. package/src/platforms/channeltalk/commands/whoami.test.ts +64 -0
  311. package/src/platforms/channeltalk/commands/whoami.ts +62 -0
  312. package/src/platforms/channeltalkbot/cli.ts +2 -0
  313. package/src/platforms/channeltalkbot/commands/index.ts +1 -0
  314. package/src/platforms/channeltalkbot/commands/whoami.test.ts +104 -0
  315. package/src/platforms/channeltalkbot/commands/whoami.ts +42 -0
  316. package/src/platforms/discord/cli.ts +2 -0
  317. package/src/platforms/discord/commands/index.ts +1 -0
  318. package/src/platforms/discord/commands/whoami.test.ts +91 -0
  319. package/src/platforms/discord/commands/whoami.ts +36 -0
  320. package/src/platforms/discord/credential-manager.test.ts +18 -1
  321. package/src/platforms/discordbot/cli.ts +2 -0
  322. package/src/platforms/discordbot/client.ts +2 -2
  323. package/src/platforms/discordbot/commands/index.ts +1 -0
  324. package/src/platforms/discordbot/commands/whoami.test.ts +96 -0
  325. package/src/platforms/discordbot/commands/whoami.ts +44 -0
  326. package/src/platforms/instagram/cli.ts +2 -1
  327. package/src/platforms/instagram/client.ts +13 -0
  328. package/src/platforms/instagram/commands/auth.test.ts +216 -0
  329. package/src/platforms/instagram/commands/chat.test.ts +123 -0
  330. package/src/platforms/instagram/commands/index.ts +1 -0
  331. package/src/platforms/instagram/commands/message.test.ts +174 -0
  332. package/src/platforms/instagram/commands/whoami.test.ts +60 -0
  333. package/src/platforms/instagram/commands/whoami.ts +21 -0
  334. package/src/platforms/kakaotalk/cli.ts +2 -1
  335. package/src/platforms/kakaotalk/client.test.ts +182 -14
  336. package/src/platforms/kakaotalk/client.ts +261 -27
  337. package/src/platforms/kakaotalk/commands/auth.test.ts +299 -0
  338. package/src/platforms/kakaotalk/commands/chat.test.ts +97 -0
  339. package/src/platforms/kakaotalk/commands/index.ts +1 -0
  340. package/src/platforms/kakaotalk/commands/message.test.ts +113 -0
  341. package/src/platforms/kakaotalk/commands/whoami.test.ts +116 -0
  342. package/src/platforms/kakaotalk/commands/whoami.ts +21 -0
  343. package/src/platforms/kakaotalk/index.test.ts +5 -0
  344. package/src/platforms/kakaotalk/index.ts +2 -0
  345. package/src/platforms/kakaotalk/protocol/session.ts +29 -7
  346. package/src/platforms/kakaotalk/protocol/types.ts +9 -0
  347. package/src/platforms/kakaotalk/types.ts +30 -0
  348. package/src/platforms/line/cli.ts +2 -2
  349. package/src/platforms/line/client.ts +14 -39
  350. package/src/platforms/line/commands/auth.test.ts +141 -0
  351. package/src/platforms/line/commands/auth.ts +37 -61
  352. package/src/platforms/line/commands/chat.test.ts +110 -0
  353. package/src/platforms/line/commands/friend.test.ts +98 -0
  354. package/src/platforms/line/commands/index.ts +1 -1
  355. package/src/platforms/line/commands/message.test.ts +119 -0
  356. package/src/platforms/line/commands/whoami.test.ts +85 -0
  357. package/src/platforms/line/commands/{profile.ts → whoami.ts} +4 -4
  358. package/src/platforms/slack/cli.ts +2 -0
  359. package/src/platforms/slack/commands/index.ts +1 -0
  360. package/src/platforms/slack/commands/whoami.test.ts +126 -0
  361. package/src/platforms/slack/commands/whoami.ts +40 -0
  362. package/src/platforms/slackbot/cli.ts +2 -1
  363. package/src/platforms/slackbot/commands/channel.test.ts +139 -0
  364. package/src/platforms/slackbot/commands/index.ts +1 -0
  365. package/src/platforms/slackbot/commands/message.test.ts +226 -0
  366. package/src/platforms/slackbot/commands/reaction.test.ts +90 -0
  367. package/src/platforms/slackbot/commands/user.test.ts +143 -0
  368. package/src/platforms/slackbot/commands/whoami.test.ts +102 -0
  369. package/src/platforms/slackbot/commands/whoami.ts +44 -0
  370. package/src/platforms/teams/cli.ts +2 -0
  371. package/src/platforms/teams/commands/index.ts +1 -0
  372. package/src/platforms/teams/commands/reaction.test.ts +45 -61
  373. package/src/platforms/teams/commands/reaction.ts +2 -0
  374. package/src/platforms/teams/commands/whoami.test.ts +83 -0
  375. package/src/platforms/teams/commands/whoami.ts +33 -0
  376. package/src/platforms/telegram/cli.ts +2 -1
  377. package/src/platforms/telegram/commands/chat.test.ts +125 -0
  378. package/src/platforms/telegram/commands/index.ts +1 -0
  379. package/src/platforms/telegram/commands/message.test.ts +92 -0
  380. package/src/platforms/telegram/commands/whoami.test.ts +75 -0
  381. package/src/platforms/telegram/commands/whoami.ts +29 -0
  382. package/src/platforms/webex/cli.ts +2 -1
  383. package/src/platforms/webex/commands/auth.test.ts +58 -46
  384. package/src/platforms/webex/commands/index.ts +1 -0
  385. package/src/platforms/webex/commands/member.test.ts +60 -57
  386. package/src/platforms/webex/commands/message.test.ts +74 -121
  387. package/src/platforms/webex/commands/message.ts +1 -1
  388. package/src/platforms/webex/commands/snapshot.test.ts +54 -45
  389. package/src/platforms/webex/commands/space.test.ts +46 -49
  390. package/src/platforms/webex/commands/whoami.test.ts +113 -0
  391. package/src/platforms/webex/commands/whoami.ts +31 -0
  392. package/src/platforms/webex/credential-manager.test.ts +0 -1
  393. package/src/platforms/wechatbot/cli.ts +25 -0
  394. package/src/platforms/wechatbot/client.test.ts +497 -0
  395. package/src/platforms/wechatbot/client.ts +268 -0
  396. package/src/platforms/wechatbot/commands/auth.test.ts +211 -0
  397. package/src/platforms/wechatbot/commands/auth.ts +203 -0
  398. package/src/platforms/wechatbot/commands/index.ts +5 -0
  399. package/src/platforms/wechatbot/commands/message.test.ts +155 -0
  400. package/src/platforms/wechatbot/commands/message.ts +104 -0
  401. package/src/platforms/wechatbot/commands/shared.ts +22 -0
  402. package/src/platforms/wechatbot/commands/template.test.ts +199 -0
  403. package/src/platforms/wechatbot/commands/template.ts +102 -0
  404. package/src/platforms/wechatbot/commands/user.test.ts +165 -0
  405. package/src/platforms/wechatbot/commands/user.ts +75 -0
  406. package/src/platforms/wechatbot/commands/whoami.test.ts +109 -0
  407. package/src/platforms/wechatbot/commands/whoami.ts +43 -0
  408. package/src/platforms/wechatbot/credential-manager.test.ts +255 -0
  409. package/src/platforms/wechatbot/credential-manager.ts +148 -0
  410. package/src/platforms/wechatbot/index.test.ts +49 -0
  411. package/src/platforms/wechatbot/index.ts +19 -0
  412. package/src/platforms/wechatbot/types.test.ts +223 -0
  413. package/src/platforms/wechatbot/types.ts +107 -0
  414. package/src/platforms/whatsapp/cli.ts +2 -1
  415. package/src/platforms/whatsapp/client.ts +180 -37
  416. package/src/platforms/whatsapp/commands/auth.test.ts +311 -0
  417. package/src/platforms/whatsapp/commands/auth.ts +194 -84
  418. package/src/platforms/whatsapp/commands/chat.test.ts +198 -0
  419. package/src/platforms/whatsapp/commands/index.ts +1 -0
  420. package/src/platforms/whatsapp/commands/message.test.ts +231 -0
  421. package/src/platforms/whatsapp/commands/shared.ts +2 -2
  422. package/src/platforms/whatsapp/commands/whoami.test.ts +59 -0
  423. package/src/platforms/whatsapp/commands/whoami.ts +21 -0
  424. package/src/platforms/whatsapp/credential-manager.test.ts +20 -0
  425. package/src/platforms/whatsapp/credential-manager.ts +17 -8
  426. package/src/platforms/whatsapp/ensure-auth.ts +2 -2
  427. package/src/platforms/whatsappbot/cli.ts +2 -1
  428. package/src/platforms/whatsappbot/commands/auth.test.ts +217 -0
  429. package/src/platforms/whatsappbot/commands/index.ts +1 -0
  430. package/src/platforms/whatsappbot/commands/message.test.ts +198 -0
  431. package/src/platforms/whatsappbot/commands/template.test.ts +112 -0
  432. package/src/platforms/whatsappbot/commands/whoami.test.ts +100 -0
  433. package/src/platforms/whatsappbot/commands/whoami.ts +57 -0
  434. package/src/shared/utils/qr.ts +92 -0
  435. package/src/tui/adapters/whatsapp-adapter.ts +19 -16
  436. package/dist/src/platforms/line/commands/profile.d.ts +0 -3
  437. package/dist/src/platforms/line/commands/profile.d.ts.map +0 -1
  438. package/dist/src/platforms/line/commands/profile.js.map +0 -1
@@ -0,0 +1,98 @@
1
+ import { afterEach, beforeEach, expect, mock, spyOn, test } from 'bun:test'
2
+
3
+ const originalConsoleLog = console.log
4
+
5
+ import { LineClient } from '../client'
6
+ import { friendCommand } from './friend'
7
+
8
+ let loginSpy: ReturnType<typeof spyOn>
9
+ let getFriendsSpy: ReturnType<typeof spyOn>
10
+ let closeSpy: ReturnType<typeof spyOn>
11
+ let consoleLogSpy: ReturnType<typeof mock>
12
+
13
+ beforeEach(() => {
14
+ loginSpy = spyOn(LineClient.prototype, 'login').mockImplementation(async function (this: LineClient) {
15
+ return this
16
+ })
17
+
18
+ getFriendsSpy = spyOn(LineClient.prototype, 'getFriends').mockResolvedValue([
19
+ {
20
+ mid: 'u111',
21
+ display_name: 'Alice',
22
+ picture_url: 'https://example.com/alice.jpg',
23
+ status_message: 'Hey!',
24
+ },
25
+ {
26
+ mid: 'u222',
27
+ display_name: 'Bob',
28
+ picture_url: 'https://example.com/bob.jpg',
29
+ status_message: 'Hello',
30
+ },
31
+ ])
32
+
33
+ closeSpy = spyOn(LineClient.prototype, 'close').mockImplementation(() => {})
34
+ consoleLogSpy = mock((..._args: unknown[]) => {}); console.log = consoleLogSpy
35
+ })
36
+
37
+ afterEach(() => {
38
+ loginSpy?.mockRestore()
39
+ getFriendsSpy?.mockRestore()
40
+ closeSpy?.mockRestore()
41
+ console.log = originalConsoleLog
42
+ })
43
+
44
+ test('list: fetches and outputs friends', async () => {
45
+ // when
46
+ await friendCommand.parseAsync(['node', 'friend', 'list'])
47
+
48
+ // then
49
+ expect(loginSpy).toHaveBeenCalledTimes(1)
50
+ expect(getFriendsSpy).toHaveBeenCalledTimes(1)
51
+ expect(consoleLogSpy).toHaveBeenCalledTimes(1)
52
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
53
+ expect(output).toHaveLength(2)
54
+ expect(output[0].mid).toBe('u111')
55
+ expect(output[0].display_name).toBe('Alice')
56
+ })
57
+
58
+ test('list: outputs friends with metadata', async () => {
59
+ // when
60
+ await friendCommand.parseAsync(['node', 'friend', 'list'])
61
+
62
+ // then
63
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
64
+ const friend = output[0]
65
+ expect(friend.mid).toBeDefined()
66
+ expect(friend.display_name).toBeDefined()
67
+ })
68
+
69
+ test('list: closes client after fetching friends', async () => {
70
+ // when
71
+ await friendCommand.parseAsync(['node', 'friend', 'list'])
72
+
73
+ // then
74
+ expect(closeSpy).toHaveBeenCalledTimes(1)
75
+ })
76
+
77
+ test('list: outputs empty array when no friends', async () => {
78
+ // given
79
+ getFriendsSpy.mockResolvedValue([])
80
+
81
+ // when
82
+ await friendCommand.parseAsync(['node', 'friend', 'list'])
83
+
84
+ // then
85
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
86
+ expect(output).toHaveLength(0)
87
+ })
88
+
89
+ test('list: includes all friend fields', async () => {
90
+ // when
91
+ await friendCommand.parseAsync(['node', 'friend', 'list'])
92
+
93
+ // then
94
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
95
+ expect(output[0].picture_url).toBe('https://example.com/alice.jpg')
96
+ expect(output[0].status_message).toBe('Hey!')
97
+ expect(output[1].display_name).toBe('Bob')
98
+ })
@@ -2,4 +2,4 @@ export { authCommand } from './auth'
2
2
  export { chatCommand } from './chat'
3
3
  export { friendCommand } from './friend'
4
4
  export { messageCommand } from './message'
5
- export { profileCommand } from './profile'
5
+ export { whoamiCommand } from './whoami'
@@ -0,0 +1,119 @@
1
+ import { afterEach, beforeEach, expect, mock, spyOn, test } from 'bun:test'
2
+
3
+ const originalConsoleLog = console.log
4
+
5
+ import { LineClient } from '../client'
6
+ import { messageCommand } from './message'
7
+
8
+ let loginSpy: ReturnType<typeof spyOn>
9
+ let getMessagesSpy: ReturnType<typeof spyOn>
10
+ let sendMessageSpy: ReturnType<typeof spyOn>
11
+ let closeSpy: ReturnType<typeof spyOn>
12
+ let consoleLogSpy: ReturnType<typeof mock>
13
+
14
+ beforeEach(() => {
15
+ loginSpy = spyOn(LineClient.prototype, 'login').mockImplementation(async function (this: LineClient) {
16
+ return this
17
+ })
18
+
19
+ getMessagesSpy = spyOn(LineClient.prototype, 'getMessages').mockResolvedValue([
20
+ {
21
+ message_id: 'msg-1',
22
+ chat_id: 'chat-1',
23
+ author_id: 'u123',
24
+ text: 'Hello world',
25
+ content_type: 'NONE',
26
+ sent_at: '2024-01-01T10:00:00Z',
27
+ },
28
+ {
29
+ message_id: 'msg-2',
30
+ chat_id: 'chat-1',
31
+ author_id: 'u456',
32
+ text: 'Hi there',
33
+ content_type: 'NONE',
34
+ sent_at: '2024-01-01T09:00:00Z',
35
+ },
36
+ ])
37
+
38
+ sendMessageSpy = spyOn(LineClient.prototype, 'sendMessage').mockResolvedValue({
39
+ success: true,
40
+ chat_id: 'chat-1',
41
+ message_id: 'msg-new',
42
+ sent_at: '2024-01-01T11:00:00Z',
43
+ })
44
+
45
+ closeSpy = spyOn(LineClient.prototype, 'close').mockImplementation(() => {})
46
+ consoleLogSpy = mock((..._args: unknown[]) => {}); console.log = consoleLogSpy
47
+ })
48
+
49
+ afterEach(() => {
50
+ loginSpy?.mockRestore()
51
+ getMessagesSpy?.mockRestore()
52
+ sendMessageSpy?.mockRestore()
53
+ closeSpy?.mockRestore()
54
+ console.log = originalConsoleLog
55
+ })
56
+
57
+ test('list: fetches and outputs messages for a chat', async () => {
58
+ // when
59
+ await messageCommand.parseAsync(['node', 'message', 'list', 'chat-1'])
60
+
61
+ // then
62
+ expect(loginSpy).toHaveBeenCalledTimes(1)
63
+ expect(getMessagesSpy).toHaveBeenCalledWith('chat-1', { count: 20 })
64
+ expect(consoleLogSpy).toHaveBeenCalledTimes(1)
65
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
66
+ expect(output).toHaveLength(2)
67
+ expect(output[0].message_id).toBe('msg-1')
68
+ expect(output[0].text).toBe('Hello world')
69
+ })
70
+
71
+ test('list: uses custom count when --count option provided', async () => {
72
+ // when
73
+ await messageCommand.parseAsync(['node', 'message', 'list', 'chat-1', '--count', '5'])
74
+
75
+ // then
76
+ expect(getMessagesSpy).toHaveBeenCalledWith('chat-1', { count: 5 })
77
+ })
78
+
79
+ test('list: closes client after fetching messages', async () => {
80
+ // when
81
+ await messageCommand.parseAsync(['node', 'message', 'list', 'chat-1'])
82
+
83
+ // then
84
+ expect(closeSpy).toHaveBeenCalledTimes(1)
85
+ })
86
+
87
+ test('send: sends message and outputs result', async () => {
88
+ // when
89
+ await messageCommand.parseAsync(['node', 'message', 'send', 'chat-1', 'Hello!'])
90
+
91
+ // then
92
+ expect(loginSpy).toHaveBeenCalledTimes(1)
93
+ expect(sendMessageSpy).toHaveBeenCalledWith('chat-1', 'Hello!')
94
+ expect(consoleLogSpy).toHaveBeenCalledTimes(1)
95
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
96
+ expect(output.success).toBe(true)
97
+ expect(output.message_id).toBe('msg-new')
98
+ })
99
+
100
+ test('send: closes client after sending message', async () => {
101
+ // when
102
+ await messageCommand.parseAsync(['node', 'message', 'send', 'chat-1', 'Hello!'])
103
+
104
+ // then
105
+ expect(closeSpy).toHaveBeenCalledTimes(1)
106
+ })
107
+
108
+ test('list: outputs messages with metadata', async () => {
109
+ // when
110
+ await messageCommand.parseAsync(['node', 'message', 'list', 'chat-1'])
111
+
112
+ // then
113
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
114
+ const msg = output[0]
115
+ expect(msg.message_id).toBeDefined()
116
+ expect(msg.chat_id).toBeDefined()
117
+ expect(msg.author_id).toBeDefined()
118
+ expect(msg.sent_at).toBeDefined()
119
+ })
@@ -0,0 +1,85 @@
1
+ import { afterEach, beforeEach, expect, mock, spyOn, test } from 'bun:test'
2
+
3
+ const originalConsoleLog = console.log
4
+
5
+ import { LineClient } from '../client'
6
+ import { whoamiCommand } from './whoami'
7
+
8
+ let loginSpy: ReturnType<typeof spyOn>
9
+ let getProfileSpy: ReturnType<typeof spyOn>
10
+ let closeSpy: ReturnType<typeof spyOn>
11
+ let consoleLogSpy: ReturnType<typeof mock>
12
+
13
+ beforeEach(() => {
14
+ loginSpy = spyOn(LineClient.prototype, 'login').mockImplementation(async function (this: LineClient) {
15
+ return this
16
+ })
17
+
18
+ getProfileSpy = spyOn(LineClient.prototype, 'getProfile').mockResolvedValue({
19
+ mid: 'u1234567890abcdef',
20
+ display_name: 'Test User',
21
+ picture_url: 'https://example.com/pic.jpg',
22
+ status_message: 'Hello LINE!',
23
+ })
24
+
25
+ closeSpy = spyOn(LineClient.prototype, 'close').mockImplementation(() => {})
26
+ consoleLogSpy = mock((..._args: unknown[]) => {}); console.log = consoleLogSpy
27
+ })
28
+
29
+ afterEach(() => {
30
+ loginSpy?.mockRestore()
31
+ getProfileSpy?.mockRestore()
32
+ closeSpy?.mockRestore()
33
+ console.log = originalConsoleLog
34
+ })
35
+
36
+ test('whoami: fetches and outputs profile', async () => {
37
+ // when
38
+ await whoamiCommand.parseAsync(['node', 'whoami'])
39
+
40
+ // then
41
+ expect(loginSpy).toHaveBeenCalledTimes(1)
42
+ expect(getProfileSpy).toHaveBeenCalledTimes(1)
43
+ expect(consoleLogSpy).toHaveBeenCalledTimes(1)
44
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
45
+ expect(output.mid).toBe('u1234567890abcdef')
46
+ expect(output.display_name).toBe('Test User')
47
+ })
48
+
49
+ test('whoami: outputs profile with all fields', async () => {
50
+ // when
51
+ await whoamiCommand.parseAsync(['node', 'whoami'])
52
+
53
+ // then
54
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
55
+ expect(output.mid).toBeDefined()
56
+ expect(output.display_name).toBeDefined()
57
+ expect(output.picture_url).toBeDefined()
58
+ expect(output.status_message).toBeDefined()
59
+ })
60
+
61
+ test('whoami: closes client after fetching profile', async () => {
62
+ // when
63
+ await whoamiCommand.parseAsync(['node', 'whoami'])
64
+
65
+ // then
66
+ expect(closeSpy).toHaveBeenCalledTimes(1)
67
+ })
68
+
69
+ test('whoami: outputs profile with picture_url', async () => {
70
+ // when
71
+ await whoamiCommand.parseAsync(['node', 'whoami'])
72
+
73
+ // then
74
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
75
+ expect(output.picture_url).toBe('https://example.com/pic.jpg')
76
+ })
77
+
78
+ test('whoami: outputs profile with status_message', async () => {
79
+ // when
80
+ await whoamiCommand.parseAsync(['node', 'whoami'])
81
+
82
+ // then
83
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
84
+ expect(output.status_message).toBe('Hello LINE!')
85
+ })
@@ -5,7 +5,7 @@ import { formatOutput } from '@/shared/utils/output'
5
5
 
6
6
  import { LineClient } from '../client'
7
7
 
8
- async function profileAction(options: { pretty?: boolean }): Promise<void> {
8
+ async function whoamiAction(options: { pretty?: boolean }): Promise<void> {
9
9
  let client: LineClient | undefined
10
10
  try {
11
11
  client = await new LineClient().login()
@@ -18,7 +18,7 @@ async function profileAction(options: { pretty?: boolean }): Promise<void> {
18
18
  }
19
19
  }
20
20
 
21
- export const profileCommand = new Command('profile')
22
- .description('Show your LINE profile')
21
+ export const whoamiCommand = new Command('whoami')
22
+ .description('Show current authenticated user')
23
23
  .option('--pretty', 'Pretty print JSON output')
24
- .action(profileAction)
24
+ .action(whoamiAction)
@@ -22,6 +22,7 @@ import {
22
22
  unreadCommand,
23
23
  userCommand,
24
24
  usergroupCommand,
25
+ whoamiCommand,
25
26
  workspaceCommand,
26
27
  } from './commands/index'
27
28
  import { ensureSlackAuth } from './ensure-auth'
@@ -66,6 +67,7 @@ program.addCommand(bookmarkCommand)
66
67
  program.addCommand(reminderCommand)
67
68
  program.addCommand(emojiCommand)
68
69
  program.addCommand(usergroupCommand)
70
+ program.addCommand(whoamiCommand)
69
71
 
70
72
  program.parse(process.argv)
71
73
 
@@ -15,4 +15,5 @@ export { snapshotCommand } from './snapshot'
15
15
  export { unreadCommand } from './unread'
16
16
  export { userCommand } from './user'
17
17
  export { usergroupCommand } from './usergroup'
18
+ export { whoamiCommand } from './whoami'
18
19
  export { workspaceCommand } from './workspace'
@@ -0,0 +1,126 @@
1
+ import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
2
+
3
+ import { SlackClient } from '@/platforms/slack/client'
4
+ import { CredentialManager } from '@/platforms/slack/credential-manager'
5
+ import { whoamiAction, whoamiCommand } from '@/platforms/slack/commands/whoami'
6
+
7
+ let credManagerSpy: ReturnType<typeof spyOn>
8
+ let clientTestAuthSpy: ReturnType<typeof spyOn>
9
+ let clientGetUserSpy: ReturnType<typeof spyOn>
10
+ let consoleLogSpy: ReturnType<typeof spyOn>
11
+ let processExitSpy: ReturnType<typeof spyOn>
12
+
13
+ const mockWorkspace = {
14
+ workspace_id: 'T123',
15
+ workspace_name: 'Test Workspace',
16
+ token: 'xoxc-test',
17
+ cookie: 'test-cookie',
18
+ }
19
+
20
+ const mockAuthInfo = {
21
+ user_id: 'U123',
22
+ team_id: 'T123',
23
+ user: 'alice',
24
+ team: 'Test Workspace',
25
+ }
26
+
27
+ const mockUser = {
28
+ id: 'U123',
29
+ name: 'alice',
30
+ real_name: 'Alice Smith',
31
+ is_admin: true,
32
+ is_owner: false,
33
+ is_bot: false,
34
+ is_app_user: false,
35
+ profile: {
36
+ email: 'alice@example.com',
37
+ title: 'Engineer',
38
+ },
39
+ }
40
+
41
+ beforeEach(() => {
42
+ credManagerSpy = spyOn(CredentialManager.prototype, 'getWorkspace').mockResolvedValue(mockWorkspace)
43
+ clientTestAuthSpy = spyOn(SlackClient.prototype, 'testAuth').mockResolvedValue(mockAuthInfo)
44
+ clientGetUserSpy = spyOn(SlackClient.prototype, 'getUser').mockResolvedValue(mockUser)
45
+ consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
46
+ processExitSpy = spyOn(process, 'exit').mockImplementation((_code?: number) => undefined as never)
47
+ })
48
+
49
+ afterEach(() => {
50
+ credManagerSpy?.mockRestore()
51
+ clientTestAuthSpy?.mockRestore()
52
+ clientGetUserSpy?.mockRestore()
53
+ consoleLogSpy?.mockRestore()
54
+ processExitSpy?.mockRestore()
55
+ })
56
+
57
+ test('whoami command is defined with correct name and description', () => {
58
+ expect(whoamiCommand).toBeDefined()
59
+ expect(whoamiCommand.name()).toBe('whoami')
60
+ expect(whoamiCommand.description()).toBe('Show current authenticated user')
61
+ })
62
+
63
+ test('whoami command has --pretty option', () => {
64
+ const options = whoamiCommand.options
65
+ const hasPretty = options.some((opt: { long?: string }) => opt.long === '--pretty')
66
+ expect(hasPretty).toBe(true)
67
+ })
68
+
69
+ test('whoami outputs expected fields', async () => {
70
+ await whoamiAction({})
71
+
72
+ expect(consoleLogSpy).toHaveBeenCalledWith(
73
+ JSON.stringify({
74
+ id: 'U123',
75
+ name: 'alice',
76
+ real_name: 'Alice Smith',
77
+ is_admin: true,
78
+ is_owner: false,
79
+ is_bot: false,
80
+ is_app_user: false,
81
+ team_id: 'T123',
82
+ team: 'Test Workspace',
83
+ profile: {
84
+ email: 'alice@example.com',
85
+ title: 'Engineer',
86
+ },
87
+ }),
88
+ )
89
+ })
90
+
91
+ test('whoami outputs pretty-printed JSON when pretty is true', async () => {
92
+ await whoamiAction({ pretty: true })
93
+
94
+ expect(consoleLogSpy).toHaveBeenCalledWith(
95
+ JSON.stringify(
96
+ {
97
+ id: 'U123',
98
+ name: 'alice',
99
+ real_name: 'Alice Smith',
100
+ is_admin: true,
101
+ is_owner: false,
102
+ is_bot: false,
103
+ is_app_user: false,
104
+ team_id: 'T123',
105
+ team: 'Test Workspace',
106
+ profile: {
107
+ email: 'alice@example.com',
108
+ title: 'Engineer',
109
+ },
110
+ },
111
+ null,
112
+ 2,
113
+ ),
114
+ )
115
+ })
116
+
117
+ test('whoami exits with error when no workspace is set', async () => {
118
+ credManagerSpy.mockResolvedValue(null)
119
+
120
+ await whoamiAction({})
121
+
122
+ expect(consoleLogSpy).toHaveBeenCalledWith(
123
+ JSON.stringify({ error: 'No current workspace set. Run "auth extract" first.' }),
124
+ )
125
+ expect(processExitSpy).toHaveBeenCalledWith(1)
126
+ })
@@ -0,0 +1,40 @@
1
+ import { Command } from 'commander'
2
+ import { handleError } from '@/shared/utils/error-handler'
3
+ import { formatOutput } from '@/shared/utils/output'
4
+ import { SlackClient } from '../client'
5
+ import { CredentialManager } from '../credential-manager'
6
+
7
+ export async function whoamiAction(options: { pretty?: boolean }): Promise<void> {
8
+ try {
9
+ const credManager = new CredentialManager()
10
+ const workspace = await credManager.getWorkspace()
11
+ if (!workspace) {
12
+ console.log(formatOutput({ error: 'No current workspace set. Run "auth extract" first.' }, options.pretty))
13
+ return process.exit(1)
14
+ }
15
+ const client = await new SlackClient().login({ token: workspace.token, cookie: workspace.cookie })
16
+ const authInfo = await client.testAuth()
17
+ const user = await client.getUser(authInfo.user_id)
18
+
19
+ const output = {
20
+ id: user.id,
21
+ name: user.name,
22
+ real_name: user.real_name,
23
+ is_admin: user.is_admin,
24
+ is_owner: user.is_owner,
25
+ is_bot: user.is_bot,
26
+ is_app_user: user.is_app_user,
27
+ team_id: authInfo.team_id,
28
+ team: authInfo.team,
29
+ profile: user.profile,
30
+ }
31
+ console.log(formatOutput(output, options.pretty))
32
+ } catch (error) {
33
+ handleError(error as Error)
34
+ }
35
+ }
36
+
37
+ export const whoamiCommand = new Command('whoami')
38
+ .description('Show current authenticated user')
39
+ .option('--pretty', 'Pretty print JSON output')
40
+ .action(whoamiAction)
@@ -3,7 +3,7 @@
3
3
  import { Command } from 'commander'
4
4
 
5
5
  import pkg from '../../../package.json' with { type: 'json' }
6
- import { authCommand, channelCommand, messageCommand, reactionCommand, userCommand } from './commands/index'
6
+ import { authCommand, channelCommand, messageCommand, reactionCommand, userCommand, whoamiCommand } from './commands/index'
7
7
 
8
8
  const program = new Command()
9
9
 
@@ -14,6 +14,7 @@ program
14
14
  .option('--bot <id>', 'Use specific bot (default: current)')
15
15
 
16
16
  program.addCommand(authCommand)
17
+ program.addCommand(whoamiCommand)
17
18
  program.addCommand(messageCommand)
18
19
  program.addCommand(channelCommand)
19
20
  program.addCommand(userCommand)
@@ -0,0 +1,139 @@
1
+ import { beforeEach, describe, expect, mock, test } from 'bun:test'
2
+
3
+ const mockResolveChannel = mock((_channel: string) => Promise.resolve('C123456'))
4
+ const mockListChannels = mock(() =>
5
+ Promise.resolve([
6
+ {
7
+ id: 'C123456',
8
+ name: 'general',
9
+ is_private: false,
10
+ is_archived: false,
11
+ created: 1609459200,
12
+ creator: 'U123',
13
+ },
14
+ {
15
+ id: 'C789012',
16
+ name: 'random',
17
+ is_private: false,
18
+ is_archived: false,
19
+ created: 1609459200,
20
+ creator: 'U123',
21
+ },
22
+ ]),
23
+ )
24
+ const mockGetChannelInfo = mock(() =>
25
+ Promise.resolve({
26
+ id: 'C123456',
27
+ name: 'general',
28
+ is_private: false,
29
+ is_archived: false,
30
+ created: 1609459200,
31
+ creator: 'U123',
32
+ topic: { value: 'General discussion', creator: 'U123', last_set: 1609459200 },
33
+ purpose: { value: 'Company-wide announcements', creator: 'U123', last_set: 1609459200 },
34
+ }),
35
+ )
36
+
37
+ mock.module('../client', () => ({
38
+ SlackBotClient: class MockSlackBotClient {
39
+ async login(_credentials?: { token: string }) {
40
+ return this
41
+ }
42
+ resolveChannel = mockResolveChannel
43
+ listChannels = mockListChannels
44
+ getChannelInfo = mockGetChannelInfo
45
+ },
46
+ }))
47
+
48
+ import { SlackBotClient } from '../client'
49
+
50
+ describe('channel commands', () => {
51
+ beforeEach(() => {
52
+ mockResolveChannel.mockClear()
53
+ mockListChannels.mockClear()
54
+ mockGetChannelInfo.mockClear()
55
+ })
56
+
57
+ describe('listChannels', () => {
58
+ test('returns list of channels', async () => {
59
+ // given
60
+ const client = await new SlackBotClient().login({ token: 'xoxb-test-token' })
61
+
62
+ // when
63
+ const channels = await client.listChannels()
64
+
65
+ // then
66
+ expect(channels).toHaveLength(2)
67
+ expect(channels[0].name).toBe('general')
68
+ expect(channels[1].name).toBe('random')
69
+ })
70
+
71
+ test('includes channel metadata', async () => {
72
+ // given
73
+ const client = await new SlackBotClient().login({ token: 'xoxb-test-token' })
74
+
75
+ // when
76
+ const channels = await client.listChannels()
77
+ const channel = channels[0]
78
+
79
+ // then
80
+ expect(channel.id).toBeDefined()
81
+ expect(channel.name).toBeDefined()
82
+ expect(channel.is_private).toBe(false)
83
+ expect(channel.is_archived).toBe(false)
84
+ expect(channel.created).toBeDefined()
85
+ })
86
+
87
+ test('passes limit option', async () => {
88
+ // given
89
+ const client = await new SlackBotClient().login({ token: 'xoxb-test-token' })
90
+
91
+ // when
92
+ await client.listChannels({ limit: 50 })
93
+
94
+ // then
95
+ expect(mockListChannels).toHaveBeenCalledWith({ limit: 50 })
96
+ })
97
+ })
98
+
99
+ describe('getChannelInfo', () => {
100
+ test('returns channel details', async () => {
101
+ // given
102
+ const client = await new SlackBotClient().login({ token: 'xoxb-test-token' })
103
+
104
+ // when
105
+ const channel = await client.getChannelInfo('C123456')
106
+
107
+ // then
108
+ expect(channel.id).toBe('C123456')
109
+ expect(channel.name).toBe('general')
110
+ expect(channel.is_private).toBe(false)
111
+ })
112
+
113
+ test('includes topic and purpose', async () => {
114
+ // given
115
+ const client = await new SlackBotClient().login({ token: 'xoxb-test-token' })
116
+
117
+ // when
118
+ const channel = await client.getChannelInfo('C123456')
119
+
120
+ // then
121
+ expect(channel.topic?.value).toBe('General discussion')
122
+ expect(channel.purpose?.value).toBe('Company-wide announcements')
123
+ })
124
+ })
125
+
126
+ describe('resolveChannel', () => {
127
+ test('resolves channel name to ID', async () => {
128
+ // given
129
+ const client = await new SlackBotClient().login({ token: 'xoxb-test-token' })
130
+
131
+ // when
132
+ const channelId = await client.resolveChannel('general')
133
+
134
+ // then
135
+ expect(channelId).toBe('C123456')
136
+ expect(mockResolveChannel).toHaveBeenCalledWith('general')
137
+ })
138
+ })
139
+ })
@@ -3,3 +3,4 @@ export { channelCommand } from './channel'
3
3
  export { messageCommand } from './message'
4
4
  export { reactionCommand } from './reaction'
5
5
  export { userCommand } from './user'
6
+ export { whoamiCommand } from './whoami'