agent-messenger 2.4.0 → 2.6.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 (359) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.github/workflows/ci.yml +35 -0
  3. package/.github/workflows/release.yml +0 -12
  4. package/README.md +3 -3
  5. package/bun.lock +10 -2
  6. package/dist/package.json +3 -1
  7. package/dist/src/platforms/channeltalk/cli.d.ts.map +1 -1
  8. package/dist/src/platforms/channeltalk/cli.js +2 -1
  9. package/dist/src/platforms/channeltalk/cli.js.map +1 -1
  10. package/dist/src/platforms/channeltalk/commands/index.d.ts +1 -0
  11. package/dist/src/platforms/channeltalk/commands/index.d.ts.map +1 -1
  12. package/dist/src/platforms/channeltalk/commands/index.js +1 -0
  13. package/dist/src/platforms/channeltalk/commands/index.js.map +1 -1
  14. package/dist/src/platforms/channeltalk/commands/whoami.d.ts +22 -0
  15. package/dist/src/platforms/channeltalk/commands/whoami.d.ts.map +1 -0
  16. package/dist/src/platforms/channeltalk/commands/whoami.js +40 -0
  17. package/dist/src/platforms/channeltalk/commands/whoami.js.map +1 -0
  18. package/dist/src/platforms/channeltalkbot/cli.d.ts.map +1 -1
  19. package/dist/src/platforms/channeltalkbot/cli.js +2 -1
  20. package/dist/src/platforms/channeltalkbot/cli.js.map +1 -1
  21. package/dist/src/platforms/channeltalkbot/commands/index.d.ts +1 -0
  22. package/dist/src/platforms/channeltalkbot/commands/index.d.ts.map +1 -1
  23. package/dist/src/platforms/channeltalkbot/commands/index.js +1 -0
  24. package/dist/src/platforms/channeltalkbot/commands/index.js.map +1 -1
  25. package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts +13 -0
  26. package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts.map +1 -0
  27. package/dist/src/platforms/channeltalkbot/commands/whoami.js +31 -0
  28. package/dist/src/platforms/channeltalkbot/commands/whoami.js.map +1 -0
  29. package/dist/src/platforms/discord/cli.d.ts.map +1 -1
  30. package/dist/src/platforms/discord/cli.js +2 -1
  31. package/dist/src/platforms/discord/cli.js.map +1 -1
  32. package/dist/src/platforms/discord/commands/index.d.ts +1 -0
  33. package/dist/src/platforms/discord/commands/index.d.ts.map +1 -1
  34. package/dist/src/platforms/discord/commands/index.js +1 -0
  35. package/dist/src/platforms/discord/commands/index.js.map +1 -1
  36. package/dist/src/platforms/discord/commands/whoami.d.ts +6 -0
  37. package/dist/src/platforms/discord/commands/whoami.d.ts.map +1 -0
  38. package/dist/src/platforms/discord/commands/whoami.js +33 -0
  39. package/dist/src/platforms/discord/commands/whoami.js.map +1 -0
  40. package/dist/src/platforms/discordbot/cli.d.ts.map +1 -1
  41. package/dist/src/platforms/discordbot/cli.js +2 -1
  42. package/dist/src/platforms/discordbot/cli.js.map +1 -1
  43. package/dist/src/platforms/discordbot/commands/index.d.ts +1 -0
  44. package/dist/src/platforms/discordbot/commands/index.d.ts.map +1 -1
  45. package/dist/src/platforms/discordbot/commands/index.js +1 -0
  46. package/dist/src/platforms/discordbot/commands/index.js.map +1 -1
  47. package/dist/src/platforms/discordbot/commands/whoami.d.ts +14 -0
  48. package/dist/src/platforms/discordbot/commands/whoami.d.ts.map +1 -0
  49. package/dist/src/platforms/discordbot/commands/whoami.js +32 -0
  50. package/dist/src/platforms/discordbot/commands/whoami.js.map +1 -0
  51. package/dist/src/platforms/instagram/cli.d.ts.map +1 -1
  52. package/dist/src/platforms/instagram/cli.js +2 -1
  53. package/dist/src/platforms/instagram/cli.js.map +1 -1
  54. package/dist/src/platforms/instagram/client.d.ts +6 -0
  55. package/dist/src/platforms/instagram/client.d.ts.map +1 -1
  56. package/dist/src/platforms/instagram/client.js +12 -0
  57. package/dist/src/platforms/instagram/client.js.map +1 -1
  58. package/dist/src/platforms/instagram/commands/index.d.ts +1 -0
  59. package/dist/src/platforms/instagram/commands/index.d.ts.map +1 -1
  60. package/dist/src/platforms/instagram/commands/index.js +1 -0
  61. package/dist/src/platforms/instagram/commands/index.js.map +1 -1
  62. package/dist/src/platforms/instagram/commands/whoami.d.ts +7 -0
  63. package/dist/src/platforms/instagram/commands/whoami.d.ts.map +1 -0
  64. package/dist/src/platforms/instagram/commands/whoami.js +19 -0
  65. package/dist/src/platforms/instagram/commands/whoami.js.map +1 -0
  66. package/dist/src/platforms/kakaotalk/cli.js +2 -2
  67. package/dist/src/platforms/kakaotalk/cli.js.map +1 -1
  68. package/dist/src/platforms/kakaotalk/client.d.ts +4 -1
  69. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  70. package/dist/src/platforms/kakaotalk/client.js +193 -27
  71. package/dist/src/platforms/kakaotalk/client.js.map +1 -1
  72. package/dist/src/platforms/kakaotalk/commands/auth.d.ts.map +1 -1
  73. package/dist/src/platforms/kakaotalk/commands/auth.js +24 -55
  74. package/dist/src/platforms/kakaotalk/commands/auth.js.map +1 -1
  75. package/dist/src/platforms/kakaotalk/commands/index.d.ts +1 -1
  76. package/dist/src/platforms/kakaotalk/commands/index.d.ts.map +1 -1
  77. package/dist/src/platforms/kakaotalk/commands/index.js +1 -1
  78. package/dist/src/platforms/kakaotalk/commands/index.js.map +1 -1
  79. package/dist/src/platforms/kakaotalk/commands/whoami.d.ts +3 -0
  80. package/dist/src/platforms/kakaotalk/commands/whoami.d.ts.map +1 -0
  81. package/dist/src/platforms/kakaotalk/commands/{profile.js → whoami.js} +5 -5
  82. package/dist/src/platforms/kakaotalk/commands/whoami.js.map +1 -0
  83. package/dist/src/platforms/kakaotalk/credential-manager.d.ts.map +1 -1
  84. package/dist/src/platforms/kakaotalk/credential-manager.js +1 -0
  85. package/dist/src/platforms/kakaotalk/credential-manager.js.map +1 -1
  86. package/dist/src/platforms/kakaotalk/index.d.ts +1 -1
  87. package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
  88. package/dist/src/platforms/kakaotalk/index.js.map +1 -1
  89. package/dist/src/platforms/kakaotalk/listener.js +2 -2
  90. package/dist/src/platforms/kakaotalk/listener.js.map +1 -1
  91. package/dist/src/platforms/kakaotalk/protocol/config.d.ts +8 -2
  92. package/dist/src/platforms/kakaotalk/protocol/config.d.ts.map +1 -1
  93. package/dist/src/platforms/kakaotalk/protocol/config.js +15 -2
  94. package/dist/src/platforms/kakaotalk/protocol/config.js.map +1 -1
  95. package/dist/src/platforms/kakaotalk/protocol/session.d.ts +6 -2
  96. package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
  97. package/dist/src/platforms/kakaotalk/protocol/session.js +37 -15
  98. package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
  99. package/dist/src/platforms/kakaotalk/protocol/types.d.ts +17 -0
  100. package/dist/src/platforms/kakaotalk/protocol/types.d.ts.map +1 -1
  101. package/dist/src/platforms/kakaotalk/protocol/types.js.map +1 -1
  102. package/dist/src/platforms/kakaotalk/types.d.ts +22 -0
  103. package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
  104. package/dist/src/platforms/kakaotalk/types.js +7 -0
  105. package/dist/src/platforms/kakaotalk/types.js.map +1 -1
  106. package/dist/src/platforms/line/cli.js +2 -2
  107. package/dist/src/platforms/line/cli.js.map +1 -1
  108. package/dist/src/platforms/line/commands/auth.d.ts.map +1 -1
  109. package/dist/src/platforms/line/commands/auth.js +9 -59
  110. package/dist/src/platforms/line/commands/auth.js.map +1 -1
  111. package/dist/src/platforms/line/commands/index.d.ts +1 -1
  112. package/dist/src/platforms/line/commands/index.d.ts.map +1 -1
  113. package/dist/src/platforms/line/commands/index.js +1 -1
  114. package/dist/src/platforms/line/commands/index.js.map +1 -1
  115. package/dist/src/platforms/line/commands/whoami.d.ts +3 -0
  116. package/dist/src/platforms/line/commands/whoami.d.ts.map +1 -0
  117. package/dist/src/platforms/line/commands/{profile.js → whoami.js} +5 -5
  118. package/dist/src/platforms/line/commands/whoami.js.map +1 -0
  119. package/dist/src/platforms/slack/cli.d.ts.map +1 -1
  120. package/dist/src/platforms/slack/cli.js +2 -1
  121. package/dist/src/platforms/slack/cli.js.map +1 -1
  122. package/dist/src/platforms/slack/commands/index.d.ts +1 -0
  123. package/dist/src/platforms/slack/commands/index.d.ts.map +1 -1
  124. package/dist/src/platforms/slack/commands/index.js +1 -0
  125. package/dist/src/platforms/slack/commands/index.js.map +1 -1
  126. package/dist/src/platforms/slack/commands/whoami.d.ts +6 -0
  127. package/dist/src/platforms/slack/commands/whoami.d.ts.map +1 -0
  128. package/dist/src/platforms/slack/commands/whoami.js +39 -0
  129. package/dist/src/platforms/slack/commands/whoami.js.map +1 -0
  130. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  131. package/dist/src/platforms/slackbot/cli.js +2 -1
  132. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  133. package/dist/src/platforms/slackbot/commands/index.d.ts +1 -0
  134. package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -1
  135. package/dist/src/platforms/slackbot/commands/index.js +1 -0
  136. package/dist/src/platforms/slackbot/commands/index.js.map +1 -1
  137. package/dist/src/platforms/slackbot/commands/whoami.d.ts +14 -0
  138. package/dist/src/platforms/slackbot/commands/whoami.d.ts.map +1 -0
  139. package/dist/src/platforms/slackbot/commands/whoami.js +32 -0
  140. package/dist/src/platforms/slackbot/commands/whoami.js.map +1 -0
  141. package/dist/src/platforms/teams/cli.d.ts.map +1 -1
  142. package/dist/src/platforms/teams/cli.js +2 -1
  143. package/dist/src/platforms/teams/cli.js.map +1 -1
  144. package/dist/src/platforms/teams/commands/index.d.ts +1 -0
  145. package/dist/src/platforms/teams/commands/index.d.ts.map +1 -1
  146. package/dist/src/platforms/teams/commands/index.js +1 -0
  147. package/dist/src/platforms/teams/commands/index.js.map +1 -1
  148. package/dist/src/platforms/teams/commands/whoami.d.ts +6 -0
  149. package/dist/src/platforms/teams/commands/whoami.d.ts.map +1 -0
  150. package/dist/src/platforms/teams/commands/whoami.js +30 -0
  151. package/dist/src/platforms/teams/commands/whoami.js.map +1 -0
  152. package/dist/src/platforms/telegram/cli.d.ts.map +1 -1
  153. package/dist/src/platforms/telegram/cli.js +2 -1
  154. package/dist/src/platforms/telegram/cli.js.map +1 -1
  155. package/dist/src/platforms/telegram/commands/index.d.ts +1 -0
  156. package/dist/src/platforms/telegram/commands/index.d.ts.map +1 -1
  157. package/dist/src/platforms/telegram/commands/index.js +1 -0
  158. package/dist/src/platforms/telegram/commands/index.js.map +1 -1
  159. package/dist/src/platforms/telegram/commands/whoami.d.ts +7 -0
  160. package/dist/src/platforms/telegram/commands/whoami.d.ts.map +1 -0
  161. package/dist/src/platforms/telegram/commands/whoami.js +27 -0
  162. package/dist/src/platforms/telegram/commands/whoami.js.map +1 -0
  163. package/dist/src/platforms/webex/cli.d.ts.map +1 -1
  164. package/dist/src/platforms/webex/cli.js +2 -1
  165. package/dist/src/platforms/webex/cli.js.map +1 -1
  166. package/dist/src/platforms/webex/commands/index.d.ts +1 -0
  167. package/dist/src/platforms/webex/commands/index.d.ts.map +1 -1
  168. package/dist/src/platforms/webex/commands/index.js +1 -0
  169. package/dist/src/platforms/webex/commands/index.js.map +1 -1
  170. package/dist/src/platforms/webex/commands/message.js +1 -1
  171. package/dist/src/platforms/webex/commands/message.js.map +1 -1
  172. package/dist/src/platforms/webex/commands/whoami.d.ts +6 -0
  173. package/dist/src/platforms/webex/commands/whoami.d.ts.map +1 -0
  174. package/dist/src/platforms/webex/commands/whoami.js +30 -0
  175. package/dist/src/platforms/webex/commands/whoami.js.map +1 -0
  176. package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -1
  177. package/dist/src/platforms/wechatbot/cli.js +2 -1
  178. package/dist/src/platforms/wechatbot/cli.js.map +1 -1
  179. package/dist/src/platforms/wechatbot/commands/index.d.ts +1 -0
  180. package/dist/src/platforms/wechatbot/commands/index.d.ts.map +1 -1
  181. package/dist/src/platforms/wechatbot/commands/index.js +1 -0
  182. package/dist/src/platforms/wechatbot/commands/index.js.map +1 -1
  183. package/dist/src/platforms/wechatbot/commands/whoami.d.ts +12 -0
  184. package/dist/src/platforms/wechatbot/commands/whoami.d.ts.map +1 -0
  185. package/dist/src/platforms/wechatbot/commands/whoami.js +33 -0
  186. package/dist/src/platforms/wechatbot/commands/whoami.js.map +1 -0
  187. package/dist/src/platforms/whatsapp/cli.d.ts.map +1 -1
  188. package/dist/src/platforms/whatsapp/cli.js +2 -1
  189. package/dist/src/platforms/whatsapp/cli.js.map +1 -1
  190. package/dist/src/platforms/whatsapp/client.d.ts +8 -0
  191. package/dist/src/platforms/whatsapp/client.d.ts.map +1 -1
  192. package/dist/src/platforms/whatsapp/client.js +116 -8
  193. package/dist/src/platforms/whatsapp/client.js.map +1 -1
  194. package/dist/src/platforms/whatsapp/commands/auth.d.ts.map +1 -1
  195. package/dist/src/platforms/whatsapp/commands/auth.js +115 -45
  196. package/dist/src/platforms/whatsapp/commands/auth.js.map +1 -1
  197. package/dist/src/platforms/whatsapp/commands/index.d.ts +1 -0
  198. package/dist/src/platforms/whatsapp/commands/index.d.ts.map +1 -1
  199. package/dist/src/platforms/whatsapp/commands/index.js +1 -0
  200. package/dist/src/platforms/whatsapp/commands/index.js.map +1 -1
  201. package/dist/src/platforms/whatsapp/commands/shared.js +2 -2
  202. package/dist/src/platforms/whatsapp/commands/shared.js.map +1 -1
  203. package/dist/src/platforms/whatsapp/commands/whoami.d.ts +7 -0
  204. package/dist/src/platforms/whatsapp/commands/whoami.d.ts.map +1 -0
  205. package/dist/src/platforms/whatsapp/commands/whoami.js +19 -0
  206. package/dist/src/platforms/whatsapp/commands/whoami.js.map +1 -0
  207. package/dist/src/platforms/whatsapp/ensure-auth.js +2 -2
  208. package/dist/src/platforms/whatsapp/ensure-auth.js.map +1 -1
  209. package/dist/src/platforms/whatsappbot/cli.d.ts.map +1 -1
  210. package/dist/src/platforms/whatsappbot/cli.js +2 -1
  211. package/dist/src/platforms/whatsappbot/cli.js.map +1 -1
  212. package/dist/src/platforms/whatsappbot/commands/index.d.ts +1 -0
  213. package/dist/src/platforms/whatsappbot/commands/index.d.ts.map +1 -1
  214. package/dist/src/platforms/whatsappbot/commands/index.js +1 -0
  215. package/dist/src/platforms/whatsappbot/commands/index.js.map +1 -1
  216. package/dist/src/platforms/whatsappbot/commands/whoami.d.ts +17 -0
  217. package/dist/src/platforms/whatsappbot/commands/whoami.d.ts.map +1 -0
  218. package/dist/src/platforms/whatsappbot/commands/whoami.js +39 -0
  219. package/dist/src/platforms/whatsappbot/commands/whoami.js.map +1 -0
  220. package/dist/src/shared/utils/qr.d.ts +15 -0
  221. package/dist/src/shared/utils/qr.d.ts.map +1 -0
  222. package/dist/src/shared/utils/qr.js +74 -0
  223. package/dist/src/shared/utils/qr.js.map +1 -0
  224. package/dist/src/tui/adapters/kakaotalk-adapter.d.ts.map +1 -1
  225. package/dist/src/tui/adapters/kakaotalk-adapter.js +5 -2
  226. package/dist/src/tui/adapters/kakaotalk-adapter.js.map +1 -1
  227. package/dist/src/tui/adapters/whatsapp-adapter.d.ts.map +1 -1
  228. package/dist/src/tui/adapters/whatsapp-adapter.js +20 -15
  229. package/dist/src/tui/adapters/whatsapp-adapter.js.map +1 -1
  230. package/docs/content/docs/cli/channeltalk.mdx +11 -0
  231. package/docs/content/docs/cli/channeltalkbot.mdx +9 -0
  232. package/docs/content/docs/cli/discord.mdx +10 -0
  233. package/docs/content/docs/cli/discordbot.mdx +9 -0
  234. package/docs/content/docs/cli/instagram.mdx +11 -0
  235. package/docs/content/docs/cli/kakaotalk.mdx +27 -39
  236. package/docs/content/docs/cli/line.mdx +4 -4
  237. package/docs/content/docs/cli/slack.mdx +10 -0
  238. package/docs/content/docs/cli/slackbot.mdx +9 -0
  239. package/docs/content/docs/cli/teams.mdx +10 -0
  240. package/docs/content/docs/cli/telegram.mdx +11 -0
  241. package/docs/content/docs/cli/webex.mdx +10 -0
  242. package/docs/content/docs/cli/wechatbot.mdx +9 -0
  243. package/docs/content/docs/cli/whatsapp.mdx +36 -7
  244. package/docs/content/docs/cli/whatsappbot.mdx +9 -0
  245. package/e2e/config.ts +1 -1
  246. package/package.json +3 -1
  247. package/skills/agent-channeltalk/SKILL.md +12 -1
  248. package/skills/agent-channeltalkbot/SKILL.md +10 -1
  249. package/skills/agent-discord/SKILL.md +11 -1
  250. package/skills/agent-discordbot/SKILL.md +10 -1
  251. package/skills/agent-instagram/SKILL.md +12 -1
  252. package/skills/agent-kakaotalk/SKILL.md +24 -70
  253. package/skills/agent-kakaotalk/references/authentication.md +4 -69
  254. package/skills/agent-kakaotalk/references/common-patterns.md +14 -1
  255. package/skills/agent-line/SKILL.md +5 -5
  256. package/skills/agent-slack/SKILL.md +11 -1
  257. package/skills/agent-slackbot/SKILL.md +10 -1
  258. package/skills/agent-teams/SKILL.md +11 -1
  259. package/skills/agent-telegram/SKILL.md +6 -1
  260. package/skills/agent-webex/SKILL.md +11 -1
  261. package/skills/agent-wechatbot/SKILL.md +10 -1
  262. package/skills/agent-whatsapp/SKILL.md +52 -15
  263. package/skills/agent-whatsapp/references/authentication.md +36 -6
  264. package/skills/agent-whatsappbot/SKILL.md +10 -1
  265. package/src/platforms/channeltalk/cli.ts +2 -0
  266. package/src/platforms/channeltalk/commands/index.ts +1 -0
  267. package/src/platforms/channeltalk/commands/whoami.test.ts +64 -0
  268. package/src/platforms/channeltalk/commands/whoami.ts +62 -0
  269. package/src/platforms/channeltalkbot/cli.ts +2 -0
  270. package/src/platforms/channeltalkbot/commands/index.ts +1 -0
  271. package/src/platforms/channeltalkbot/commands/whoami.test.ts +104 -0
  272. package/src/platforms/channeltalkbot/commands/whoami.ts +42 -0
  273. package/src/platforms/discord/cli.ts +2 -0
  274. package/src/platforms/discord/commands/index.ts +1 -0
  275. package/src/platforms/discord/commands/whoami.test.ts +91 -0
  276. package/src/platforms/discord/commands/whoami.ts +36 -0
  277. package/src/platforms/discordbot/cli.ts +2 -0
  278. package/src/platforms/discordbot/commands/index.ts +1 -0
  279. package/src/platforms/discordbot/commands/whoami.test.ts +96 -0
  280. package/src/platforms/discordbot/commands/whoami.ts +44 -0
  281. package/src/platforms/instagram/cli.ts +2 -1
  282. package/src/platforms/instagram/client.ts +13 -0
  283. package/src/platforms/instagram/commands/chat.test.ts +1 -5
  284. package/src/platforms/instagram/commands/index.ts +1 -0
  285. package/src/platforms/instagram/commands/message.test.ts +1 -5
  286. package/src/platforms/instagram/commands/whoami.test.ts +60 -0
  287. package/src/platforms/instagram/commands/whoami.ts +21 -0
  288. package/src/platforms/kakaotalk/cli.ts +2 -2
  289. package/src/platforms/kakaotalk/client.test.ts +25 -14
  290. package/src/platforms/kakaotalk/client.ts +228 -33
  291. package/src/platforms/kakaotalk/commands/auth.ts +22 -73
  292. package/src/platforms/kakaotalk/commands/index.ts +1 -1
  293. package/src/platforms/kakaotalk/commands/{profile.test.ts → whoami.test.ts} +37 -5
  294. package/src/platforms/kakaotalk/commands/{profile.ts → whoami.ts} +4 -4
  295. package/src/platforms/kakaotalk/credential-manager.ts +1 -0
  296. package/src/platforms/kakaotalk/index.ts +1 -0
  297. package/src/platforms/kakaotalk/listener.test.ts +2 -2
  298. package/src/platforms/kakaotalk/listener.ts +2 -2
  299. package/src/platforms/kakaotalk/protocol/config.ts +26 -2
  300. package/src/platforms/kakaotalk/protocol/session.ts +42 -16
  301. package/src/platforms/kakaotalk/protocol/types.ts +9 -0
  302. package/src/platforms/kakaotalk/types.ts +16 -0
  303. package/src/platforms/line/cli.ts +2 -2
  304. package/src/platforms/line/commands/auth.ts +37 -70
  305. package/src/platforms/line/commands/index.ts +1 -1
  306. package/src/platforms/line/commands/{profile.test.ts → whoami.test.ts} +11 -11
  307. package/src/platforms/line/commands/{profile.ts → whoami.ts} +4 -4
  308. package/src/platforms/slack/cli.ts +2 -0
  309. package/src/platforms/slack/commands/index.ts +1 -0
  310. package/src/platforms/slack/commands/whoami.test.ts +126 -0
  311. package/src/platforms/slack/commands/whoami.ts +40 -0
  312. package/src/platforms/slackbot/cli.ts +2 -1
  313. package/src/platforms/slackbot/commands/index.ts +1 -0
  314. package/src/platforms/slackbot/commands/whoami.test.ts +102 -0
  315. package/src/platforms/slackbot/commands/whoami.ts +44 -0
  316. package/src/platforms/teams/cli.ts +2 -0
  317. package/src/platforms/teams/commands/index.ts +1 -0
  318. package/src/platforms/teams/commands/whoami.test.ts +83 -0
  319. package/src/platforms/teams/commands/whoami.ts +33 -0
  320. package/src/platforms/telegram/cli.ts +2 -1
  321. package/src/platforms/telegram/commands/index.ts +1 -0
  322. package/src/platforms/telegram/commands/whoami.test.ts +75 -0
  323. package/src/platforms/telegram/commands/whoami.ts +29 -0
  324. package/src/platforms/webex/cli.ts +2 -1
  325. package/src/platforms/webex/commands/auth.test.ts +58 -46
  326. package/src/platforms/webex/commands/index.ts +1 -0
  327. package/src/platforms/webex/commands/member.test.ts +1 -5
  328. package/src/platforms/webex/commands/message.test.ts +1 -5
  329. package/src/platforms/webex/commands/message.ts +1 -1
  330. package/src/platforms/webex/commands/snapshot.test.ts +1 -5
  331. package/src/platforms/webex/commands/space.test.ts +1 -5
  332. package/src/platforms/webex/commands/whoami.test.ts +113 -0
  333. package/src/platforms/webex/commands/whoami.ts +31 -0
  334. package/src/platforms/webex/credential-manager.test.ts +0 -1
  335. package/src/platforms/wechatbot/cli.ts +2 -1
  336. package/src/platforms/wechatbot/commands/index.ts +1 -0
  337. package/src/platforms/wechatbot/commands/whoami.test.ts +109 -0
  338. package/src/platforms/wechatbot/commands/whoami.ts +43 -0
  339. package/src/platforms/whatsapp/cli.ts +2 -1
  340. package/src/platforms/whatsapp/client.ts +156 -24
  341. package/src/platforms/whatsapp/commands/auth.ts +176 -70
  342. package/src/platforms/whatsapp/commands/index.ts +1 -0
  343. package/src/platforms/whatsapp/commands/shared.ts +2 -2
  344. package/src/platforms/whatsapp/commands/whoami.test.ts +59 -0
  345. package/src/platforms/whatsapp/commands/whoami.ts +21 -0
  346. package/src/platforms/whatsapp/ensure-auth.ts +2 -2
  347. package/src/platforms/whatsappbot/cli.ts +2 -1
  348. package/src/platforms/whatsappbot/commands/index.ts +1 -0
  349. package/src/platforms/whatsappbot/commands/whoami.test.ts +100 -0
  350. package/src/platforms/whatsappbot/commands/whoami.ts +57 -0
  351. package/src/shared/utils/qr.ts +92 -0
  352. package/src/tui/adapters/kakaotalk-adapter.ts +5 -2
  353. package/src/tui/adapters/whatsapp-adapter.ts +19 -16
  354. package/dist/src/platforms/kakaotalk/commands/profile.d.ts +0 -3
  355. package/dist/src/platforms/kakaotalk/commands/profile.d.ts.map +0 -1
  356. package/dist/src/platforms/kakaotalk/commands/profile.js.map +0 -1
  357. package/dist/src/platforms/line/commands/profile.d.ts +0 -3
  358. package/dist/src/platforms/line/commands/profile.d.ts.map +0 -1
  359. package/dist/src/platforms/line/commands/profile.js.map +0 -1
