agent-messenger 2.6.3 → 2.8.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 (515) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.github/workflows/ci.yml +6 -0
  3. package/.oxfmtrc.json +13 -1
  4. package/.oxlintrc.json +10 -1
  5. package/README.md +1 -1
  6. package/dist/package.json +59 -58
  7. package/dist/src/platforms/channeltalk/client.d.ts.map +1 -1
  8. package/dist/src/platforms/channeltalk/client.js +2 -2
  9. package/dist/src/platforms/channeltalk/client.js.map +1 -1
  10. package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
  11. package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
  12. package/dist/src/platforms/channeltalk/commands/message.d.ts.map +1 -1
  13. package/dist/src/platforms/channeltalk/commands/message.js.map +1 -1
  14. package/dist/src/platforms/channeltalk/commands/snapshot.d.ts.map +1 -1
  15. package/dist/src/platforms/channeltalk/commands/snapshot.js.map +1 -1
  16. package/dist/src/platforms/channeltalk/ensure-auth.d.ts.map +1 -1
  17. package/dist/src/platforms/channeltalk/ensure-auth.js.map +1 -1
  18. package/dist/src/platforms/channeltalk/token-extractor.d.ts +9 -23
  19. package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
  20. package/dist/src/platforms/channeltalk/token-extractor.js +109 -341
  21. package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
  22. package/dist/src/platforms/channeltalkbot/client.d.ts +1 -1
  23. package/dist/src/platforms/channeltalkbot/client.d.ts.map +1 -1
  24. package/dist/src/platforms/channeltalkbot/client.js +4 -4
  25. package/dist/src/platforms/channeltalkbot/client.js.map +1 -1
  26. package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
  27. package/dist/src/platforms/channeltalkbot/commands/auth.js +4 -1
  28. package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
  29. package/dist/src/platforms/channeltalkbot/commands/shared.d.ts.map +1 -1
  30. package/dist/src/platforms/channeltalkbot/commands/shared.js.map +1 -1
  31. package/dist/src/platforms/discord/commands/auth.js.map +1 -1
  32. package/dist/src/platforms/discord/commands/whoami.d.ts.map +1 -1
  33. package/dist/src/platforms/discord/commands/whoami.js.map +1 -1
  34. package/dist/src/platforms/discord/token-extractor.d.ts +2 -10
  35. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  36. package/dist/src/platforms/discord/token-extractor.js +38 -172
  37. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  38. package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
  39. package/dist/src/platforms/discordbot/client.js.map +1 -1
  40. package/dist/src/platforms/instagram/cli.d.ts.map +1 -1
  41. package/dist/src/platforms/instagram/cli.js +1 -4
  42. package/dist/src/platforms/instagram/cli.js.map +1 -1
  43. package/dist/src/platforms/instagram/client.d.ts.map +1 -1
  44. package/dist/src/platforms/instagram/client.js +8 -7
  45. package/dist/src/platforms/instagram/client.js.map +1 -1
  46. package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
  47. package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
  48. package/dist/src/platforms/instagram/commands/chat.d.ts.map +1 -1
  49. package/dist/src/platforms/instagram/commands/chat.js.map +1 -1
  50. package/dist/src/platforms/instagram/commands/message.d.ts.map +1 -1
  51. package/dist/src/platforms/instagram/commands/message.js.map +1 -1
  52. package/dist/src/platforms/instagram/commands/shared.d.ts.map +1 -1
  53. package/dist/src/platforms/instagram/commands/shared.js.map +1 -1
  54. package/dist/src/platforms/instagram/credential-manager.d.ts.map +1 -1
  55. package/dist/src/platforms/instagram/credential-manager.js +1 -1
  56. package/dist/src/platforms/instagram/credential-manager.js.map +1 -1
  57. package/dist/src/platforms/instagram/ensure-auth.d.ts.map +1 -1
  58. package/dist/src/platforms/instagram/ensure-auth.js.map +1 -1
  59. package/dist/src/platforms/instagram/token-extractor.d.ts +7 -19
  60. package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
  61. package/dist/src/platforms/instagram/token-extractor.js +44 -270
  62. package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
  63. package/dist/src/platforms/instagram/types.d.ts.map +1 -1
  64. package/dist/src/platforms/instagram/types.js +4 -2
  65. package/dist/src/platforms/instagram/types.js.map +1 -1
  66. package/dist/src/platforms/kakaotalk/auth/kakao-login.d.ts.map +1 -1
  67. package/dist/src/platforms/kakaotalk/auth/kakao-login.js +18 -4
  68. package/dist/src/platforms/kakaotalk/auth/kakao-login.js.map +1 -1
  69. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  70. package/dist/src/platforms/kakaotalk/client.js +3 -3
  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 +15 -9
  74. package/dist/src/platforms/kakaotalk/commands/auth.js.map +1 -1
  75. package/dist/src/platforms/kakaotalk/commands/shared.d.ts.map +1 -1
  76. package/dist/src/platforms/kakaotalk/commands/shared.js.map +1 -1
  77. package/dist/src/platforms/kakaotalk/protocol/connection.d.ts.map +1 -1
  78. package/dist/src/platforms/kakaotalk/protocol/connection.js.map +1 -1
  79. package/dist/src/platforms/kakaotalk/protocol/crypto.js +1 -1
  80. package/dist/src/platforms/kakaotalk/protocol/crypto.js.map +1 -1
  81. package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
  82. package/dist/src/platforms/kakaotalk/protocol/session.js +1 -3
  83. package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
  84. package/dist/src/platforms/kakaotalk/token-extractor.js +5 -2
  85. package/dist/src/platforms/kakaotalk/token-extractor.js.map +1 -1
  86. package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
  87. package/dist/src/platforms/kakaotalk/types.js +4 -2
  88. package/dist/src/platforms/kakaotalk/types.js.map +1 -1
  89. package/dist/src/platforms/line/cli.d.ts.map +1 -1
  90. package/dist/src/platforms/line/cli.js +1 -4
  91. package/dist/src/platforms/line/cli.js.map +1 -1
  92. package/dist/src/platforms/line/client.d.ts.map +1 -1
  93. package/dist/src/platforms/line/client.js +5 -13
  94. package/dist/src/platforms/line/client.js.map +1 -1
  95. package/dist/src/platforms/line/commands/chat.d.ts.map +1 -1
  96. package/dist/src/platforms/line/commands/chat.js.map +1 -1
  97. package/dist/src/platforms/line/commands/message.d.ts.map +1 -1
  98. package/dist/src/platforms/line/commands/message.js.map +1 -1
  99. package/dist/src/platforms/line/listener.js +1 -1
  100. package/dist/src/platforms/line/listener.js.map +1 -1
  101. package/dist/src/platforms/slack/cli.d.ts.map +1 -1
  102. package/dist/src/platforms/slack/cli.js.map +1 -1
  103. package/dist/src/platforms/slack/client-mappers.d.ts +14 -0
  104. package/dist/src/platforms/slack/client-mappers.d.ts.map +1 -0
  105. package/dist/src/platforms/slack/client-mappers.js +245 -0
  106. package/dist/src/platforms/slack/client-mappers.js.map +1 -0
  107. package/dist/src/platforms/slack/client.d.ts +0 -1
  108. package/dist/src/platforms/slack/client.d.ts.map +1 -1
  109. package/dist/src/platforms/slack/client.js +41 -455
  110. package/dist/src/platforms/slack/client.js.map +1 -1
  111. package/dist/src/platforms/slack/commands/channel.d.ts.map +1 -1
  112. package/dist/src/platforms/slack/commands/channel.js.map +1 -1
  113. package/dist/src/platforms/slack/commands/emoji.d.ts.map +1 -1
  114. package/dist/src/platforms/slack/commands/emoji.js +1 -3
  115. package/dist/src/platforms/slack/commands/emoji.js.map +1 -1
  116. package/dist/src/platforms/slack/commands/message.d.ts.map +1 -1
  117. package/dist/src/platforms/slack/commands/message.js.map +1 -1
  118. package/dist/src/platforms/slack/commands/reminder.d.ts.map +1 -1
  119. package/dist/src/platforms/slack/commands/reminder.js.map +1 -1
  120. package/dist/src/platforms/slack/commands/user.d.ts.map +1 -1
  121. package/dist/src/platforms/slack/commands/user.js.map +1 -1
  122. package/dist/src/platforms/slack/commands/usergroup.d.ts.map +1 -1
  123. package/dist/src/platforms/slack/commands/usergroup.js.map +1 -1
  124. package/dist/src/platforms/slack/commands/whoami.d.ts.map +1 -1
  125. package/dist/src/platforms/slack/commands/whoami.js.map +1 -1
  126. package/dist/src/platforms/slack/token-extractor.d.ts +2 -6
  127. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  128. package/dist/src/platforms/slack/token-extractor.js +35 -229
  129. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  130. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  131. package/dist/src/platforms/slackbot/cli.js +1 -1
  132. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  133. package/dist/src/platforms/teams/client.d.ts.map +1 -1
  134. package/dist/src/platforms/teams/client.js +1 -1
  135. package/dist/src/platforms/teams/client.js.map +1 -1
  136. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
  137. package/dist/src/platforms/teams/commands/auth.js +4 -1
  138. package/dist/src/platforms/teams/commands/auth.js.map +1 -1
  139. package/dist/src/platforms/teams/commands/whoami.d.ts.map +1 -1
  140. package/dist/src/platforms/teams/commands/whoami.js.map +1 -1
  141. package/dist/src/platforms/teams/token-extractor.d.ts +6 -18
  142. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
  143. package/dist/src/platforms/teams/token-extractor.js +71 -324
  144. package/dist/src/platforms/teams/token-extractor.js.map +1 -1
  145. package/dist/src/platforms/telegram/cli.d.ts.map +1 -1
  146. package/dist/src/platforms/telegram/cli.js +1 -4
  147. package/dist/src/platforms/telegram/cli.js.map +1 -1
  148. package/dist/src/platforms/telegram/client.d.ts.map +1 -1
  149. package/dist/src/platforms/telegram/client.js.map +1 -1
  150. package/dist/src/platforms/telegram/commands/auth.d.ts.map +1 -1
  151. package/dist/src/platforms/telegram/commands/auth.js +1 -1
  152. package/dist/src/platforms/telegram/commands/auth.js.map +1 -1
  153. package/dist/src/platforms/telegram/commands/chat.d.ts.map +1 -1
  154. package/dist/src/platforms/telegram/commands/chat.js.map +1 -1
  155. package/dist/src/platforms/telegram/commands/message.d.ts.map +1 -1
  156. package/dist/src/platforms/telegram/commands/message.js.map +1 -1
  157. package/dist/src/platforms/telegram/commands/whoami.js +1 -1
  158. package/dist/src/platforms/telegram/commands/whoami.js.map +1 -1
  159. package/dist/src/platforms/telegram/credential-manager.d.ts.map +1 -1
  160. package/dist/src/platforms/telegram/credential-manager.js +6 -2
  161. package/dist/src/platforms/telegram/credential-manager.js.map +1 -1
  162. package/dist/src/platforms/telegram/my-telegram-org.js.map +1 -1
  163. package/dist/src/platforms/webex/cli.d.ts.map +1 -1
  164. package/dist/src/platforms/webex/cli.js +1 -4
  165. package/dist/src/platforms/webex/cli.js.map +1 -1
  166. package/dist/src/platforms/webex/client.d.ts.map +1 -1
  167. package/dist/src/platforms/webex/client.js +19 -15
  168. package/dist/src/platforms/webex/client.js.map +1 -1
  169. package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
  170. package/dist/src/platforms/webex/commands/auth.js +1 -3
  171. package/dist/src/platforms/webex/commands/auth.js.map +1 -1
  172. package/dist/src/platforms/webex/commands/member.d.ts.map +1 -1
  173. package/dist/src/platforms/webex/commands/member.js +1 -3
  174. package/dist/src/platforms/webex/commands/member.js.map +1 -1
  175. package/dist/src/platforms/webex/commands/message.d.ts.map +1 -1
  176. package/dist/src/platforms/webex/commands/message.js.map +1 -1
  177. package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -1
  178. package/dist/src/platforms/webex/commands/snapshot.js.map +1 -1
  179. package/dist/src/platforms/webex/commands/space.d.ts.map +1 -1
  180. package/dist/src/platforms/webex/commands/space.js.map +1 -1
  181. package/dist/src/platforms/webex/commands/whoami.d.ts.map +1 -1
  182. package/dist/src/platforms/webex/commands/whoami.js.map +1 -1
  183. package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -1
  184. package/dist/src/platforms/webex/credential-manager.js.map +1 -1
  185. package/dist/src/platforms/webex/ensure-auth.d.ts.map +1 -1
  186. package/dist/src/platforms/webex/ensure-auth.js +1 -3
  187. package/dist/src/platforms/webex/ensure-auth.js.map +1 -1
  188. package/dist/src/platforms/webex/index.d.ts +1 -1
  189. package/dist/src/platforms/webex/index.d.ts.map +1 -1
  190. package/dist/src/platforms/webex/index.js.map +1 -1
  191. package/dist/src/platforms/webex/markdown-to-html.d.ts +3 -0
  192. package/dist/src/platforms/webex/markdown-to-html.d.ts.map +1 -0
  193. package/dist/src/platforms/webex/markdown-to-html.js +161 -0
  194. package/dist/src/platforms/webex/markdown-to-html.js.map +1 -0
  195. package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
  196. package/dist/src/platforms/webex/token-extractor.js +5 -14
  197. package/dist/src/platforms/webex/token-extractor.js.map +1 -1
  198. package/dist/src/platforms/wechatbot/client.d.ts.map +1 -1
  199. package/dist/src/platforms/wechatbot/client.js.map +1 -1
  200. package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
  201. package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
  202. package/dist/src/platforms/whatsapp/cli.d.ts.map +1 -1
  203. package/dist/src/platforms/whatsapp/cli.js +1 -4
  204. package/dist/src/platforms/whatsapp/cli.js.map +1 -1
  205. package/dist/src/platforms/whatsapp/commands/chat.d.ts.map +1 -1
  206. package/dist/src/platforms/whatsapp/commands/chat.js.map +1 -1
  207. package/dist/src/platforms/whatsapp/commands/message.d.ts.map +1 -1
  208. package/dist/src/platforms/whatsapp/commands/message.js.map +1 -1
  209. package/dist/src/platforms/whatsapp/commands/shared.d.ts.map +1 -1
  210. package/dist/src/platforms/whatsapp/commands/shared.js.map +1 -1
  211. package/dist/src/platforms/whatsapp/credential-manager.d.ts.map +1 -1
  212. package/dist/src/platforms/whatsapp/credential-manager.js +1 -1
  213. package/dist/src/platforms/whatsapp/credential-manager.js.map +1 -1
  214. package/dist/src/platforms/whatsapp/ensure-auth.d.ts.map +1 -1
  215. package/dist/src/platforms/whatsapp/ensure-auth.js.map +1 -1
  216. package/dist/src/platforms/whatsappbot/client.d.ts.map +1 -1
  217. package/dist/src/platforms/whatsappbot/client.js +2 -2
  218. package/dist/src/platforms/whatsappbot/client.js.map +1 -1
  219. package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
  220. package/dist/src/platforms/whatsappbot/commands/auth.js +4 -1
  221. package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
  222. package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
  223. package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
  224. package/dist/src/platforms/whatsappbot/commands/shared.d.ts.map +1 -1
  225. package/dist/src/platforms/whatsappbot/commands/shared.js.map +1 -1
  226. package/dist/src/shared/chromium/browsers.d.ts +7 -0
  227. package/dist/src/shared/chromium/browsers.d.ts.map +1 -0
  228. package/dist/src/shared/chromium/browsers.js +89 -0
  229. package/dist/src/shared/chromium/browsers.js.map +1 -0
  230. package/dist/src/shared/chromium/cookie-reader.d.ts +20 -0
  231. package/dist/src/shared/chromium/cookie-reader.d.ts.map +1 -0
  232. package/dist/src/shared/chromium/cookie-reader.js +99 -0
  233. package/dist/src/shared/chromium/cookie-reader.js.map +1 -0
  234. package/dist/src/shared/chromium/decryptor.d.ts +42 -0
  235. package/dist/src/shared/chromium/decryptor.d.ts.map +1 -0
  236. package/dist/src/shared/chromium/decryptor.js +205 -0
  237. package/dist/src/shared/chromium/decryptor.js.map +1 -0
  238. package/dist/src/shared/chromium/index.d.ts +6 -0
  239. package/dist/src/shared/chromium/index.d.ts.map +1 -0
  240. package/dist/src/shared/chromium/index.js +4 -0
  241. package/dist/src/shared/chromium/index.js.map +1 -0
  242. package/dist/src/shared/chromium/types.d.ts +11 -0
  243. package/dist/src/shared/chromium/types.d.ts.map +1 -0
  244. package/dist/src/shared/chromium/types.js +2 -0
  245. package/dist/src/shared/chromium/types.js.map +1 -0
  246. package/dist/src/shared/utils/derived-key-cache.d.ts +1 -1
  247. package/dist/src/shared/utils/derived-key-cache.d.ts.map +1 -1
  248. package/dist/src/shared/utils/linux-keyring.js +4 -1
  249. package/dist/src/shared/utils/linux-keyring.js.map +1 -1
  250. package/dist/src/tui/adapters/kakaotalk-adapter.d.ts.map +1 -1
  251. package/dist/src/tui/adapters/kakaotalk-adapter.js +6 -1
  252. package/dist/src/tui/adapters/kakaotalk-adapter.js.map +1 -1
  253. package/dist/src/tui/adapters/telegram-adapter.js +1 -1
  254. package/dist/src/tui/adapters/telegram-adapter.js.map +1 -1
  255. package/dist/src/tui/adapters/webex-adapter.js +1 -1
  256. package/dist/src/tui/adapters/webex-adapter.js.map +1 -1
  257. package/dist/src/tui/app.d.ts.map +1 -1
  258. package/dist/src/tui/app.js +112 -23
  259. package/dist/src/tui/app.js.map +1 -1
  260. package/dist/src/tui/utils.d.ts.map +1 -1
  261. package/dist/src/tui/utils.js +11 -13
  262. package/dist/src/tui/utils.js.map +1 -1
  263. package/dist/src/tui/views/channel-picker.d.ts.map +1 -1
  264. package/dist/src/tui/views/channel-picker.js.map +1 -1
  265. package/dist/src/tui/views/workspace-picker.d.ts.map +1 -1
  266. package/dist/src/tui/views/workspace-picker.js.map +1 -1
  267. package/docs/content/docs/cli/channeltalk.mdx +24 -22
  268. package/docs/content/docs/cli/channeltalkbot.mdx +7 -7
  269. package/docs/content/docs/cli/instagram.mdx +4 -4
  270. package/docs/content/docs/cli/kakaotalk.mdx +9 -8
  271. package/docs/content/docs/cli/line.mdx +14 -14
  272. package/docs/content/docs/cli/webex.mdx +19 -19
  273. package/docs/content/docs/cli/wechatbot.mdx +12 -11
  274. package/docs/content/docs/cli/whatsapp.mdx +5 -4
  275. package/docs/content/docs/cli/whatsappbot.mdx +11 -11
  276. package/docs/content/docs/index.mdx +7 -7
  277. package/docs/content/docs/meta.json +1 -9
  278. package/docs/content/docs/sdk/channeltalk.mdx +5 -6
  279. package/docs/content/docs/sdk/channeltalkbot.mdx +6 -12
  280. package/docs/content/docs/sdk/discord.mdx +36 -43
  281. package/docs/content/docs/sdk/instagram.mdx +18 -18
  282. package/docs/content/docs/sdk/kakaotalk.mdx +27 -18
  283. package/docs/content/docs/sdk/line.mdx +8 -13
  284. package/docs/content/docs/sdk/meta.json +14 -1
  285. package/docs/content/docs/sdk/slack.mdx +36 -42
  286. package/docs/content/docs/sdk/teams.mdx +2 -8
  287. package/docs/content/docs/sdk/webex.mdx +2 -12
  288. package/docs/content/docs/sdk/wechatbot.mdx +1 -5
  289. package/docs/content/docs/sdk/whatsapp.mdx +10 -19
  290. package/docs/content/docs/sdk/whatsappbot.mdx +2 -10
  291. package/docs/content/docs/tui.mdx +23 -23
  292. package/docs/src/app/page.tsx +353 -108
  293. package/e2e/channeltalkbot.e2e.test.ts +1 -5
  294. package/e2e/config.ts +6 -2
  295. package/package.json +59 -58
  296. package/scripts/prepublish.ts +1 -3
  297. package/skills/agent-channeltalk/SKILL.md +1 -1
  298. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  299. package/skills/agent-discord/SKILL.md +1 -1
  300. package/skills/agent-discordbot/SKILL.md +1 -1
  301. package/skills/agent-instagram/SKILL.md +1 -1
  302. package/skills/agent-kakaotalk/SKILL.md +1 -1
  303. package/skills/agent-line/SKILL.md +1 -1
  304. package/skills/agent-slack/SKILL.md +1 -1
  305. package/skills/agent-slackbot/SKILL.md +1 -1
  306. package/skills/agent-teams/SKILL.md +1 -1
  307. package/skills/agent-telegram/SKILL.md +1 -1
  308. package/skills/agent-webex/SKILL.md +1 -1
  309. package/skills/agent-wechatbot/SKILL.md +1 -1
  310. package/skills/agent-whatsapp/SKILL.md +1 -1
  311. package/skills/agent-whatsappbot/SKILL.md +1 -1
  312. package/src/platforms/channeltalk/client.test.ts +116 -29
  313. package/src/platforms/channeltalk/client.ts +26 -6
  314. package/src/platforms/channeltalk/commands/auth.test.ts +5 -5
  315. package/src/platforms/channeltalk/commands/auth.ts +19 -5
  316. package/src/platforms/channeltalk/commands/message.test.ts +2 -6
  317. package/src/platforms/channeltalk/commands/message.ts +5 -1
  318. package/src/platforms/channeltalk/commands/snapshot.test.ts +19 -4
  319. package/src/platforms/channeltalk/commands/snapshot.ts +5 -1
  320. package/src/platforms/channeltalk/ensure-auth.test.ts +20 -17
  321. package/src/platforms/channeltalk/ensure-auth.ts +6 -7
  322. package/src/platforms/channeltalk/index.ts +0 -1
  323. package/src/platforms/channeltalk/token-extractor.test.ts +33 -25
  324. package/src/platforms/channeltalk/token-extractor.ts +120 -372
  325. package/src/platforms/channeltalkbot/client.test.ts +1 -3
  326. package/src/platforms/channeltalkbot/client.ts +39 -13
  327. package/src/platforms/channeltalkbot/commands/auth.test.ts +3 -1
  328. package/src/platforms/channeltalkbot/commands/auth.ts +4 -1
  329. package/src/platforms/channeltalkbot/commands/bot.test.ts +13 -5
  330. package/src/platforms/channeltalkbot/commands/message.test.ts +12 -6
  331. package/src/platforms/channeltalkbot/commands/shared.ts +6 -2
  332. package/src/platforms/channeltalkbot/commands/snapshot.test.ts +17 -5
  333. package/src/platforms/channeltalkbot/credential-manager.test.ts +1 -1
  334. package/src/platforms/channeltalkbot/index.test.ts +0 -2
  335. package/src/platforms/channeltalkbot/index.ts +0 -1
  336. package/src/platforms/discord/commands/auth.test.ts +6 -4
  337. package/src/platforms/discord/commands/auth.ts +14 -14
  338. package/src/platforms/discord/commands/whoami.test.ts +2 -4
  339. package/src/platforms/discord/commands/whoami.ts +2 -0
  340. package/src/platforms/discord/ensure-auth.test.ts +5 -3
  341. package/src/platforms/discord/index.ts +0 -1
  342. package/src/platforms/discord/listener.test.ts +7 -1
  343. package/src/platforms/discord/token-extractor.test.ts +18 -12
  344. package/src/platforms/discord/token-extractor.ts +46 -190
  345. package/src/platforms/discordbot/client.ts +1 -4
  346. package/src/platforms/discordbot/commands/auth.test.ts +3 -1
  347. package/src/platforms/discordbot/commands/channel.test.ts +3 -1
  348. package/src/platforms/discordbot/commands/message.test.ts +3 -1
  349. package/src/platforms/discordbot/commands/server.test.ts +3 -1
  350. package/src/platforms/discordbot/commands/snapshot.test.ts +3 -1
  351. package/src/platforms/discordbot/commands/thread.test.ts +3 -1
  352. package/src/platforms/discordbot/commands/user.test.ts +3 -1
  353. package/src/platforms/instagram/cli.ts +1 -4
  354. package/src/platforms/instagram/client.test.ts +3 -8
  355. package/src/platforms/instagram/client.ts +39 -34
  356. package/src/platforms/instagram/commands/auth.test.ts +13 -12
  357. package/src/platforms/instagram/commands/auth.ts +136 -71
  358. package/src/platforms/instagram/commands/chat.test.ts +21 -24
  359. package/src/platforms/instagram/commands/chat.ts +2 -0
  360. package/src/platforms/instagram/commands/message.test.ts +29 -24
  361. package/src/platforms/instagram/commands/message.ts +3 -4
  362. package/src/platforms/instagram/commands/shared.ts +2 -5
  363. package/src/platforms/instagram/commands/whoami.test.ts +4 -6
  364. package/src/platforms/instagram/credential-manager.ts +2 -6
  365. package/src/platforms/instagram/ensure-auth.test.ts +1 -4
  366. package/src/platforms/instagram/ensure-auth.ts +6 -3
  367. package/src/platforms/instagram/listener.test.ts +7 -3
  368. package/src/platforms/instagram/token-extractor.test.ts +4 -16
  369. package/src/platforms/instagram/token-extractor.ts +55 -309
  370. package/src/platforms/instagram/types.test.ts +2 -6
  371. package/src/platforms/instagram/types.ts +4 -2
  372. package/src/platforms/kakaotalk/auth/kakao-login.ts +30 -8
  373. package/src/platforms/kakaotalk/client.test.ts +37 -25
  374. package/src/platforms/kakaotalk/client.ts +23 -12
  375. package/src/platforms/kakaotalk/commands/auth.test.ts +6 -18
  376. package/src/platforms/kakaotalk/commands/auth.ts +101 -47
  377. package/src/platforms/kakaotalk/commands/chat.test.ts +8 -11
  378. package/src/platforms/kakaotalk/commands/message.test.ts +15 -24
  379. package/src/platforms/kakaotalk/commands/shared.ts +1 -0
  380. package/src/platforms/kakaotalk/commands/whoami.test.ts +6 -10
  381. package/src/platforms/kakaotalk/credential-manager.test.ts +1 -4
  382. package/src/platforms/kakaotalk/index.test.ts +1 -0
  383. package/src/platforms/kakaotalk/index.ts +0 -2
  384. package/src/platforms/kakaotalk/listener.test.ts +7 -1
  385. package/src/platforms/kakaotalk/protocol/connection.ts +4 -1
  386. package/src/platforms/kakaotalk/protocol/crypto.ts +1 -1
  387. package/src/platforms/kakaotalk/protocol/session.ts +12 -6
  388. package/src/platforms/kakaotalk/token-extractor.ts +5 -5
  389. package/src/platforms/kakaotalk/types.ts +8 -7
  390. package/src/platforms/line/cli.ts +1 -4
  391. package/src/platforms/line/client.ts +12 -20
  392. package/src/platforms/line/commands/auth.test.ts +2 -1
  393. package/src/platforms/line/commands/chat.test.ts +2 -1
  394. package/src/platforms/line/commands/chat.ts +1 -4
  395. package/src/platforms/line/commands/friend.test.ts +2 -1
  396. package/src/platforms/line/commands/message.test.ts +2 -1
  397. package/src/platforms/line/commands/message.ts +2 -9
  398. package/src/platforms/line/commands/whoami.test.ts +2 -1
  399. package/src/platforms/line/credential-manager.test.ts +1 -2
  400. package/src/platforms/line/index.test.ts +1 -0
  401. package/src/platforms/line/listener.ts +1 -1
  402. package/src/platforms/line/types.test.ts +1 -0
  403. package/src/platforms/slack/cli.ts +3 -1
  404. package/src/platforms/slack/client-mappers.ts +297 -0
  405. package/src/platforms/slack/client.test.ts +532 -17
  406. package/src/platforms/slack/client.ts +69 -458
  407. package/src/platforms/slack/commands/channel.ts +1 -4
  408. package/src/platforms/slack/commands/emoji.test.ts +6 -4
  409. package/src/platforms/slack/commands/emoji.ts +20 -22
  410. package/src/platforms/slack/commands/message.ts +6 -1
  411. package/src/platforms/slack/commands/pin.test.ts +14 -12
  412. package/src/platforms/slack/commands/reminder.ts +7 -6
  413. package/src/platforms/slack/commands/user.ts +6 -1
  414. package/src/platforms/slack/commands/usergroup.test.ts +3 -3
  415. package/src/platforms/slack/commands/usergroup.ts +10 -7
  416. package/src/platforms/slack/commands/whoami.test.ts +1 -1
  417. package/src/platforms/slack/commands/whoami.ts +2 -0
  418. package/src/platforms/slack/index.ts +0 -2
  419. package/src/platforms/slack/listener.test.ts +1 -0
  420. package/src/platforms/slack/token-extractor.test.ts +7 -12
  421. package/src/platforms/slack/token-extractor.ts +47 -255
  422. package/src/platforms/slackbot/cli.ts +8 -1
  423. package/src/platforms/slackbot/commands/auth.test.ts +3 -1
  424. package/src/platforms/teams/client.ts +1 -1
  425. package/src/platforms/teams/commands/auth.test.ts +1 -1
  426. package/src/platforms/teams/commands/auth.ts +4 -1
  427. package/src/platforms/teams/commands/whoami.test.ts +2 -4
  428. package/src/platforms/teams/commands/whoami.ts +2 -0
  429. package/src/platforms/teams/index.ts +0 -1
  430. package/src/platforms/teams/token-extractor.ts +82 -350
  431. package/src/platforms/telegram/app-config.test.ts +1 -0
  432. package/src/platforms/telegram/chat-utils.test.ts +5 -1
  433. package/src/platforms/telegram/cli.ts +2 -4
  434. package/src/platforms/telegram/client.test.ts +16 -3
  435. package/src/platforms/telegram/client.ts +14 -4
  436. package/src/platforms/telegram/commands/auth.test.ts +1 -0
  437. package/src/platforms/telegram/commands/auth.ts +3 -4
  438. package/src/platforms/telegram/commands/chat.test.ts +2 -5
  439. package/src/platforms/telegram/commands/chat.ts +1 -0
  440. package/src/platforms/telegram/commands/message.test.ts +2 -5
  441. package/src/platforms/telegram/commands/message.ts +1 -0
  442. package/src/platforms/telegram/commands/shared.test.ts +1 -0
  443. package/src/platforms/telegram/commands/whoami.test.ts +5 -7
  444. package/src/platforms/telegram/commands/whoami.ts +1 -1
  445. package/src/platforms/telegram/credential-manager.test.ts +1 -0
  446. package/src/platforms/telegram/credential-manager.ts +11 -2
  447. package/src/platforms/telegram/my-telegram-org.ts +6 -2
  448. package/src/platforms/telegram/types.test.ts +1 -0
  449. package/src/platforms/webex/app-config.test.ts +1 -0
  450. package/src/platforms/webex/cli.ts +1 -4
  451. package/src/platforms/webex/client.test.ts +39 -12
  452. package/src/platforms/webex/client.ts +30 -61
  453. package/src/platforms/webex/commands/auth.test.ts +7 -1
  454. package/src/platforms/webex/commands/auth.ts +12 -15
  455. package/src/platforms/webex/commands/member.test.ts +1 -3
  456. package/src/platforms/webex/commands/member.ts +14 -19
  457. package/src/platforms/webex/commands/message.ts +4 -15
  458. package/src/platforms/webex/commands/snapshot.test.ts +28 -3
  459. package/src/platforms/webex/commands/snapshot.ts +3 -3
  460. package/src/platforms/webex/commands/space.test.ts +3 -3
  461. package/src/platforms/webex/commands/space.ts +2 -9
  462. package/src/platforms/webex/commands/whoami.test.ts +12 -5
  463. package/src/platforms/webex/commands/whoami.ts +2 -0
  464. package/src/platforms/webex/credential-manager.ts +11 -2
  465. package/src/platforms/webex/ensure-auth.ts +1 -3
  466. package/src/platforms/webex/index.ts +1 -7
  467. package/src/platforms/webex/markdown-to-html.test.ts +141 -0
  468. package/src/platforms/webex/markdown-to-html.ts +194 -0
  469. package/src/platforms/webex/token-extractor.ts +6 -29
  470. package/src/platforms/wechatbot/cli.ts +0 -0
  471. package/src/platforms/wechatbot/client.test.ts +6 -2
  472. package/src/platforms/wechatbot/client.ts +6 -1
  473. package/src/platforms/wechatbot/commands/auth.test.ts +3 -7
  474. package/src/platforms/wechatbot/commands/message.test.ts +1 -4
  475. package/src/platforms/wechatbot/commands/message.ts +5 -1
  476. package/src/platforms/wechatbot/commands/template.test.ts +1 -4
  477. package/src/platforms/wechatbot/commands/user.test.ts +2 -7
  478. package/src/platforms/whatsapp/cli.ts +1 -4
  479. package/src/platforms/whatsapp/commands/auth.test.ts +19 -22
  480. package/src/platforms/whatsapp/commands/chat.test.ts +21 -24
  481. package/src/platforms/whatsapp/commands/chat.ts +2 -0
  482. package/src/platforms/whatsapp/commands/message.test.ts +22 -24
  483. package/src/platforms/whatsapp/commands/message.ts +3 -5
  484. package/src/platforms/whatsapp/commands/shared.ts +2 -5
  485. package/src/platforms/whatsapp/commands/whoami.test.ts +2 -2
  486. package/src/platforms/whatsapp/credential-manager.ts +2 -6
  487. package/src/platforms/whatsapp/ensure-auth.test.ts +1 -4
  488. package/src/platforms/whatsapp/ensure-auth.ts +14 -6
  489. package/src/platforms/whatsapp/index.ts +0 -2
  490. package/src/platforms/whatsappbot/client.test.ts +13 -7
  491. package/src/platforms/whatsappbot/client.ts +18 -4
  492. package/src/platforms/whatsappbot/commands/auth.ts +4 -1
  493. package/src/platforms/whatsappbot/commands/message.test.ts +12 -2
  494. package/src/platforms/whatsappbot/commands/message.ts +16 -3
  495. package/src/platforms/whatsappbot/commands/shared.ts +3 -1
  496. package/src/platforms/whatsappbot/commands/whoami.test.ts +1 -3
  497. package/src/platforms/whatsappbot/index.ts +0 -2
  498. package/src/shared/chromium/browsers.test.ts +274 -0
  499. package/src/shared/chromium/browsers.ts +86 -0
  500. package/src/shared/chromium/cookie-reader.test.ts +274 -0
  501. package/src/shared/chromium/cookie-reader.ts +111 -0
  502. package/src/shared/chromium/decryptor.test.ts +449 -0
  503. package/src/shared/chromium/decryptor.ts +227 -0
  504. package/src/shared/chromium/index.ts +11 -0
  505. package/src/shared/chromium/types.ts +11 -0
  506. package/src/shared/utils/derived-key-cache.ts +1 -1
  507. package/src/shared/utils/linux-keyring.ts +4 -4
  508. package/src/tui/adapters/kakaotalk-adapter.ts +6 -1
  509. package/src/tui/adapters/telegram-adapter.ts +1 -1
  510. package/src/tui/adapters/webex-adapter.ts +1 -1
  511. package/src/tui/app.ts +149 -59
  512. package/src/tui/utils.test.ts +144 -145
  513. package/src/tui/utils.ts +27 -29
  514. package/src/tui/views/channel-picker.ts +1 -1
  515. package/src/tui/views/workspace-picker.ts +1 -1
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
+
2
3
  import { findFuzzyChats, mergeChats, normalizeChatSearchText } from './chat-utils'
