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
@@ -41,7 +41,12 @@ async function resolveClientCredentials(options: {
41
41
  return getWebexAppCredentials()
42
42
  }
43
43
 
44
- export async function loginAction(options: { token?: string; clientId?: string; clientSecret?: string; pretty?: boolean }): Promise<void> {
44
+ export async function loginAction(options: {
45
+ token?: string
46
+ clientId?: string
47
+ clientSecret?: string
48
+ pretty?: boolean
49
+ }): Promise<void> {
45
50
  try {
46
51
  const credManager = new WebexCredentialManager()
47
52
 
@@ -110,9 +115,7 @@ export async function statusAction(options: { pretty?: boolean }): Promise<void>
110
115
  const token = await credManager.getToken(config?.clientId, config?.clientSecret)
111
116
 
112
117
  if (!token) {
113
- console.log(
114
- formatOutput({ error: 'Not authenticated. Run "auth login" first.' }, options.pretty),
115
- )
118
+ console.log(formatOutput({ error: 'Not authenticated. Run "auth login" first.' }, options.pretty))
116
119
  process.exit(1)
117
120
  return
118
121
  }
@@ -139,10 +142,7 @@ export async function statusAction(options: { pretty?: boolean }): Promise<void>
139
142
 
140
143
  export async function extractAction(options: { pretty?: boolean; debug?: boolean }): Promise<void> {
141
144
  try {
142
- const extractor = new WebexTokenExtractor(
143
- undefined,
144
- options.debug ? (msg) => debug(`[debug] ${msg}`) : undefined,
145
- )
145
+ const extractor = new WebexTokenExtractor(undefined, options.debug ? (msg) => debug(`[debug] ${msg}`) : undefined)
146
146
 
147
147
  if (options.debug) {
148
148
  debug('[debug] Searching browser profiles for Webex tokens...')
@@ -154,7 +154,8 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
154
154
  console.log(
155
155
  formatOutput(
156
156
  {
157
- error: 'No Webex token found in any browser. Make sure you are logged in to web.webex.com in Chrome, Edge, Arc, or Brave.',
157
+ error:
158
+ 'No Webex token found in any browser. Make sure you are logged in to web.webex.com in Chrome, Edge, Arc, or Brave.',
158
159
  hint: 'Run "auth login" for OAuth Device Grant flow, or --debug for more info.',
159
160
  },
160
161
  options.pretty,
@@ -175,9 +176,7 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
175
176
  tokenType: 'extracted',
176
177
  deviceUrl: extracted.deviceUrl,
177
178
  userId: extracted.userId,
178
- encryptionKeys: extracted.encryptionKeys
179
- ? Object.fromEntries(extracted.encryptionKeys)
180
- : undefined,
179
+ encryptionKeys: extracted.encryptionKeys ? Object.fromEntries(extracted.encryptionKeys) : undefined,
181
180
  })
182
181
 
183
182
  console.log(
@@ -201,9 +200,7 @@ export async function logoutAction(options: { pretty?: boolean }): Promise<void>
201
200
  const config = await credManager.loadConfig()
202
201
 
203
202
  if (!config) {
204
- console.log(
205
- formatOutput({ error: 'Not authenticated. Run "auth login" first.' }, options.pretty),
206
- )
203
+ console.log(formatOutput({ error: 'Not authenticated. Run "auth login" first.' }, options.pretty))
207
204
  process.exit(1)
208
205
  return
209
206
  }
@@ -47,9 +47,7 @@ describe('member commands', () => {
47
47
 
48
48
  beforeEach(() => {
49
49
  mockListMemberships.mockReset().mockImplementation(() => Promise.resolve(mockMembers))
50
- mockLogin.mockReset().mockImplementation(() =>
51
- Promise.resolve({ listMemberships: mockListMemberships }),
52
- )
50
+ mockLogin.mockReset().mockImplementation(() => Promise.resolve({ listMemberships: mockListMemberships }))
53
51
  mockHandleError.mockReset().mockImplementation((err: Error) => {
54
52
  throw err
55
53
  })
@@ -5,10 +5,7 @@ import { formatOutput } from '@/shared/utils/output'
5
5
 
6
6
  import { WebexClient } from '../client'
7
7
 
8
- export async function listAction(
9
- spaceId: string,
10
- options: { limit?: number; pretty?: boolean },
11
- ): Promise<void> {
8
+ export async function listAction(spaceId: string, options: { limit?: number; pretty?: boolean }): Promise<void> {
12
9
  try {
13
10
  const client = await new WebexClient().login()
14
11
  const members = await client.listMemberships(spaceId, { max: options.limit })
@@ -28,18 +25,16 @@ export async function listAction(
28
25
  }
29
26
  }
30
27
 
31
- export const memberCommand = new Command('member')
32
- .description('Member commands')
33
- .addCommand(
34
- new Command('list')
35
- .description('List members of a space')
36
- .argument('<space-id>', 'Space ID')
37
- .option('--limit <n>', 'Number of members to retrieve', '100')
38
- .option('--pretty', 'Pretty print JSON output')
39
- .action((spaceId, options) =>
40
- listAction(spaceId, {
41
- limit: parseInt(options.limit, 10),
42
- pretty: options.pretty,
43
- }),
44
- ),
45
- )
28
+ export const memberCommand = new Command('member').description('Member commands').addCommand(
29
+ new Command('list')
30
+ .description('List members of a space')
31
+ .argument('<space-id>', 'Space ID')
32
+ .option('--limit <n>', 'Number of members to retrieve', '100')
33
+ .option('--pretty', 'Pretty print JSON output')
34
+ .action((spaceId, options) =>
35
+ listAction(spaceId, {
36
+ limit: parseInt(options.limit, 10),
37
+ pretty: options.pretty,
38
+ }),
39
+ ),
40
+ )
@@ -29,10 +29,7 @@ export async function sendAction(
29
29
  }
30
30
  }
31
31
 
32
- export async function listAction(
33
- spaceId: string,
34
- options: { limit?: number; pretty?: boolean },
35
- ): Promise<void> {
32
+ export async function listAction(spaceId: string, options: { limit?: number; pretty?: boolean }): Promise<void> {
36
33
  try {
37
34
  const client = await new WebexClient().login()
38
35
  const limit = options.limit ?? 50
@@ -52,10 +49,7 @@ export async function listAction(
52
49
  }
53
50
  }
54
51
 
55
- export async function getAction(
56
- messageId: string,
57
- options: { pretty?: boolean },
58
- ): Promise<void> {
52
+ export async function getAction(messageId: string, options: { pretty?: boolean }): Promise<void> {
59
53
  try {
60
54
  const client = await new WebexClient().login()
61
55
  const message = await client.getMessage(messageId)
@@ -74,15 +68,10 @@ export async function getAction(
74
68
  }
75
69
  }
76
70
 
77
- export async function deleteAction(
78
- messageId: string,
79
- options: { force?: boolean; pretty?: boolean },
80
- ): Promise<void> {
71
+ export async function deleteAction(messageId: string, options: { force?: boolean; pretty?: boolean }): Promise<void> {
81
72
  try {
82
73
  if (!options.force) {
83
- console.log(
84
- formatOutput({ warning: 'Use --force to confirm deletion', messageId }, options.pretty),
85
- )
74
+ console.log(formatOutput({ warning: 'Use --force to confirm deletion', messageId }, options.pretty))
86
75
  return process.exit(0)
87
76
  }
88
77
 
@@ -1,4 +1,5 @@
1
1
  import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
2
+
2
3
  import { WebexError } from '../types'
3
4
 
4
5
  const mockHandleError = mock((err: Error) => {
@@ -10,12 +11,36 @@ mock.module('@/shared/utils/error-handler', () => ({
10
11
  }))
11
12
 
12
13
  const mockSpaces = [
13
- { id: 'space-1', title: 'General', type: 'group', isLocked: false, lastActivity: '2024-01-15T00:00:00.000Z', created: '2024-01-01T00:00:00.000Z', creatorId: 'person-1' },
14
- { id: 'space-2', title: 'Random', type: 'group', isLocked: false, lastActivity: '2024-01-14T00:00:00.000Z', created: '2024-01-01T00:00:00.000Z', creatorId: 'person-1' },
14
+ {
15
+ id: 'space-1',
16
+ title: 'General',
17
+ type: 'group',
18
+ isLocked: false,
19
+ lastActivity: '2024-01-15T00:00:00.000Z',
20
+ created: '2024-01-01T00:00:00.000Z',
21
+ creatorId: 'person-1',
22
+ },
23
+ {
24
+ id: 'space-2',
25
+ title: 'Random',
26
+ type: 'group',
27
+ isLocked: false,
28
+ lastActivity: '2024-01-14T00:00:00.000Z',
29
+ created: '2024-01-01T00:00:00.000Z',
30
+ creatorId: 'person-1',
31
+ },
15
32
  ]
16
33
 
17
34
  const mockMyMemberships = [
18
- { id: 'mem-1', roomId: 'space-1', personId: 'person-1', personEmail: 'alice@example.com', personDisplayName: 'Alice', isModerator: true, created: '2024-01-01T00:00:00.000Z' },
35
+ {
36
+ id: 'mem-1',
37
+ roomId: 'space-1',
38
+ personId: 'person-1',
39
+ personEmail: 'alice@example.com',
40
+ personDisplayName: 'Alice',
41
+ isModerator: true,
42
+ created: '2024-01-01T00:00:00.000Z',
43
+ },
19
44
  ]
20
45
 
21
46
  const mockListSpaces = mock(() => Promise.resolve(mockSpaces as any))
@@ -1,11 +1,11 @@
1
1
  import { Command } from 'commander'
2
+
2
3
  import { handleError } from '@/shared/utils/error-handler'
3
4
  import { formatOutput } from '@/shared/utils/output'
5
+
4
6
  import { WebexClient } from '../client'
5
7
 
6
- export async function snapshotAction(options: {
7
- pretty?: boolean
8
- }): Promise<void> {
8
+ export async function snapshotAction(options: { pretty?: boolean }): Promise<void> {
9
9
  try {
10
10
  const client = await new WebexClient().login()
11
11
 
@@ -59,9 +59,9 @@ let consoleLogSpy: ReturnType<typeof spyOn>
59
59
  beforeEach(() => {
60
60
  mockListSpaces.mockReset().mockImplementation(() => Promise.resolve(mockSpaces))
61
61
  mockGetSpace.mockReset().mockImplementation(() => Promise.resolve(mockSpace))
62
- mockLogin.mockReset().mockImplementation(() =>
63
- Promise.resolve({ listSpaces: mockListSpaces, getSpace: mockGetSpace }),
64
- )
62
+ mockLogin
63
+ .mockReset()
64
+ .mockImplementation(() => Promise.resolve({ listSpaces: mockListSpaces, getSpace: mockGetSpace }))
65
65
  mockHandleError.mockReset().mockImplementation((err: Error) => {
66
66
  throw err
67
67
  })
@@ -5,11 +5,7 @@ import { formatOutput } from '@/shared/utils/output'
5
5
 
6
6
  import { WebexClient } from '../client'
7
7
 
8
- export async function listAction(options: {
9
- type?: string
10
- limit?: number
11
- pretty?: boolean
12
- }): Promise<void> {
8
+ export async function listAction(options: { type?: string; limit?: number; pretty?: boolean }): Promise<void> {
13
9
  try {
14
10
  const client = await new WebexClient().login()
15
11
  const spaces = await client.listSpaces({ type: options.type, max: options.limit })
@@ -26,10 +22,7 @@ export async function listAction(options: {
26
22
  }
27
23
  }
28
24
 
29
- export async function infoAction(
30
- spaceId: string,
31
- options: { pretty?: boolean },
32
- ): Promise<void> {
25
+ export async function infoAction(spaceId: string, options: { pretty?: boolean }): Promise<void> {
33
26
  try {
34
27
  const client = await new WebexClient().login()
35
28
  const space = await client.getSpace(spaceId)
@@ -18,7 +18,9 @@ const mockUser = {
18
18
  }
19
19
 
20
20
  const makeFakeClient = () => ({
21
- login: async function (this: unknown) { return this },
21
+ login: async function (this: unknown) {
22
+ return this
23
+ },
22
24
  testAuth: async () => mockUser,
23
25
  })
24
26
 
@@ -100,10 +102,15 @@ test('whoami outputs pretty-printed JSON when --pretty flag is passed', async ()
100
102
 
101
103
  test('whoami exits with code 1 when not authenticated', async () => {
102
104
  // given: no credentials
103
- webexClientSpy.mockImplementation(() => ({
104
- login: async () => { throw new WebexError('No Webex credentials found.', 'no_credentials') },
105
- testAuth: async () => mockUser,
106
- }) as unknown as clientModule.WebexClient)
105
+ webexClientSpy.mockImplementation(
106
+ () =>
107
+ ({
108
+ login: async () => {
109
+ throw new WebexError('No Webex credentials found.', 'no_credentials')
110
+ },
111
+ testAuth: async () => mockUser,
112
+ }) as unknown as clientModule.WebexClient,
113
+ )
107
114
 
108
115
  // when: running whoami
109
116
  await whoamiCommand.parseAsync([], { from: 'user' })
@@ -1,6 +1,8 @@
1
1
  import { Command } from 'commander'
2
+
2
3
  import { handleError } from '@/shared/utils/error-handler'
3
4
  import { formatOutput } from '@/shared/utils/output'
5
+
4
6
  import { WebexClient } from '../client'
5
7
 
6
8
  export async function whoamiAction(options: { pretty?: boolean }): Promise<void> {
@@ -95,7 +95,10 @@ export class WebexCredentialManager {
95
95
  }
96
96
  }
97
97
 
98
- async requestDeviceCode(clientId: string, scopes?: string): Promise<{
98
+ async requestDeviceCode(
99
+ clientId: string,
100
+ scopes?: string,
101
+ ): Promise<{
99
102
  deviceCode: string
100
103
  userCode: string
101
104
  verificationUri: string
@@ -136,7 +139,13 @@ export class WebexCredentialManager {
136
139
  }
137
140
  }
138
141
 
139
- async pollDeviceToken(deviceCode: string, interval: number, expiresIn: number, clientId: string, clientSecret?: string): Promise<WebexConfig> {
142
+ async pollDeviceToken(
143
+ deviceCode: string,
144
+ interval: number,
145
+ expiresIn: number,
146
+ clientId: string,
147
+ clientSecret?: string,
148
+ ): Promise<WebexConfig> {
140
149
  const basicAuth = btoa(`${clientId}:${clientSecret ?? ''}`)
141
150
  const deadline = Date.now() + expiresIn * 1000
142
151
 
@@ -32,9 +32,7 @@ export async function ensureWebexAuth(): Promise<void> {
32
32
  tokenType: 'extracted',
33
33
  deviceUrl: extracted.deviceUrl,
34
34
  userId: extracted.userId,
35
- encryptionKeys: extracted.encryptionKeys
36
- ? Object.fromEntries(extracted.encryptionKeys)
37
- : undefined,
35
+ encryptionKeys: extracted.encryptionKeys ? Object.fromEntries(extracted.encryptionKeys) : undefined,
38
36
  })
39
37
  } catch {
40
38
  // Intentionally silent — best-effort preflight that should not block commands
@@ -3,13 +3,7 @@ export { WebexCredentialManager } from './credential-manager'
3
3
  export { WebexTokenExtractor } from './token-extractor'
4
4
  export type { ExtractedWebexToken } from './token-extractor'
5
5
  export { WebexError } from './types'
6
- export type {
7
- WebexConfig,
8
- WebexMembership,
9
- WebexMessage,
10
- WebexPerson,
11
- WebexSpace,
12
- } from './types'
6
+ export type { WebexConfig, WebexMembership, WebexMessage, WebexPerson, WebexSpace } from './types'
13
7
  export {
14
8
  WebexConfigSchema,
15
9
  WebexMembershipSchema,
@@ -0,0 +1,141 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+
3
+ import { markdownToHtml, stripMarkdown } from './markdown-to-html'
4
+
5
+ describe('markdownToHtml', () => {
6
+ test('converts bold text', () => {
7
+ expect(markdownToHtml('**bold**')).toBe('<strong>bold</strong>')
8
+ })
9
+
10
+ test('converts italic text', () => {
11
+ expect(markdownToHtml('_italic_')).toBe('<em>italic</em>')
12
+ })
13
+
14
+ test('does not italicize mid-word underscores', () => {
15
+ expect(markdownToHtml('some_variable_name')).toBe('some_variable_name')
16
+ })
17
+
18
+ test('converts bold and italic text', () => {
19
+ expect(markdownToHtml('***both***')).toBe('<strong><em>both</em></strong>')
20
+ })
21
+
22
+ test('converts inline code', () => {
23
+ expect(markdownToHtml('Use `code` here')).toBe('Use <code>code</code> here')
24
+ })
25
+
26
+ test('converts code blocks with language', () => {
27
+ expect(markdownToHtml('```ts\nconst x = 1 < 2\n```')).toBe(
28
+ '<pre><code class="language-ts">const x = 1 &lt; 2</code></pre>',
29
+ )
30
+ })
31
+
32
+ test('converts code blocks without language', () => {
33
+ expect(markdownToHtml('```\nconst x = 1 & 2\n```')).toBe('<pre><code>const x = 1 &amp; 2</code></pre>')
34
+ })
35
+
36
+ test('does not process markdown inside code blocks', () => {
37
+ expect(markdownToHtml('```\n**bold** _italic_\n```')).toBe('<pre><code>**bold** _italic_</code></pre>')
38
+ })
39
+
40
+ test('converts links', () => {
41
+ expect(markdownToHtml('[Webex](https://example.com?a=1&b=2)')).toBe(
42
+ '<a href="https://example.com?a=1&amp;b=2">Webex</a>',
43
+ )
44
+ })
45
+
46
+ test('strips unsafe javascript: URLs to plain text', () => {
47
+ expect(markdownToHtml('[click](javascript:void)')).toBe('click')
48
+ })
49
+
50
+ test('strips unsafe data: URLs to plain text', () => {
51
+ expect(markdownToHtml('[x](data:text/html,payload)')).toBe('x')
52
+ })
53
+
54
+ test('allows mailto: links', () => {
55
+ expect(markdownToHtml('[email](mailto:a@b.com)')).toBe('<a href="mailto:a@b.com">email</a>')
56
+ })
57
+
58
+ test('escapes quotes in URLs to prevent attribute breakout', () => {
59
+ expect(markdownToHtml('[x](https://a.com?q="test")')).toBe('<a href="https://a.com?q=&quot;test&quot;">x</a>')
60
+ })
61
+
62
+ test('converts unordered lists', () => {
63
+ expect(markdownToHtml('- one\n- two')).toBe('<ul><li>one</li><li>two</li></ul>')
64
+ })
65
+
66
+ test('converts ordered lists', () => {
67
+ expect(markdownToHtml('1. one\n2. two')).toBe('<ol><li>one</li><li>two</li></ol>')
68
+ })
69
+
70
+ test('converts blockquotes', () => {
71
+ expect(markdownToHtml('> one\n> two')).toBe('<blockquote>one<br/>two</blockquote>')
72
+ })
73
+
74
+ test('converts headings', () => {
75
+ expect(markdownToHtml('# one\n###### six')).toBe('<h1>one</h1><br/><br/><h6>six</h6>')
76
+ })
77
+
78
+ test('converts horizontal rules', () => {
79
+ expect(markdownToHtml('before\n---\nafter')).toBe('before<br/><br/><hr><br/><br/>after')
80
+ })
81
+
82
+ test('converts paragraph newlines to br', () => {
83
+ expect(markdownToHtml('one\ntwo')).toBe('one<br/>two')
84
+ })
85
+
86
+ test('supports nested formatting', () => {
87
+ expect(markdownToHtml('**bold _and italic_**')).toBe('<strong>bold <em>and italic</em></strong>')
88
+ })
89
+
90
+ test('escapes html special characters in text', () => {
91
+ expect(markdownToHtml('5 < 7 & 8 > 3')).toBe('5 &lt; 7 &amp; 8 &gt; 3')
92
+ })
93
+
94
+ test('separates multiple paragraphs with br', () => {
95
+ expect(markdownToHtml('first\n\nsecond')).toBe('first<br/><br/>second')
96
+ })
97
+
98
+ test('renders mixed content', () => {
99
+ expect(markdownToHtml('Hello **team**\n\n- one\n- two\n\n```js\nconst x = 1\n```')).toBe(
100
+ 'Hello <strong>team</strong><br/><br/><ul><li>one</li><li>two</li></ul><br/><br/><pre><code class="language-js">const x = 1</code></pre>',
101
+ )
102
+ })
103
+
104
+ test('returns empty string for empty input', () => {
105
+ expect(markdownToHtml('')).toBe('')
106
+ })
107
+
108
+ test('returns plain text when there is no markdown', () => {
109
+ expect(markdownToHtml('hello world')).toBe('hello world')
110
+ })
111
+
112
+ test('preserves whitespace-only input', () => {
113
+ expect(markdownToHtml(' ')).toBe(' ')
114
+ })
115
+ })
116
+
117
+ describe('stripMarkdown', () => {
118
+ test('strips inline markdown syntax', () => {
119
+ expect(stripMarkdown('**bold** _italic_ `code`')).toBe('bold italic code')
120
+ })
121
+
122
+ test('strips links to their labels', () => {
123
+ expect(stripMarkdown('[Webex](https://example.com)')).toBe('Webex')
124
+ })
125
+
126
+ test('strips block markdown syntax', () => {
127
+ expect(stripMarkdown('# Title\n> quote\n- item\n1. first\n---')).toBe('Title\nquote\nitem\nfirst\n')
128
+ })
129
+
130
+ test('keeps code block content', () => {
131
+ expect(stripMarkdown('```ts\nconst x = 1\n```')).toBe('const x = 1')
132
+ })
133
+
134
+ test('handles nested formatting', () => {
135
+ expect(stripMarkdown('**bold _and italic_**')).toBe('bold and italic')
136
+ })
137
+
138
+ test('returns plain text unchanged', () => {
139
+ expect(stripMarkdown('hello world')).toBe('hello world')
140
+ })
141
+ })