@@ -0,0 +1,42 @@
1
+ import { Command } from 'commander'
2
+
3
+ import { formatOutput } from '@/shared/utils/output'
4
+
5
+ import type { WorkspaceOption } from './shared'
6
+ import { getClient } from './shared'
7
+
8
+ interface WhoamiResult {
9
+ id?: string
10
+ name?: string
11
+ homepage_url?: string
12
+ description?: string
13
+ error?: string
14
+ }
15
+
16
+ export async function whoamiAction(options: WorkspaceOption): Promise<WhoamiResult> {
17
+ try {
18
+ const client = await getClient(options)
19
+ const channel = await client.getChannel()
20
+ return {
21
+ id: channel.id,
22
+ name: channel.name,
23
+ homepage_url: channel.homepageUrl,
24
+ description: channel.description,
25
+ }
26
+ } catch (error) {
27
+ return { error: (error as Error).message }
28
+ }
29
+ }
30
+
31
+ function cliOutput(result: WhoamiResult, pretty?: boolean): void {
32
+ console.log(formatOutput(result, pretty))
33
+ if (result.error) process.exit(1)
34
+ }
35
+
36
+ export const whoamiCommand = new Command('whoami')
37
+ .description('Show current authenticated bot')
38
+ .option('--workspace <id>', 'Workspace ID to use')
39
+ .option('--pretty', 'Pretty print JSON output')
40
+ .action(async (opts: WorkspaceOption) => {
41
+ cliOutput(await whoamiAction(opts), opts.pretty)
42
+ })
@@ -20,6 +20,7 @@ import {
20
20
  snapshotCommand,
21
21
  threadCommand,
22
22
  userCommand,
23
+ whoamiCommand,
23
24
  } from './commands'