3
4
 
4
5
  describe('normalizeChatSearchText', () => {
@@ -56,7 +57,10 @@ describe('findFuzzyChats', () => {
56
57
 
57
58
  describe('mergeChats', () => {
58
59
  const a = [{ id: 1, title: 'A', type: 'group' }] as any[]
59
- const b = [{ id: 1, title: 'A', type: 'group' }, { id: 2, title: 'B', type: 'group' }] as any[]
60
+ const b = [
61
+ { id: 1, title: 'A', type: 'group' },
62
+ { id: 2, title: 'B', type: 'group' },
63
+ ] as any[]
60
64
 
61
65
  test('deduplicates by id', () => {
62
66
  const result = mergeChats(a, b)
@@ -1,15 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
3
  import { Command } from 'commander'
4
+
4
5
  import pkg from '../../../package.json' with { type: 'json' }
5
6
  import { authCommand, chatCommand, messageCommand, whoamiCommand } from './commands'
6
7
 
7
8
  const program = new Command()
8
9
 
9
- program
10
- .name('agent-telegram')
11
- .description('CLI tool for Telegram communication via TDLib')
12
- .version(pkg.version)
10
+ program.name('agent-telegram').description('CLI tool for Telegram communication via TDLib').version(pkg.version)
13
11
 
14
12
  program.addCommand(authCommand)
15
13
  program.addCommand(chatCommand)
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, mock, test } from 'bun:test'
2
+
2
3
  import { TelegramTdlibClient } from './client'
3
4
  import type { TelegramAccount, TelegramAccountPaths } from './types'
4
5
 
@@ -62,14 +63,20 @@ describe('listChats', () => {
62
63
  events.push({ '@type': 'ok', '@extra': request['@extra'] })
63
64
  } else {
64
65
  // given — third call returns 404 (all chats loaded)
65
- events.push({ '@type': 'error', code: 404, message: 'Chat list has been loaded completely', '@extra': request['@extra'] })
66
+ events.push({
67
+ '@type': 'error',
68
+ code: 404,
69
+ message: 'Chat list has been loaded completely',
70
+ '@extra': request['@extra'],
71
+ })
66
72
  }
67
73
  return
68
74
  }
69
75
 
70
76
  if (request['@type'] === 'getChats') {
71
77
  // when — after first two loadChats calls, return partial; after 404, return all
72
- const returnCount = loadChatsCallCount >= 3 ? allChatIds.length : Math.min(loadChatsCallCount * 2, allChatIds.length)
78
+ const returnCount =
79
+ loadChatsCallCount >= 3 ? allChatIds.length : Math.min(loadChatsCallCount * 2, allChatIds.length)
73
80
  events.push({
74
81
  '@type': 'chats',
75
82
  total_count: returnCount,
@@ -81,7 +88,13 @@ describe('listChats', () => {
81
88
 
82
89
  if (request['@type'] === 'getChat') {
83
90
  const chatId = request.chat_id
84
- const typeNames = ['chatTypePrivate', 'chatTypePrivate', 'chatTypeBasicGroup', 'chatTypeSupergroup', 'chatTypeSupergroup']
91
+ const typeNames = [
92
+ 'chatTypePrivate',
93
+ 'chatTypePrivate',
94
+ 'chatTypeBasicGroup',
95
+ 'chatTypeSupergroup',
96
+ 'chatTypeSupergroup',
97
+ ]
85
98
  const idx = allChatIds.indexOf(chatId)
86
99
  events.push({
87
100
  '@type': 'chat',
@@ -1,4 +1,5 @@
1
1
  import { mkdir } from 'node:fs/promises'
2
+
2
3
  import pkg from '../../../package.json' with { type: 'json' }
3
4
  import { findFuzzyChats, mergeChats, normalizeChatSearchText } from './chat-utils'
4
5
  import { TdjsonBinding } from './tdlib'
@@ -90,7 +91,9 @@ export class TelegramTdlibClient {
90
91
  application_version: `agent-messenger/${pkg.version}`,
91
92
  })
92
93
 
93
- state = (await this.waitForAuthorizationStateChange('authorizationStateWaitTdlibParameters')) as TdAuthorizationState
94
+ state = (await this.waitForAuthorizationStateChange(
95
+ 'authorizationStateWaitTdlibParameters',
96
+ )) as TdAuthorizationState
94
97
  }
95
98
 
96
99
  return state
@@ -431,7 +434,9 @@ export class TelegramTdlibClient {
431
434
  }
432
435
 
433
436
  const chats = await this.searchChats(reference, 20)
434
- const exactMatch = chats.find((chat) => normalizeChatSearchText(chat.title) === normalizeChatSearchText(reference))
437
+ const exactMatch = chats.find(
438
+ (chat) => normalizeChatSearchText(chat.title) === normalizeChatSearchText(reference),
439
+ )
435
440
 
436
441
  if (exactMatch) {
437
442
  return this.call({
@@ -490,7 +495,9 @@ export class TelegramTdlibClient {
490
495
  const pending = this.pendingMessages.get(update.old_message_id)
491
496
  if (pending) {
492
497
  this.pendingMessages.delete(update.old_message_id)
493
- pending.reject(new TelegramError(update.error_message ?? 'Message send failed', update.error_code ?? 'send_failed'))
498
+ pending.reject(
499
+ new TelegramError(update.error_message ?? 'Message send failed', update.error_code ?? 'send_failed'),
500
+ )
494
501
  }
495
502
  return event
496
503
  }
@@ -527,7 +534,10 @@ export class TelegramTdlibClient {
527
534
  this.handleEvent(event)
528
535
  }
529
536
 
530
- throw new TelegramError(`Timed out waiting for authorization state change from ${previousType ?? 'unknown state'}.`, 'timeout')
537
+ throw new TelegramError(
538
+ `Timed out waiting for authorization state change from ${previousType ?? 'unknown state'}.`,
539
+ 'timeout',
540
+ )
531
541
  }
532
542
 
533
543
  private async waitForAuthorizationState(targetType: string, timeoutMs: number = 15000): Promise<any> {
@@ -1,4 +1,5 @@
1
1
  import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2
+
2
3
  import { getNonInteractiveLoginMessage, promptNextLoginInput } from './auth'
3
4
 
4
5
  describe('promptNextLoginInput non-interactive', () => {
@@ -2,9 +2,10 @@ import { Writable } from 'node:stream'
2
2
 
3
3
  import { Command } from 'commander'
4
4
 
5
+ import { info, error as stderrError } from '@/shared/utils/stderr'
6
+
5
7
  import { handleError } from '../../../shared/utils/error-handler'
6
8
  import { formatOutput } from '../../../shared/utils/output'
7
- import { info, error as stderrError } from '@/shared/utils/stderr'
8
9
  import { getTelegramAppCredentials } from '../app-config'
9
10
  import { TelegramTdlibClient } from '../client'
10
11
  import { TelegramCredentialManager } from '../credential-manager'
@@ -226,9 +227,7 @@ async function handleNonInteractiveProvisioning(
226
227
  }
227
228
 
228
229
  if (!options.phone) {
229
- console.log(
230
- formatOutput({ next_action: 'provide_phone', message: 'Provide --phone flag to start login.' }, pretty),
231
- )
230
+ console.log(formatOutput({ next_action: 'provide_phone', message: 'Provide --phone flag to start login.' }, pretty))
232
231
  process.exit(0)
233
232
  }
234
233
 
@@ -11,9 +11,7 @@ const mockSearchChats = mock(() =>
11
11
  Promise.resolve([{ id: 'chat-1', title: 'General', type: 'supergroup', unread_count: 0 }]),
12
12
  )
13
13
 
14
- const mockGetChat = mock(() =>
15
- Promise.resolve({ id: 'chat-1', title: 'General', type: 'supergroup', unread_count: 0 }),
16
- )
14
+ const mockGetChat = mock(() => Promise.resolve({ id: 'chat-1', title: 'General', type: 'supergroup', unread_count: 0 }))
17
15
 
18
16
  const mockClient = {
19
17
  listChats: mockListChats,
@@ -22,8 +20,7 @@ const mockClient = {
22
20
  }
23
21
 
24
22
  mock.module('./shared', () => ({
25
- withTelegramClient: async (_opts: unknown, fn: (client: typeof mockClient) => Promise<unknown>) =>
26
- fn(mockClient),
23
+ withTelegramClient: async (_opts: unknown, fn: (client: typeof mockClient) => Promise<unknown>) => fn(mockClient),
27
24
  }))
28
25
 
29
26
  import { chatCommand } from './chat'
@@ -1,4 +1,5 @@
1
1
  import { Command } from 'commander'
2
+
2
3
  import { handleError } from '../../../shared/utils/error-handler'
3
4
  import { formatOutput } from '../../../shared/utils/output'
4
5
  import { parseLimitOption, withTelegramClient } from './shared'
@@ -7,9 +7,7 @@ const mockListMessages = mock(() =>
7
7
  ]),
8
8
  )
9
9
 
10
- const mockSendMessage = mock(() =>
11
- Promise.resolve({ id: 3, text: 'Sent message', sender_id: 'user-1', date: 3000 }),
12
- )
10
+ const mockSendMessage = mock(() => Promise.resolve({ id: 3, text: 'Sent message', sender_id: 'user-1', date: 3000 }))
13
11
 
14
12
  const mockClient = {
15
13
  listMessages: mockListMessages,
@@ -17,8 +15,7 @@ const mockClient = {
17
15
  }
18
16
 
19
17
  mock.module('./shared', () => ({
20
- withTelegramClient: async (_opts: unknown, fn: (client: typeof mockClient) => Promise<unknown>) =>
21
- fn(mockClient),
18
+ withTelegramClient: async (_opts: unknown, fn: (client: typeof mockClient) => Promise<unknown>) => fn(mockClient),
22
19
  }))
23
20
 
24
21
  import { messageCommand } from './message'
@@ -1,4 +1,5 @@
1
1
  import { Command } from 'commander'
2
+
2
3
  import { handleError } from '../../../shared/utils/error-handler'
3
4
  import { formatOutput } from '../../../shared/utils/output'
4
5
  import { parseLimitOption, withTelegramClient } from './shared'
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
+
2
3
  import { TelegramError } from '../types'
3
4
  import { parseLimitOption } from './shared'
4
5
 
@@ -1,8 +1,8 @@
1
1
  import { afterEach, beforeEach, describe, expect, spyOn, test } from 'bun:test'
2
2
 
3
3
  import { TelegramTdlibClient } from '../client'
4
- import type { TelegramAccount } from '../types'
5
4
  import { TelegramCredentialManager } from '../credential-manager'
5
+ import type { TelegramAccount } from '../types'
6
6
  import * as sharedModule from './shared'
7
7
  import { whoamiAction } from './whoami'
8
8
 
@@ -28,12 +28,10 @@ let consoleLogSpy: ReturnType<typeof spyOn>
28
28
  describe('whoami command', () => {
29
29
  beforeEach(() => {
30
30
  getAuthStatusSpy = spyOn(TelegramTdlibClient.prototype, 'getAuthStatus').mockResolvedValue(mockAuthStatus)
31
- withTelegramClientSpy = spyOn(sharedModule, 'withTelegramClient').mockImplementation(
32
- async (_opts, fn) => {
33
- const fakeClient = Object.create(TelegramTdlibClient.prototype) as TelegramTdlibClient
34
- return fn(fakeClient, {} as TelegramAccount, new TelegramCredentialManager())
35
- },
36
- )
31
+ withTelegramClientSpy = spyOn(sharedModule, 'withTelegramClient').mockImplementation(async (_opts, fn) => {
32
+ const fakeClient = Object.create(TelegramTdlibClient.prototype) as TelegramTdlibClient
33
+ return fn(fakeClient, {} as TelegramAccount, new TelegramCredentialManager())
34
+ })
37
35
  consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
38
36
  })
39
37
 
@@ -13,7 +13,7 @@ export async function whoamiAction(options: { account?: string; pretty?: boolean
13
13
  account_id: status.account_id,
14
14
  phone_number: status.phone_number,
15
15
  authenticated: status.authenticated,
16
- ...status.user && { user: status.user },
16
+ ...(status.user && { user: status.user }),
17
17
  }
18
18
  console.log(formatOutput(output, options.pretty))
19
19
  })
@@ -1,6 +1,7 @@
1
1
  import { afterAll, describe, expect, test } from 'bun:test'
2
2
  import { existsSync, rmSync } from 'node:fs'
3
3
  import { join } from 'node:path'
4
+
4
5
  import { TelegramCredentialManager } from './credential-manager'
5
6
 
6
7
  const testDirs: string[] = []
@@ -2,6 +2,7 @@ import { existsSync } from 'node:fs'
2
2
  import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'
3
3
  import { homedir } from 'node:os'
4
4
  import { join } from 'node:path'
5
+
5
6
  import {
6
7
  createAccountId,
7
8
  type TelegramAccount,
@@ -87,14 +88,22 @@ export class TelegramCredentialManager {
87
88
  const oldPaths = this.getAccountPaths(normalizedOldAccountId)
88
89
  const newPaths = this.getAccountPaths(account.account_id)
89
90
 
90
- if (normalizedOldAccountId !== account.account_id && existsSync(oldPaths.account_dir) && existsSync(newPaths.account_dir)) {
91
+ if (
92
+ normalizedOldAccountId !== account.account_id &&
93
+ existsSync(oldPaths.account_dir) &&
94
+ existsSync(newPaths.account_dir)
95
+ ) {
91
96
  throw new TelegramError(
92
97
  `Can't migrate Telegram account data from "${normalizedOldAccountId}" to "${account.account_id}" because the target TDLib directory already exists: ${newPaths.account_dir}`,
93
98
  'account_migration_conflict',
94
99
  )
95
100
  }
96
101
 
97
- if (normalizedOldAccountId !== account.account_id && existsSync(oldPaths.account_dir) && !existsSync(newPaths.account_dir)) {
102
+ if (
103
+ normalizedOldAccountId !== account.account_id &&
104
+ existsSync(oldPaths.account_dir) &&
105
+ !existsSync(newPaths.account_dir)
106
+ ) {
98
107
  await mkdir(this.tdlibRootDir, { recursive: true })
99
108
  await rename(oldPaths.account_dir, newPaths.account_dir)
100
109
  }
@@ -187,8 +187,12 @@ function isCreateApplicationPage(html: string): boolean {
187
187
  }
188
188
 
189
189
  function extractAppCredentials(html: string): { api_id: number; api_hash: string } {
190
- const apiIdMatch = html.match(/<span class="form-control input-xlarge uneditable-input"[^>]*><strong>(\d+)<\/strong><\/span>/)
191
- const apiHashMatch = html.match(/<span class="form-control input-xlarge uneditable-input"[^>]*>([a-f0-9]{32})<\/span>/)
190
+ const apiIdMatch = html.match(
191
+ /<span class="form-control input-xlarge uneditable-input"[^>]*><strong>(\d+)<\/strong><\/span>/,
192
+ )
193
+ const apiHashMatch = html.match(
194
+ /<span class="form-control input-xlarge uneditable-input"[^>]*>([a-f0-9]{32})<\/span>/,
195
+ )
192
196
 
193
197
  if (!apiIdMatch?.[1] || !apiHashMatch?.[1]) {
194
198
  throw new TelegramError('Failed to parse my.telegram.org response', 'parse_error')
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
+
2
3
  import { findFuzzyChats, normalizeChatSearchText } from './chat-utils'
3
4
  import { createAccountId, simplifyChat, simplifyMessage, summarizeAuthorizationState } from './types'
4
5
 
@@ -1,4 +1,5 @@
1
1
  import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2
+
2
3
  import { getWebexAppCredentials } from './app-config'
3
4
 
4
5
  const ENV_KEYS = [
@@ -18,10 +18,7 @@ function isAuthCommand(command: CommandType): boolean {
18
18
 
19
19
  const program = new Command()
20
20
 
21
- program
22
- .name('agent-webex')
23
- .description('CLI tool for Cisco Webex communication')
24
- .version(pkg.version)
21
+ program.name('agent-webex').description('CLI tool for Cisco Webex communication').version(pkg.version)
25
22
 
26
23
  program.hook('preAction', async (_thisCommand, actionCommand) => {
27
24
  if (isAuthCommand(actionCommand)) return
@@ -155,9 +155,7 @@ describe('WebexClient', () => {
155
155
  const client = await new WebexClient().login({ token: 'test-token' })
156
156
  await client.sendMessage('room1', '**bold**', { markdown: true })
157
157
 
158
- expect(fetchCalls[0].options?.body).toBe(
159
- JSON.stringify({ roomId: 'room1', markdown: '**bold**' }),
160
- )
158
+ expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ roomId: 'room1', markdown: '**bold**' }))
161
159
  })
162
160
  })
163
161
 
@@ -168,9 +166,7 @@ describe('WebexClient', () => {
168
166
  const client = await new WebexClient().login({ token: 'test-token' })
169
167
  await client.sendDirectMessage('user@example.com', 'Hello')
170
168
 
171
- expect(fetchCalls[0].options?.body).toBe(
172
- JSON.stringify({ toPersonEmail: 'user@example.com', text: 'Hello' }),
173
- )
169
+ expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ toPersonEmail: 'user@example.com', text: 'Hello' }))
174
170
  })
175
171
 
176
172
  test('sends markdown direct message when option set', async () => {
@@ -246,9 +242,7 @@ describe('WebexClient', () => {
246
242
 
247
243
  expect(fetchCalls[0].url).toBe('https://webexapis.com/v1/messages/msg1')
248
244
  expect(fetchCalls[0].options?.method).toBe('PUT')
249
- expect(fetchCalls[0].options?.body).toBe(
250
- JSON.stringify({ roomId: 'room1', text: 'Edited text' }),
251
- )
245
+ expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ roomId: 'room1', text: 'Edited text' }))
252
246
  })
253
247
 
254
248
  test('sends markdown when option set', async () => {
@@ -257,9 +251,7 @@ describe('WebexClient', () => {
257
251
  const client = await new WebexClient().login({ token: 'test-token' })
258
252
  await client.editMessage('msg1', 'room1', '**edited**', { markdown: true })
259
253
 
260
- expect(fetchCalls[0].options?.body).toBe(
261
- JSON.stringify({ roomId: 'room1', markdown: '**edited**' }),
262
- )
254
+ expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ roomId: 'room1', markdown: '**edited**' }))
263
255
  })
264
256
  })
265
257
 
@@ -483,6 +475,29 @@ describe('WebexClient', () => {
483
475
  expect(message.personEmail).toBe('test@example.com')
484
476
  expect(message.created).toBe('2026-01-01T00:00:00.000Z')
485
477
  })
478
+
479
+ test('markdown option converts content to HTML and strips displayName', async () => {
480
+ mockResponse(mockActivity('bold text'))
481
+
482
+ const client = await createExtractedClient()
483
+ await client.sendMessage(TEST_ROOM_ID, '**bold text**', { markdown: true })
484
+
485
+ const body = JSON.parse(fetchCalls[0].options?.body as string)
486
+ expect(body.object.displayName).toBe('bold text')
487
+ expect(body.object.content).toBe('<strong>bold text</strong>')
488
+ expect(body.object.markdown).toBeUndefined()
489
+ })
490
+
491
+ test('markdown option does not affect plain text messages', async () => {
492
+ mockResponse(mockActivity('Hello world'))
493
+
494
+ const client = await createExtractedClient()
495
+ await client.sendMessage(TEST_ROOM_ID, 'Hello world')
496
+
497
+ const body = JSON.parse(fetchCalls[0].options?.body as string)
498
+ expect(body.object.displayName).toBe('Hello world')
499
+ expect(body.object.content).toBe('Hello world')
500
+ })
486
501
  })
487
502
 
488
503
  describe('listMessages', () => {
@@ -637,6 +652,18 @@ describe('WebexClient', () => {
637
652
  const body = JSON.parse(fetchCalls[0].options?.body as string)
638
653
  expect(body.target.id).toBe(TEST_CONV_UUID)
639
654
  })
655
+
656
+ test('markdown option converts content to HTML and strips displayName', async () => {
657
+ mockResponse(mockActivity('italic text'))
658
+
659
+ const client = await createExtractedClient()
660
+ await client.editMessage('activity-123', TEST_ROOM_ID, '_italic text_', { markdown: true })
661
+
662
+ const body = JSON.parse(fetchCalls[0].options?.body as string)
663
+ expect(body.object.displayName).toBe('italic text')
664
+ expect(body.object.content).toBe('<em>italic text</em>')
665
+ expect(body.object.markdown).toBeUndefined()
666
+ })
640
667
  })
641
668
 
642
669
  describe('sendDirectMessage', () => {
@@ -1,7 +1,8 @@
1
- import type { WebexMembership, WebexMessage, WebexPerson, WebexSpace } from './types'
2
- import { WebexError } from './types'
3
1
  import { WebexCredentialManager } from './credential-manager'
4
2
  import { WebexEncryptionService } from './encryption'
3
+ import { markdownToHtml, stripMarkdown } from './markdown-to-html'
4
+ import type { WebexMembership, WebexMessage, WebexPerson, WebexSpace } from './types'
5
+ import { WebexError } from './types'
5
6
 
6
7
  const BASE_URL = 'https://webexapis.com/v1'
7
8
  const MAX_RETRIES = 3
@@ -35,10 +36,7 @@ export class WebexClient {
35
36
  const config = await credManager.loadConfig()
36
37
  const token = await credManager.getToken(config?.clientId, config?.clientSecret)
37
38
  if (!token) {
38
- throw new WebexError(
39
- 'No Webex credentials found. Run "auth login" to authenticate.',
40
- 'no_credentials',
41
- )
39
+ throw new WebexError('No Webex credentials found. Run "auth login" to authenticate.', 'no_credentials')
42
40
  }
43
41
  this.deviceUrl = config?.deviceUrl ?? null
44
42
  this.tokenType = config?.tokenType ?? null
@@ -62,10 +60,7 @@ export class WebexClient {
62
60
  }
63
61
 
64
62
  private getBucketKey(method: string, path: string): string {
65
- const normalized = path.replace(
66
- /\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?=\/|$)/gi,
67
- '/{id}',
68
- )
63
+ const normalized = path.replace(/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?=\/|$)/gi, '/{id}')
69
64
  return `${method}:${normalized}`
70
65
  }
71
66
 
@@ -151,10 +146,7 @@ export class WebexClient {
151
146
  errors?: Array<{ description: string }>
152
147
  trackingId?: string
153
148
  } | null
154
- const message =
155
- errorBody?.message ??
156
- errorBody?.errors?.[0]?.description ??
157
- `HTTP ${response.status}`
149
+ const message = errorBody?.message ?? errorBody?.errors?.[0]?.description ?? `HTTP ${response.status}`
158
150
  throw new WebexError(message, `http_${response.status}`)
159
151
  }
160
152
 
@@ -185,11 +177,7 @@ export class WebexClient {
185
177
  return this.request<WebexSpace>('GET', `/rooms/${spaceId}`)
186
178
  }
187
179
 
188
- async sendMessage(
189
- roomId: string,
190
- text: string,
191
- options?: { markdown?: boolean },
192
- ): Promise<WebexMessage> {
180
+ async sendMessage(roomId: string, text: string, options?: { markdown?: boolean }): Promise<WebexMessage> {
193
181
  if (this.useInternalAPI) {
194
182
  return this.sendMessageInternal(roomId, text, options)
195
183
  }
@@ -226,10 +214,7 @@ export class WebexClient {
226
214
 
227
215
  if (!response.ok) {
228
216
  const errorBody = (await response.json().catch(() => null)) as { message?: string } | null
229
- throw new WebexError(
230
- errorBody?.message ?? `HTTP ${response.status}`,
231
- `http_${response.status}`,
232
- )
217
+ throw new WebexError(errorBody?.message ?? `HTTP ${response.status}`, `http_${response.status}`)
233
218
  }
234
219
 
235
220
  if (response.status === 204) return undefined as T
@@ -237,7 +222,7 @@ export class WebexClient {
237
222
  }
238
223
 
239
224
  private async activityToMessage(a: InternalActivity, roomId: string): Promise<WebexMessage> {
240
- let text = a.object?.content ?? a.object?.displayName
225
+ let text = a.object?.displayName ?? a.object?.content
241
226
 
242
227
  if (this.encryption && text?.startsWith('eyJ')) {
243
228
  const keyUrl = a.encryptionKeyUrl ?? a.object?.encryptionKeyUrl
@@ -265,10 +250,8 @@ export class WebexClient {
265
250
  text: string,
266
251
  options?: { markdown?: boolean },
267
252
  ): Promise<{ object: Record<string, string>; encryptionKeyUrl?: string }> {
268
- const buildObject = (content: string): Record<string, string> =>
269
- options?.markdown
270
- ? { objectType: 'comment', displayName: content, content, markdown: content }
271
- : { objectType: 'comment', displayName: content, content }
253
+ const displayName = options?.markdown ? stripMarkdown(text) : text
254
+ const content = options?.markdown ? markdownToHtml(text) : text
272
255
 
273
256
  if (this.encryption) {
274
257
  const conv = await this.internalRequest<InternalConversation>(
@@ -276,14 +259,22 @@ export class WebexClient {
276
259
  )
277
260
  const keyUri = conv.defaultActivityEncryptionKeyUrl
278
261
  if (keyUri) {
279
- const encrypted = await this.encryption.encryptText(keyUri, text)
280
- if (encrypted) {
281
- return { object: buildObject(encrypted), encryptionKeyUrl: keyUri }
262
+ const encryptedDisplayName = await this.encryption.encryptText(keyUri, displayName)
263
+ const encryptedContent = await this.encryption.encryptText(keyUri, content)
264
+ if (encryptedDisplayName && encryptedContent) {
265
+ return {
266
+ object: {
267
+ objectType: 'comment',
268
+ displayName: encryptedDisplayName,
269
+ content: encryptedContent,
270
+ },
271
+ encryptionKeyUrl: keyUri,
272
+ }
282
273
  }
283
274
  }
284
275
  }
285
276
 
286
- return { object: buildObject(text) }
277
+ return { object: { objectType: 'comment', displayName, content } }
287
278
  }
288
279
 
289
280
  private async sendMessageInternal(
@@ -312,11 +303,7 @@ export class WebexClient {
312
303
  return this.activityToMessage(result, roomId)
313
304
  }
314
305
 
315
- async sendDirectMessage(
316
- personEmail: string,
317
- text: string,
318
- options?: { markdown?: boolean },
319
- ): Promise<WebexMessage> {
306
+ async sendDirectMessage(personEmail: string, text: string, options?: { markdown?: boolean }): Promise<WebexMessage> {
320
307
  if (this.useInternalAPI) {
321
308
  const roomId = await this.findDirectRoomByEmail(personEmail)
322
309
  if (!roomId) {
@@ -333,10 +320,7 @@ export class WebexClient {
333
320
  private async findDirectRoomByEmail(email: string): Promise<string | null> {
334
321
  const rooms = await this.request<{ items: WebexSpace[] }>('GET', `/rooms?type=direct&max=100`)
335
322
  for (const room of rooms.items) {
336
- const members = await this.request<{ items: WebexMembership[] }>(
337
- 'GET',
338
- `/memberships?roomId=${room.id}&max=10`,
339
- )
323
+ const members = await this.request<{ items: WebexMembership[] }>('GET', `/memberships?roomId=${room.id}&max=10`)
340
324
  if (members.items.some((m) => m.personEmail === email)) {
341
325
  return room.id
342
326
  }
@@ -365,9 +349,7 @@ export class WebexClient {
365
349
  if (this.useInternalAPI) {
366
350
  const activity = await this.internalRequest<InternalActivity>(`/activities/${messageId}`)
367
351
  const convId = activity.target?.id ?? ''
368
- const roomId = convId
369
- ? Buffer.from(`ciscospark://urn:TEAM:unknown/ROOM/${convId}`).toString('base64')
370
- : ''
352
+ const roomId = convId ? Buffer.from(`ciscospark://urn:TEAM:unknown/ROOM/${convId}`).toString('base64') : ''
371
353
  return this.activityToMessage(activity, roomId)
372
354
  }
373
355
  return this.request<WebexMessage>('GET', `/messages/${messageId}`)
@@ -423,11 +405,7 @@ export class WebexClient {
423
405
  return this.request<WebexMessage>('PUT', `/messages/${messageId}`, body)
424
406
  }
425
407
 
426
- async listPeople(options?: {
427
- email?: string
428
- displayName?: string
429
- max?: number
430
- }): Promise<WebexPerson[]> {
408
+ async listPeople(options?: { email?: string; displayName?: string; max?: number }): Promise<WebexPerson[]> {
431
409
  const params = new URLSearchParams()
432
410
  if (options?.email) params.set('email', options.email)
433
411
  if (options?.displayName) params.set('displayName', options.displayName)
@@ -441,24 +419,15 @@ export class WebexClient {
441
419
  async listMyMemberships(options?: { max?: number }): Promise<WebexMembership[]> {
442
420
  const params = new URLSearchParams()
443
421
  params.set('max', String(options?.max ?? 100))
444
- const data = await this.request<{ items: WebexMembership[] }>(
445
- 'GET',
446
- `/memberships?${params}`,
447
- )
422
+ const data = await this.request<{ items: WebexMembership[] }>('GET', `/memberships?${params}`)
448
423
  return data.items
449
424
  }
450
425
 
451
- async listMemberships(
452
- roomId: string,
453
- options?: { max?: number },
454
- ): Promise<WebexMembership[]> {
426
+ async listMemberships(roomId: string, options?: { max?: number }): Promise<WebexMembership[]> {
455
427
  const params = new URLSearchParams()
456
428
  params.set('roomId', roomId)
457
429
  if (options?.max) params.set('max', String(options.max))
458
- const data = await this.request<{ items: WebexMembership[] }>(
459
- 'GET',
460
- `/memberships?${params}`,
461
- )
430
+ const data = await this.request<{ items: WebexMembership[] }>('GET', `/memberships?${params}`)
462
431
  return data.items
463
432
  }
464
433
  }
@@ -90,7 +90,13 @@ describe('auth commands', () => {
90
90
  await loginAction({ clientId: 'my-id', clientSecret: 'my-secret', pretty: false })
91
91
 
92
92
  expect(WebexCredentialManager.prototype.requestDeviceCode).toHaveBeenCalledWith('my-id')
93
- expect(WebexCredentialManager.prototype.pollDeviceToken).toHaveBeenCalledWith('d', 0.01, 300, 'my-id', 'my-secret')
93
+ expect(WebexCredentialManager.prototype.pollDeviceToken).toHaveBeenCalledWith(
94
+ 'd',
95
+ 0.01,
96
+ 300,
97
+ 'my-id',
98
+ 'my-secret',
99
+ )
94
100
  })
95
101
 
96
102
  test('saves tokenType as oauth in config', async () => {