24
25
  import { ensureDiscordAuth } from './ensure-auth'
25
26
 
@@ -60,6 +61,7 @@ program.addCommand(reactionCommand)
60
61
  program.addCommand(snapshotCommand)
61
62
  program.addCommand(threadCommand)
62
63
  program.addCommand(userCommand)
64
+ program.addCommand(whoamiCommand)
63
65
 
64
66
  program.parse(process.argv)
65
67
 
@@ -13,3 +13,4 @@ export { serverCommand } from './server'
13
13
  export { snapshotCommand } from './snapshot'
14
14
  export { threadCommand } from './thread'
15
15
  export { userCommand } from './user'
16
+ export { whoamiCommand } from './whoami'
@@ -0,0 +1,91 @@
1
+ import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
2
+
3
+ import { DiscordClient } from '@/platforms/discord/client'
4
+ import { DiscordCredentialManager } from '@/platforms/discord/credential-manager'
5
+ import { whoamiAction, whoamiCommand } from '@/platforms/discord/commands/whoami'
6
+
7
+ let credManagerSpy: ReturnType<typeof spyOn>
8
+ let clientTestAuthSpy: ReturnType<typeof spyOn>
9
+ let consoleLogSpy: ReturnType<typeof spyOn>
10
+ let processExitSpy: ReturnType<typeof spyOn>
11
+
12
+ const mockConfig = {
13
+ token: 'test-discord-token',
14
+ }
15
+
16
+ const mockUser = {
17
+ id: 'user123',
18
+ username: 'testuser',
19
+ global_name: 'Test User',
20
+ avatar: 'avatar_hash',
21
+ bot: false,
22
+ }
23
+
24
+ beforeEach(() => {
25
+ credManagerSpy = spyOn(DiscordCredentialManager.prototype, 'load').mockResolvedValue(mockConfig)
26
+ clientTestAuthSpy = spyOn(DiscordClient.prototype, 'testAuth').mockResolvedValue(mockUser)
27
+ consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
28
+ processExitSpy = spyOn(process, 'exit').mockImplementation((_code?: number) => undefined as never)
29
+ })
30
+
31
+ afterEach(() => {
32
+ credManagerSpy?.mockRestore()
33
+ clientTestAuthSpy?.mockRestore()
34
+ consoleLogSpy?.mockRestore()
35
+ processExitSpy?.mockRestore()
36
+ })
37
+
38
+ test('whoami command is defined with correct name and description', () => {
39
+ expect(whoamiCommand).toBeDefined()
40
+ expect(whoamiCommand.name()).toBe('whoami')
41
+ expect(whoamiCommand.description()).toBe('Show current authenticated user')
42
+ })
43
+
44
+ test('whoami command has --pretty option', () => {
45
+ const options = whoamiCommand.options
46
+ const hasPretty = options.some((opt: { long?: string }) => opt.long === '--pretty')
47
+ expect(hasPretty).toBe(true)
48
+ })
49
+
50
+ test('whoami outputs expected user fields', async () => {
51
+ await whoamiAction({})
52
+
53
+ expect(consoleLogSpy).toHaveBeenCalledWith(
54
+ JSON.stringify({
55
+ id: 'user123',
56
+ username: 'testuser',
57
+ global_name: 'Test User',
58
+ avatar: 'avatar_hash',
59
+ bot: false,
60
+ }),
61
+ )
62
+ })
63
+
64
+ test('whoami outputs pretty-printed JSON when pretty is true', async () => {
65
+ await whoamiAction({ pretty: true })
66
+
67
+ expect(consoleLogSpy).toHaveBeenCalledWith(
68
+ JSON.stringify(
69
+ {
70
+ id: 'user123',
71
+ username: 'testuser',
72
+ global_name: 'Test User',
73
+ avatar: 'avatar_hash',
74
+ bot: false,
75
+ },
76
+ null,
77
+ 2,
78
+ ),
79
+ )
80
+ })
81
+
82
+ test('whoami exits with error when not authenticated', async () => {
83
+ credManagerSpy.mockResolvedValue({ token: undefined })
84
+
85
+ await whoamiAction({})
86
+
87
+ expect(consoleLogSpy).toHaveBeenCalledWith(
88
+ JSON.stringify({ error: 'Not authenticated. Run "auth extract" first.' }),
89
+ )
90
+ expect(processExitSpy).toHaveBeenCalledWith(1)
91
+ })
@@ -0,0 +1,36 @@
1
+ import { Command } from 'commander'
2
+ import { handleError } from '@/shared/utils/error-handler'
3
+ import { formatOutput } from '@/shared/utils/output'
4
+ import { DiscordClient } from '../client'
5
+ import { DiscordCredentialManager } from '../credential-manager'
6
+
7
+ export async function whoamiAction(options: { pretty?: boolean }): Promise<void> {
8
+ try {
9
+ const credManager = new DiscordCredentialManager()
10
+ const config = await credManager.load()
11
+
12
+ if (!config.token) {
13
+ console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
14
+ return process.exit(1)
15
+ }
16
+
17
+ const client = await new DiscordClient().login({ token: config.token })
18
+ const user = await client.testAuth()
19
+
20
+ const output = {
21
+ id: user.id,
22
+ username: user.username,
23
+ global_name: user.global_name,
24
+ avatar: user.avatar,
25
+ bot: user.bot,
26
+ }
27
+ console.log(formatOutput(output, options.pretty))
28
+ } catch (error) {
29
+ handleError(error as Error)
30
+ }
31
+ }
32
+
33
+ export const whoamiCommand = new Command('whoami')
34
+ .description('Show current authenticated user')
35
+ .option('--pretty', 'Pretty print JSON output')
36
+ .action(whoamiAction)
@@ -13,6 +13,7 @@ import {
13
13
  snapshotCommand,
14
14
  threadCommand,
15
15
  userCommand,
16
+ whoamiCommand,
16
17
  } from './commands/index'
17
18
 
18
19
  const program = new Command()
@@ -25,6 +26,7 @@ program
25
26
  .option('--server <id>', 'Server ID to use')
26
27
 
27
28
  program.addCommand(authCommand)
29
+ program.addCommand(whoamiCommand)
28
30
  program.addCommand(serverCommand)
29
31
  program.addCommand(messageCommand)
30
32
  program.addCommand(channelCommand)
@@ -7,3 +7,4 @@ export { serverCommand } from './server'
7
7
  export { snapshotCommand } from './snapshot'
8
8
  export { threadCommand } from './thread'
9
9
  export { userCommand } from './user'
10
+ export { whoamiCommand } from './whoami'
@@ -0,0 +1,96 @@
1
+ import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test'
2
+ import { existsSync, rmSync } from 'node:fs'
3
+ import { mkdir } from 'node:fs/promises'
4
+ import { tmpdir } from 'node:os'
5
+ import { join } from 'node:path'
6
+
7
+ const mockTestAuth = mock(() =>
8
+ Promise.resolve({
9
+ id: 'bot-user-id',
10
+ username: 'testbot',
11
+ global_name: 'Test Bot',
12
+ avatar: 'avatar123',
13
+ bot: true,
14
+ }),
15
+ )
16
+
17
+ mock.module('../client', () => ({
18
+ DiscordBotClient: class MockDiscordBotClient {
19
+ async login(_credentials?: any) {
20
+ return this
21
+ }
22
+ testAuth = mockTestAuth
23
+ },
24
+ }))
25
+
26
+ import { DiscordBotCredentialManager } from '../credential-manager'
27
+ import { whoamiAction } from './whoami'
28
+
29
+ describe('whoami command', () => {
30
+ let tempDir: string
31
+ let originalEnv: NodeJS.ProcessEnv
32
+
33
+ beforeEach(async () => {
34
+ tempDir = join(tmpdir(), `discordbot-whoami-test-${Date.now()}`)
35
+ await mkdir(tempDir, { recursive: true })
36
+ originalEnv = { ...process.env }
37
+ delete process.env.E2E_DISCORDBOT_TOKEN
38
+ mockTestAuth.mockClear()
39
+ })
40
+
41
+ afterEach(() => {
42
+ if (existsSync(tempDir)) {
43
+ rmSync(tempDir, { recursive: true })
44
+ }
45
+ process.env = originalEnv
46
+ })
47
+
48
+ test('returns auth info for current bot', async () => {
49
+ const manager = new DiscordBotCredentialManager(tempDir)
50
+ await manager.setCredentials({
51
+ token: 'bot-token-123',
52
+ bot_id: 'bot1',
53
+ bot_name: 'Test Bot',
54
+ })
55
+
56
+ const result = await whoamiAction({ _credManager: manager })
57
+
58
+ expect(result.id).toBe('bot-user-id')
59
+ expect(result.username).toBe('testbot')
60
+ expect(result.global_name).toBe('Test Bot')
61
+ expect(result.avatar).toBe('avatar123')
62
+ expect(result.bot).toBe(true)
63
+ expect(result.error).toBeUndefined()
64
+ })
65
+
66
+ test('returns auth info for specific --bot', async () => {
67
+ const manager = new DiscordBotCredentialManager(tempDir)
68
+ await manager.setCredentials({
69
+ token: 'bot-token-123',
70
+ bot_id: 'deploy',
71
+ bot_name: 'Deploy Bot',
72
+ })
73
+
74
+ const result = await whoamiAction({ bot: 'deploy', _credManager: manager })
75
+
76
+ expect(result.id).toBe('bot-user-id')
77
+ expect(result.username).toBe('testbot')
78
+ expect(mockTestAuth).toHaveBeenCalledTimes(1)
79
+ })
80
+
81
+ test('returns error when client throws', async () => {
82
+ mockTestAuth.mockImplementationOnce(() => Promise.reject(new Error('API Error')))
83
+
84
+ const manager = new DiscordBotCredentialManager(tempDir)
85
+ await manager.setCredentials({
86
+ token: 'bot-token-123',
87
+ bot_id: 'bot1',
88
+ bot_name: 'Test Bot',
89
+ })
90
+
91
+ const result = await whoamiAction({ _credManager: manager })
92
+
93
+ expect(result.error).toBeDefined()
94
+ expect(result.error).toContain('API Error')
95
+ })
96
+ })
@@ -0,0 +1,44 @@
1
+ import { Command } from 'commander'
2
+
3
+ import { formatOutput } from '@/shared/utils/output'
4
+
5
+ import type { BotOption } from './shared'
6
+ import { getClient } from './shared'
7
+
8
+ interface WhoamiResult {
9
+ id?: string
10
+ username?: string
11
+ global_name?: string
12
+ avatar?: string
13
+ bot?: boolean
14
+ error?: string
15
+ }
16
+
17
+ export async function whoamiAction(options: BotOption): Promise<WhoamiResult> {
18
+ try {
19
+ const client = await getClient(options)
20
+ const info = await client.testAuth()
21
+ return {
22
+ id: info.id,
23
+ username: info.username,
24
+ global_name: info.global_name,
25
+ avatar: info.avatar,
26
+ bot: info.bot,
27
+ }
28
+ } catch (error) {
29
+ return { error: (error as Error).message }
30
+ }
31
+ }
32
+
33
+ function cliOutput(result: WhoamiResult, pretty?: boolean): void {
34
+ console.log(formatOutput(result, pretty))
35
+ if (result.error) process.exit(1)
36
+ }
37
+
38
+ export const whoamiCommand = new Command('whoami')
39
+ .description('Show current authenticated bot')
40
+ .option('--bot <id>', 'Bot ID to use')
41
+ .option('--pretty', 'Pretty print JSON output')
42
+ .action(async (opts: BotOption) => {
43
+ cliOutput(await whoamiAction(opts), opts.pretty)
44
+ })
@@ -4,7 +4,7 @@ import type { Command as CommandType } from 'commander'
4
4
  import { Command } from 'commander'
5
5
 
6
6
  import pkg from '../../../package.json' with { type: 'json' }
7
- import { authCommand, chatCommand, messageCommand } from './commands/index'
7
+ import { authCommand, chatCommand, messageCommand, whoamiCommand } from './commands/index'
8
8
  import { ensureInstagramAuth } from './ensure-auth'
9
9
 
10
10
  function isAuthCommand(command: CommandType): boolean {
@@ -31,6 +31,7 @@ program.hook('preAction', async (_thisCommand, actionCommand) => {
31
31
  program.addCommand(authCommand)
32
32
  program.addCommand(chatCommand)
33
33
  program.addCommand(messageCommand)
34
+ program.addCommand(whoamiCommand)
34
35
 
35
36
  program.parse(process.argv)
36
37
 
@@ -410,6 +410,19 @@ export class InstagramClient {
410
410
  return this.userId
411
411
  }
412
412
 
413
+ async getProfile(): Promise<{ user_id: string; username: string; full_name: string | null; profile_pic_url: string | null }> {
414
+ if (!this.userId) {
415
+ throw new InstagramError('Not authenticated. Call login() first.', 'not_authenticated')
416
+ }
417
+ const account = await this.credentialManager.getAccount()
418
+ return {
419
+ user_id: this.userId,
420
+ username: account?.username ?? '',
421
+ full_name: account?.full_name ?? null,
422
+ profile_pic_url: account?.profile_pic_url ?? null,
423
+ }
424
+ }
425
+
413
426
  private async preLoginFlow(): Promise<{ keyId: string; publicKey: string } | null> {
414
427
  const url = `${IG_BASE_URL}/qe/sync/`
415
428
  const headers = this.buildHeaders()
@@ -1,4 +1,4 @@
1
- import { afterAll, afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
2
2
 
3
3
  const originalConsoleLog = console.log
4
4
  import type { Command } from 'commander'
@@ -34,10 +34,6 @@ function resetCommandState(cmd: Command): void {
34
34
  }
35
35
  }
36
36
 
37
- afterAll(() => {
38
- mock.restore()
39
- })
40
-
41
37
  describe('chat commands', () => {
42
38
  let consoleLogSpy: ReturnType<typeof mock>
43
39
  let processExitSpy: ReturnType<typeof spyOn>
@@ -1,3 +1,4 @@
1
1
  export { authCommand } from './auth'
2
2
  export { chatCommand } from './chat'
3
3
  export { messageCommand } from './message'
4
+ export { whoamiCommand } from './whoami'
@@ -1,4 +1,4 @@
1
- import { afterAll, afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
2
2
 
3
3
  const originalConsoleLog = console.log
4
4
  import type { Command } from 'commander'
@@ -32,10 +32,6 @@ function resetCommandState(cmd: Command): void {
32
32
  }
33
33
  }
34
34
 
35
- afterAll(() => {
36
- mock.restore()
37
- })
38
-
39
35
  describe('message commands', () => {
40
36
  let consoleLogSpy: ReturnType<typeof mock>
41
37
  let processExitSpy: ReturnType<typeof spyOn>
@@ -0,0 +1,60 @@
1
+ import { afterEach, beforeEach, describe, expect, spyOn, test } from 'bun:test'
2
+
3
+ import { InstagramClient } from '../client'
4
+ import * as sharedModule from './shared'
5
+ import { whoamiAction } from './whoami'
6
+
7
+ let withInstagramClientSpy: ReturnType<typeof spyOn>
8
+ let getProfileSpy: ReturnType<typeof spyOn>
9
+ let consoleLogSpy: ReturnType<typeof spyOn>
10
+
11
+ describe('whoami command', () => {
12
+ beforeEach(() => {
13
+ getProfileSpy = spyOn(InstagramClient.prototype, 'getProfile').mockResolvedValue({
14
+ user_id: '987654321',
15
+ username: 'testuser',
16
+ full_name: 'Test User',
17
+ profile_pic_url: 'https://example.com/pic.jpg',
18
+ })
19
+ withInstagramClientSpy = spyOn(sharedModule, 'withInstagramClient').mockImplementation(
20
+ async (_opts, fn) => {
21
+ const fakeClient = Object.create(InstagramClient.prototype) as InstagramClient
22
+ return fn(fakeClient)
23
+ },
24
+ )
25
+ consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
26
+ })
27
+
28
+ afterEach(() => {
29
+ getProfileSpy?.mockRestore()
30
+ withInstagramClientSpy?.mockRestore()
31
+ consoleLogSpy?.mockRestore()
32
+ })
33
+
34
+ test('outputs profile information', async () => {
35
+ await whoamiAction({})
36
+
37
+ expect(consoleLogSpy).toHaveBeenCalledTimes(1)
38
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string)
39
+ expect(output.user_id).toBe('987654321')
40
+ expect(output.username).toBe('testuser')
41
+ expect(output.full_name).toBe('Test User')
42
+ expect(output.profile_pic_url).toBe('https://example.com/pic.jpg')
43
+ })
44
+
45
+ test('outputs profile with null optional fields', async () => {
46
+ getProfileSpy.mockResolvedValue({
47
+ user_id: '987654321',
48
+ username: 'testuser',
49
+ full_name: null,
50
+ profile_pic_url: null,
51
+ })
52
+
53
+ await whoamiAction({})
54
+
55
+ expect(consoleLogSpy).toHaveBeenCalledTimes(1)
56
+ const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string)
57
+ expect(output.full_name).toBeNull()
58
+ expect(output.profile_pic_url).toBeNull()
59
+ })
60
+ })
@@ -0,0 +1,21 @@
1
+ import { Command } from 'commander'
2
+
3
+ import { handleError } from '@/shared/utils/error-handler'
4
+ import { formatOutput } from '@/shared/utils/output'
5
+
6
+ import { withInstagramClient } from './shared'
7
+
8
+ export async function whoamiAction(options: { account?: string; pretty?: boolean }): Promise<void> {
9
+ try {
10
+ const profile = await withInstagramClient(options, (client) => client.getProfile())
11
+ console.log(formatOutput(profile, options.pretty))
12
+ } catch (error) {
13
+ handleError(error as Error)
14
+ }
15
+ }
16
+
17
+ export const whoamiCommand = new Command('whoami')
18
+ .description('Show current authenticated user')
19
+ .option('--account <id>', 'Use a specific Instagram account')
20
+ .option('--pretty', 'Pretty print JSON output')
21
+ .action(whoamiAction)
@@ -4,7 +4,7 @@ import type { Command as CommandType } from 'commander'
4
4
  import { Command } from 'commander'
5
5
 
6
6
  import pkg from '../../../package.json' with { type: 'json' }
7
- import { authCommand, chatCommand, messageCommand, profileCommand } from './commands/index'
7
+ import { authCommand, chatCommand, messageCommand, whoamiCommand } from './commands/index'
8
8
  import { ensureKakaoAuth } from './ensure-auth'
9
9
 
10
10
  function isAuthCommand(command: CommandType): boolean {
@@ -31,7 +31,7 @@ program.hook('preAction', async (_thisCommand, actionCommand) => {
31
31
  program.addCommand(authCommand)
32
32
  program.addCommand(chatCommand)
33
33
  program.addCommand(messageCommand)
34
- program.addCommand(profileCommand)
34
+ program.addCommand(whoamiCommand)
35
35
 
36
36
  program.parse(process.argv)
37
37
 
@@ -5,6 +5,8 @@ import { KakaoTalkClient, KakaoTalkError } from './client'
5
5
  // Mock LocoSession at module level
6
6
  const mockLogin = mock(() => Promise.resolve({}))
7
7
  const mockGetChatList = mock(() => Promise.resolve({}))
8
+ const mockGetChatLogs = mock(() => Promise.resolve({}))
9
+ const mockGetChatInfo = mock(() => Promise.resolve({}))
8
10
  const mockSyncMessages = mock(() => Promise.resolve({}))
9
11
  const mockSendMessage = mock(() => Promise.resolve({}))
10
12
  const mockClose = mock(() => {})
@@ -14,6 +16,8 @@ mock.module('./protocol/session', () => ({
14
16
  LocoSession: class MockLocoSession {
15
17
  login = mockLogin
16
18
  getChatList = mockGetChatList
19
+ getChatLogs = mockGetChatLogs
20
+ getChatInfo = mockGetChatInfo
17
21
  syncMessages = mockSyncMessages
18
22
  sendMessage = mockSendMessage
19
23
  close = mockClose
@@ -28,6 +32,8 @@ function makeLong(n: number): { low: number; high: number } {
28
32
  function resetAllMocks() {
29
33
  mockLogin.mockReset()
30
34
  mockGetChatList.mockReset()
35
+ mockGetChatLogs.mockReset()
36
+ mockGetChatInfo.mockReset()
31
37
  mockSyncMessages.mockReset()
32
38
  mockSendMessage.mockReset()
33
39
  mockClose.mockReset()
@@ -67,6 +73,8 @@ describe('KakaoTalkClient', () => {
67
73
  beforeEach(() => {
68
74
  resetAllMocks()
69
75
  mockLogin.mockResolvedValue(DEFAULT_LOGIN_RESULT)
76
+ mockGetChatLogs.mockResolvedValue({ body: { status: 0, chatLogs: [], eof: true } })
77
+ mockGetChatInfo.mockResolvedValue({ body: { l: makeLong(99999) } })
70
78
  })
71
79
 
72
80
  afterEach(() => {
@@ -316,13 +324,14 @@ describe('KakaoTalkClient', () => {
316
324
 
317
325
  describe('getMessages', () => {
318
326
  test('returns formatted messages', async () => {
319
- mockSyncMessages.mockResolvedValueOnce({
327
+ mockGetChatLogs.mockResolvedValueOnce({
320
328
  body: {
329
+ status: 0,
321
330
  chatLogs: [
322
- { logId: makeLong(10), type: 1, authorId: 42, message: 'hello', sendAt: 1700000001 },
323
- { logId: makeLong(11), type: 1, authorId: 43, message: 'world', sendAt: 1700000002 },
331
+ { logId: makeLong(10), chatId: 100, type: 1, authorId: 42, message: 'hello', sendAt: 1700000001 },
332
+ { logId: makeLong(11), chatId: 100, type: 1, authorId: 43, message: 'world', sendAt: 1700000002 },
324
333
  ],
325
- isOK: true,
334
+ eof: true,
326
335
  },
327
336
  })
328
337
 
@@ -351,14 +360,15 @@ describe('KakaoTalkClient', () => {
351
360
  test('respects count option', async () => {
352
361
  const logs = Array.from({ length: 50 }, (_, i) => ({
353
362
  logId: makeLong(i + 1),
363
+ chatId: 100,
354
364
  type: 1,
355
365
  authorId: 1,
356
366
  message: `msg-${i}`,
357
367
  sendAt: 1700000000 + i,
358
368
  }))
359
369
 
360
- mockSyncMessages.mockResolvedValueOnce({
361
- body: { chatLogs: logs, isOK: true },
370
+ mockGetChatLogs.mockResolvedValueOnce({
371
+ body: { status: 0, chatLogs: logs, eof: true },
362
372
  })
363
373
 
364
374
  const client = await new KakaoTalkClient().login({ oauthToken: 'token', userId: 'user1', deviceUuid: 'device1' })
@@ -373,13 +383,14 @@ describe('KakaoTalkClient', () => {
373
383
  })
374
384
 
375
385
  test('sorts messages by sent_at ascending', async () => {
376
- mockSyncMessages.mockResolvedValueOnce({
386
+ mockGetChatLogs.mockResolvedValueOnce({
377
387
  body: {
388
+ status: 0,
378
389
  chatLogs: [
379
- { logId: makeLong(2), type: 1, authorId: 1, message: 'second', sendAt: 200 },
380
- { logId: makeLong(1), type: 1, authorId: 1, message: 'first', sendAt: 100 },
390
+ { logId: makeLong(2), chatId: 100, type: 1, authorId: 1, message: 'second', sendAt: 200 },
391
+ { logId: makeLong(1), chatId: 100, type: 1, authorId: 1, message: 'first', sendAt: 100 },
381
392
  ],
382
- isOK: true,
393
+ eof: true,
383
394
  },
384
395
  })
385
396
 
@@ -556,8 +567,8 @@ describe('KakaoTalkClient', () => {
556
567
  })
557
568
 
558
569
  test('reuses session across multiple calls', async () => {
559
- mockSyncMessages.mockResolvedValue({
560
- body: { chatLogs: [], isOK: true },
570
+ mockGetChatLogs.mockResolvedValue({
571
+ body: { status: 0, chatLogs: [], eof: true },
561
572
  })
562
573
 
563
574
  const client = await new KakaoTalkClient().login({ oauthToken: 'token', userId: 'user1', deviceUuid: 'device1' })
@@ -574,8 +585,8 @@ describe('KakaoTalkClient', () => {
574
585
  mockLogin.mockImplementation(
575
586
  () => new Promise((resolve) => setTimeout(() => resolve(DEFAULT_LOGIN_RESULT), 50)),
576
587
  )
577
- mockSyncMessages.mockResolvedValue({
578
- body: { chatLogs: [], isOK: true },
588
+ mockGetChatLogs.mockResolvedValue({
589
+ body: { status: 0, chatLogs: [], eof: true },
579
590
  })
580
591
 
581
592
  const client = await new KakaoTalkClient().login({ oauthToken: 'token', userId: 'user1', deviceUuid: 'device1' })