agent-messenger 1.0.0 → 1.2.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 (512) hide show
  1. package/.claude/commands/release.md +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.github/workflows/ci.yml +1 -1
  4. package/.github/workflows/e2e.yml.disabled +69 -0
  5. package/CONTRIBUTING.md +2 -2
  6. package/README.md +18 -15
  7. package/biome.json +34 -2
  8. package/bun.lock +63 -0
  9. package/dist/package.json +8 -4
  10. package/dist/src/cli.d.ts.map +1 -1
  11. package/dist/src/cli.js +4 -1
  12. package/dist/src/cli.js.map +1 -1
  13. package/dist/src/platforms/discord/cli.js +4 -4
  14. package/dist/src/platforms/discord/cli.js.map +1 -1
  15. package/dist/src/platforms/discord/client.d.ts +26 -5
  16. package/dist/src/platforms/discord/client.d.ts.map +1 -1
  17. package/dist/src/platforms/discord/client.js +115 -17
  18. package/dist/src/platforms/discord/client.js.map +1 -1
  19. package/dist/src/platforms/discord/commands/auth.js +16 -16
  20. package/dist/src/platforms/discord/commands/auth.js.map +1 -1
  21. package/dist/src/platforms/discord/commands/channel.js +4 -4
  22. package/dist/src/platforms/discord/commands/channel.js.map +1 -1
  23. package/dist/src/platforms/discord/commands/dm.d.ts +9 -0
  24. package/dist/src/platforms/discord/commands/dm.d.ts.map +1 -0
  25. package/dist/src/platforms/discord/commands/dm.js +68 -0
  26. package/dist/src/platforms/discord/commands/dm.js.map +1 -0
  27. package/dist/src/platforms/discord/commands/friend.d.ts +3 -0
  28. package/dist/src/platforms/discord/commands/friend.d.ts.map +1 -0
  29. package/dist/src/platforms/discord/commands/friend.js +39 -0
  30. package/dist/src/platforms/discord/commands/friend.js.map +1 -0
  31. package/dist/src/platforms/discord/commands/index.d.ts +1 -1
  32. package/dist/src/platforms/discord/commands/index.d.ts.map +1 -1
  33. package/dist/src/platforms/discord/commands/index.js +1 -1
  34. package/dist/src/platforms/discord/commands/index.js.map +1 -1
  35. package/dist/src/platforms/discord/commands/member.d.ts +3 -0
  36. package/dist/src/platforms/discord/commands/member.d.ts.map +1 -0
  37. package/dist/src/platforms/discord/commands/member.js +47 -0
  38. package/dist/src/platforms/discord/commands/member.js.map +1 -0
  39. package/dist/src/platforms/discord/commands/mention.d.ts +8 -0
  40. package/dist/src/platforms/discord/commands/mention.d.ts.map +1 -0
  41. package/dist/src/platforms/discord/commands/mention.js +47 -0
  42. package/dist/src/platforms/discord/commands/mention.js.map +1 -0
  43. package/dist/src/platforms/discord/commands/message.d.ts +13 -0
  44. package/dist/src/platforms/discord/commands/message.d.ts.map +1 -1
  45. package/dist/src/platforms/discord/commands/message.js +95 -1
  46. package/dist/src/platforms/discord/commands/message.js.map +1 -1
  47. package/dist/src/platforms/discord/commands/note.d.ts +3 -0
  48. package/dist/src/platforms/discord/commands/note.d.ts.map +1 -0
  49. package/dist/src/platforms/discord/commands/note.js +56 -0
  50. package/dist/src/platforms/discord/commands/note.js.map +1 -0
  51. package/dist/src/platforms/discord/commands/profile.d.ts +3 -0
  52. package/dist/src/platforms/discord/commands/profile.d.ts.map +1 -0
  53. package/dist/src/platforms/discord/commands/profile.js +47 -0
  54. package/dist/src/platforms/discord/commands/profile.js.map +1 -0
  55. package/dist/src/platforms/discord/commands/server.d.ts +15 -0
  56. package/dist/src/platforms/discord/commands/server.d.ts.map +1 -0
  57. package/dist/src/platforms/discord/commands/server.js +102 -0
  58. package/dist/src/platforms/discord/commands/server.js.map +1 -0
  59. package/dist/src/platforms/discord/commands/snapshot.js +10 -10
  60. package/dist/src/platforms/discord/commands/snapshot.js.map +1 -1
  61. package/dist/src/platforms/discord/commands/thread.d.ts +10 -0
  62. package/dist/src/platforms/discord/commands/thread.d.ts.map +1 -0
  63. package/dist/src/platforms/discord/commands/thread.js +67 -0
  64. package/dist/src/platforms/discord/commands/thread.js.map +1 -0
  65. package/dist/src/platforms/discord/commands/user.d.ts.map +1 -1
  66. package/dist/src/platforms/discord/commands/user.js +14 -5
  67. package/dist/src/platforms/discord/commands/user.js.map +1 -1
  68. package/dist/src/platforms/discord/credential-manager.d.ts +13 -13
  69. package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -1
  70. package/dist/src/platforms/discord/credential-manager.js +28 -22
  71. package/dist/src/platforms/discord/credential-manager.js.map +1 -1
  72. package/dist/src/platforms/discord/super-properties.d.ts +4 -0
  73. package/dist/src/platforms/discord/super-properties.d.ts.map +1 -0
  74. package/dist/src/platforms/discord/super-properties.js +50 -0
  75. package/dist/src/platforms/discord/super-properties.js.map +1 -0
  76. package/dist/src/platforms/discord/token-extractor.d.ts +6 -1
  77. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  78. package/dist/src/platforms/discord/token-extractor.js +27 -2
  79. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  80. package/dist/src/platforms/discord/types.d.ts +389 -22
  81. package/dist/src/platforms/discord/types.d.ts.map +1 -1
  82. package/dist/src/platforms/discord/types.js +46 -4
  83. package/dist/src/platforms/discord/types.js.map +1 -1
  84. package/dist/src/platforms/slack/cli.d.ts.map +1 -1
  85. package/dist/src/platforms/slack/cli.js +7 -2
  86. package/dist/src/platforms/slack/cli.js.map +1 -1
  87. package/dist/src/platforms/slack/client.d.ts +19 -1
  88. package/dist/src/platforms/slack/client.d.ts.map +1 -1
  89. package/dist/src/platforms/slack/client.js +134 -0
  90. package/dist/src/platforms/slack/client.js.map +1 -1
  91. package/dist/src/platforms/slack/commands/activity.d.ts +3 -0
  92. package/dist/src/platforms/slack/commands/activity.d.ts.map +1 -0
  93. package/dist/src/platforms/slack/commands/activity.js +40 -0
  94. package/dist/src/platforms/slack/commands/activity.js.map +1 -0
  95. package/dist/src/platforms/slack/commands/drafts.d.ts +3 -0
  96. package/dist/src/platforms/slack/commands/drafts.d.ts.map +1 -0
  97. package/dist/src/platforms/slack/commands/drafts.js +45 -0
  98. package/dist/src/platforms/slack/commands/drafts.js.map +1 -0
  99. package/dist/src/platforms/slack/commands/index.d.ts +5 -0
  100. package/dist/src/platforms/slack/commands/index.d.ts.map +1 -1
  101. package/dist/src/platforms/slack/commands/index.js +5 -0
  102. package/dist/src/platforms/slack/commands/index.js.map +1 -1
  103. package/dist/src/platforms/slack/commands/saved.d.ts +3 -0
  104. package/dist/src/platforms/slack/commands/saved.d.ts.map +1 -0
  105. package/dist/src/platforms/slack/commands/saved.js +54 -0
  106. package/dist/src/platforms/slack/commands/saved.js.map +1 -0
  107. package/dist/src/platforms/slack/commands/sections.d.ts +3 -0
  108. package/dist/src/platforms/slack/commands/sections.d.ts.map +1 -0
  109. package/dist/src/platforms/slack/commands/sections.js +37 -0
  110. package/dist/src/platforms/slack/commands/sections.js.map +1 -0
  111. package/dist/src/platforms/slack/commands/unread.d.ts +12 -0
  112. package/dist/src/platforms/slack/commands/unread.d.ts.map +1 -0
  113. package/dist/src/platforms/slack/commands/unread.js +89 -0
  114. package/dist/src/platforms/slack/commands/unread.js.map +1 -0
  115. package/dist/src/platforms/slack/credential-manager.d.ts.map +1 -1
  116. package/dist/src/platforms/slack/credential-manager.js +20 -6
  117. package/dist/src/platforms/slack/credential-manager.js.map +1 -1
  118. package/dist/src/platforms/slack/token-extractor.d.ts +8 -1
  119. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  120. package/dist/src/platforms/slack/token-extractor.js +83 -11
  121. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  122. package/dist/src/platforms/slack/types.d.ts +52 -0
  123. package/dist/src/platforms/slack/types.d.ts.map +1 -1
  124. package/dist/src/platforms/slack/types.js.map +1 -1
  125. package/dist/src/platforms/teams/cli.d.ts.map +1 -0
  126. package/dist/{cli.js → src/platforms/teams/cli.js} +11 -10
  127. package/dist/src/platforms/teams/cli.js.map +1 -0
  128. package/dist/src/platforms/teams/client.d.ts +32 -0
  129. package/dist/src/platforms/teams/client.d.ts.map +1 -0
  130. package/dist/src/platforms/teams/client.js +202 -0
  131. package/dist/src/platforms/teams/client.js.map +1 -0
  132. package/dist/src/platforms/teams/commands/auth.d.ts +14 -0
  133. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -0
  134. package/dist/src/platforms/teams/commands/auth.js +176 -0
  135. package/dist/src/platforms/teams/commands/auth.js.map +1 -0
  136. package/dist/src/platforms/teams/commands/channel.d.ts +13 -0
  137. package/dist/src/platforms/teams/commands/channel.d.ts.map +1 -0
  138. package/dist/src/platforms/teams/commands/channel.js +97 -0
  139. package/dist/src/platforms/teams/commands/channel.js.map +1 -0
  140. package/dist/src/platforms/teams/commands/file.d.ts +12 -0
  141. package/dist/src/platforms/teams/commands/file.d.ts.map +1 -0
  142. package/dist/src/platforms/teams/commands/file.js +104 -0
  143. package/dist/src/platforms/teams/commands/file.js.map +1 -0
  144. package/dist/{commands → src/platforms/teams/commands}/index.d.ts +5 -2
  145. package/dist/src/platforms/teams/commands/index.d.ts.map +1 -0
  146. package/dist/{commands → src/platforms/teams/commands}/index.js +5 -2
  147. package/dist/src/platforms/teams/commands/index.js.map +1 -0
  148. package/dist/src/platforms/teams/commands/message.d.ts +17 -0
  149. package/dist/src/platforms/teams/commands/message.d.ts.map +1 -0
  150. package/dist/src/platforms/teams/commands/message.js +133 -0
  151. package/dist/src/platforms/teams/commands/message.js.map +1 -0
  152. package/dist/src/platforms/teams/commands/reaction.d.ts +9 -0
  153. package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -0
  154. package/dist/src/platforms/teams/commands/reaction.js +68 -0
  155. package/dist/src/platforms/teams/commands/reaction.js.map +1 -0
  156. package/dist/src/platforms/teams/commands/snapshot.d.ts +10 -0
  157. package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -0
  158. package/dist/src/platforms/teams/commands/snapshot.js +85 -0
  159. package/dist/src/platforms/teams/commands/snapshot.js.map +1 -0
  160. package/dist/src/platforms/teams/commands/team.d.ts +18 -0
  161. package/dist/src/platforms/teams/commands/team.d.ts.map +1 -0
  162. package/dist/src/platforms/teams/commands/team.js +130 -0
  163. package/dist/src/platforms/teams/commands/team.js.map +1 -0
  164. package/dist/src/platforms/teams/commands/user.d.ts.map +1 -0
  165. package/dist/src/platforms/teams/commands/user.js +88 -0
  166. package/dist/src/platforms/teams/commands/user.js.map +1 -0
  167. package/dist/src/platforms/teams/credential-manager.d.ts +18 -0
  168. package/dist/src/platforms/teams/credential-manager.d.ts.map +1 -0
  169. package/dist/src/platforms/teams/credential-manager.js +81 -0
  170. package/dist/src/platforms/teams/credential-manager.js.map +1 -0
  171. package/dist/src/platforms/teams/index.d.ts +4 -0
  172. package/dist/src/platforms/teams/index.d.ts.map +1 -0
  173. package/dist/src/platforms/teams/index.js +6 -0
  174. package/dist/src/platforms/teams/index.js.map +1 -0
  175. package/dist/src/platforms/teams/token-extractor.d.ts +41 -0
  176. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -0
  177. package/dist/src/platforms/teams/token-extractor.js +360 -0
  178. package/dist/src/platforms/teams/token-extractor.js.map +1 -0
  179. package/dist/src/platforms/teams/types.d.ts +209 -0
  180. package/dist/src/platforms/teams/types.d.ts.map +1 -0
  181. package/dist/src/platforms/teams/types.js +65 -0
  182. package/dist/src/platforms/teams/types.js.map +1 -0
  183. package/dist/src/shared/utils/derived-key-cache.d.ts +20 -0
  184. package/dist/src/shared/utils/derived-key-cache.d.ts.map +1 -0
  185. package/dist/src/shared/utils/derived-key-cache.js +52 -0
  186. package/dist/src/shared/utils/derived-key-cache.js.map +1 -0
  187. package/docs/README.md +113 -0
  188. package/docs/biome.json +8 -0
  189. package/docs/bun.lock +1426 -0
  190. package/docs/content/docs/agent-skills.mdx +98 -0
  191. package/docs/content/docs/index.mdx +124 -0
  192. package/docs/{discord.md → content/docs/integrations/discord.mdx} +46 -21
  193. package/docs/content/docs/integrations/meta.json +5 -0
  194. package/docs/{slack.md → content/docs/integrations/slack.mdx} +5 -4
  195. package/docs/content/docs/integrations/teams.mdx +322 -0
  196. package/docs/content/docs/meta.json +8 -0
  197. package/docs/content/docs/quick-start.mdx +103 -0
  198. package/docs/eslint.config.mjs +30 -0
  199. package/docs/next.config.ts +10 -0
  200. package/docs/package.json +42 -0
  201. package/docs/postcss.config.mjs +7 -0
  202. package/docs/public/file.svg +1 -0
  203. package/docs/public/globe.svg +1 -0
  204. package/docs/public/next.svg +1 -0
  205. package/docs/public/vercel.svg +1 -0
  206. package/docs/public/window.svg +1 -0
  207. package/docs/source.config.ts +11 -0
  208. package/docs/src/app/api/search/route.ts +4 -0
  209. package/docs/src/app/docs/[[...slug]]/page.tsx +53 -0
  210. package/docs/src/app/docs/layout.tsx +21 -0
  211. package/docs/src/app/globals.css +10 -0
  212. package/docs/src/app/icon.png +0 -0
  213. package/docs/src/app/layout.config.tsx +7 -0
  214. package/docs/src/app/layout.tsx +35 -0
  215. package/docs/src/app/page.tsx +489 -0
  216. package/docs/src/lib/source.ts +15 -0
  217. package/docs/src/mdx-components.tsx +18 -0
  218. package/docs/tsconfig.json +36 -0
  219. package/e2e/README.md +256 -0
  220. package/e2e/config.ts +51 -0
  221. package/e2e/discord.e2e.test.ts +252 -0
  222. package/e2e/helpers.ts +107 -0
  223. package/e2e/slack.e2e.test.ts +309 -0
  224. package/package.json +8 -4
  225. package/scripts/postbuild.ts +15 -0
  226. package/skills/agent-discord/SKILL.md +96 -30
  227. package/skills/agent-discord/references/authentication.md +27 -27
  228. package/skills/agent-discord/references/common-patterns.md +15 -15
  229. package/skills/agent-discord/templates/post-message.sh +6 -6
  230. package/skills/agent-discord/templates/{guild-summary.sh → server-summary.sh} +20 -20
  231. package/skills/agent-slack/SKILL.md +53 -0
  232. package/skills/agent-teams/SKILL.md +292 -0
  233. package/skills/agent-teams/references/authentication.md +375 -0
  234. package/skills/agent-teams/references/common-patterns.md +596 -0
  235. package/skills/agent-teams/templates/monitor-channel.sh +239 -0
  236. package/skills/agent-teams/templates/post-message.sh +224 -0
  237. package/skills/agent-teams/templates/team-summary.sh +210 -0
  238. package/src/cli.ts +4 -0
  239. package/src/platforms/discord/cli.ts +3 -3
  240. package/src/platforms/discord/client.test.ts +15 -15
  241. package/src/platforms/discord/client.ts +163 -17
  242. package/src/platforms/discord/commands/auth.test.ts +53 -37
  243. package/src/platforms/discord/commands/auth.ts +16 -16
  244. package/src/platforms/discord/commands/channel.test.ts +58 -46
  245. package/src/platforms/discord/commands/channel.ts +4 -4
  246. package/src/platforms/discord/commands/dm.test.ts +146 -0
  247. package/src/platforms/discord/commands/dm.ts +85 -0
  248. package/src/platforms/discord/commands/file.test.ts +40 -53
  249. package/src/platforms/discord/commands/friend.test.ts +134 -0
  250. package/src/platforms/discord/commands/friend.ts +45 -0
  251. package/src/platforms/discord/commands/index.ts +1 -1
  252. package/src/platforms/discord/commands/member.test.ts +98 -0
  253. package/src/platforms/discord/commands/member.ts +59 -0
  254. package/src/platforms/discord/commands/mention.test.ts +129 -0
  255. package/src/platforms/discord/commands/mention.ts +59 -0
  256. package/src/platforms/discord/commands/message.test.ts +139 -44
  257. package/src/platforms/discord/commands/message.ts +134 -1
  258. package/src/platforms/discord/commands/note.test.ts +84 -0
  259. package/src/platforms/discord/commands/note.ts +73 -0
  260. package/src/platforms/discord/commands/profile.test.ts +107 -0
  261. package/src/platforms/discord/commands/profile.ts +55 -0
  262. package/src/platforms/discord/commands/reaction.test.ts +54 -42
  263. package/src/platforms/discord/commands/server.test.ts +137 -0
  264. package/src/platforms/discord/commands/{guild.ts → server.ts} +31 -31
  265. package/src/platforms/discord/commands/snapshot.test.ts +1 -1
  266. package/src/platforms/discord/commands/snapshot.ts +10 -10
  267. package/src/platforms/discord/commands/thread.test.ts +121 -0
  268. package/src/platforms/discord/commands/thread.ts +92 -0
  269. package/src/platforms/discord/commands/user.test.ts +8 -8
  270. package/src/platforms/discord/commands/user.ts +16 -5
  271. package/src/platforms/discord/credential-manager.test.ts +137 -136
  272. package/src/platforms/discord/credential-manager.ts +35 -26
  273. package/src/platforms/discord/super-properties.ts +55 -0
  274. package/src/platforms/discord/token-extractor.test.ts +133 -383
  275. package/src/platforms/discord/token-extractor.ts +37 -3
  276. package/src/platforms/discord/types.test.ts +8 -8
  277. package/src/platforms/discord/types.ts +144 -8
  278. package/{tests → src/platforms/slack}/cli.test.ts +3 -3
  279. package/src/platforms/slack/cli.ts +10 -0
  280. package/{tests/slack-client.test.ts → src/platforms/slack/client.test.ts} +1 -1
  281. package/src/platforms/slack/client.ts +172 -1
  282. package/src/platforms/slack/commands/activity.test.ts +147 -0
  283. package/src/platforms/slack/commands/activity.ts +65 -0
  284. package/{tests → src/platforms/slack}/commands/auth.test.ts +25 -13
  285. package/{tests → src/platforms/slack}/commands/channel.test.ts +2 -2
  286. package/src/platforms/slack/commands/drafts.test.ts +136 -0
  287. package/src/platforms/slack/commands/drafts.ts +62 -0
  288. package/{tests → src/platforms/slack}/commands/file.test.ts +2 -2
  289. package/src/platforms/slack/commands/index.ts +5 -0
  290. package/{tests → src/platforms/slack}/commands/message.test.ts +2 -2
  291. package/{tests → src/platforms/slack}/commands/reaction.test.ts +1 -1
  292. package/src/platforms/slack/commands/saved.test.ts +140 -0
  293. package/src/platforms/slack/commands/saved.ts +71 -0
  294. package/src/platforms/slack/commands/sections.test.ts +80 -0
  295. package/src/platforms/slack/commands/sections.ts +50 -0
  296. package/{tests → src/platforms/slack}/commands/snapshot.test.ts +117 -105
  297. package/src/platforms/slack/commands/unread.test.ts +139 -0
  298. package/src/platforms/slack/commands/unread.ts +129 -0
  299. package/{tests → src/platforms/slack}/commands/user.test.ts +3 -3
  300. package/{tests → src/platforms/slack}/commands/workspace.test.ts +44 -95
  301. package/{tests → src/platforms/slack}/credential-manager.test.ts +2 -2
  302. package/src/platforms/slack/credential-manager.ts +22 -7
  303. package/src/platforms/slack/token-extractor-node-test.ts +40 -0
  304. package/src/platforms/slack/token-extractor-node.test.ts +10 -0
  305. package/src/platforms/slack/token-extractor.ts +93 -12
  306. package/{tests → src/platforms/slack}/types.test.ts +1 -1
  307. package/src/platforms/slack/types.ts +58 -0
  308. package/src/platforms/teams/cli.ts +36 -0
  309. package/src/platforms/teams/client.test.ts +500 -0
  310. package/src/platforms/teams/client.ts +365 -0
  311. package/src/platforms/teams/commands/auth.test.ts +99 -0
  312. package/src/platforms/teams/commands/auth.ts +232 -0
  313. package/src/platforms/teams/commands/channel.test.ts +147 -0
  314. package/src/platforms/teams/commands/channel.ts +129 -0
  315. package/src/platforms/teams/commands/file.test.ts +88 -0
  316. package/src/platforms/teams/commands/file.ts +144 -0
  317. package/src/platforms/teams/commands/index.ts +12 -0
  318. package/src/platforms/teams/commands/message.test.ts +110 -0
  319. package/src/platforms/teams/commands/message.ts +188 -0
  320. package/src/platforms/teams/commands/reaction.test.ts +87 -0
  321. package/src/platforms/teams/commands/reaction.ts +104 -0
  322. package/src/platforms/teams/commands/snapshot.test.ts +35 -0
  323. package/src/platforms/teams/commands/snapshot.ts +115 -0
  324. package/src/platforms/teams/commands/team.test.ts +157 -0
  325. package/src/platforms/teams/commands/team.ts +164 -0
  326. package/src/platforms/teams/commands/user.test.ts +83 -0
  327. package/src/platforms/teams/commands/user.ts +112 -0
  328. package/src/platforms/teams/credential-manager.test.ts +178 -0
  329. package/src/platforms/teams/credential-manager.ts +92 -0
  330. package/src/platforms/teams/index.ts +5 -0
  331. package/src/platforms/teams/token-extractor.test.ts +429 -0
  332. package/src/platforms/teams/token-extractor.ts +490 -0
  333. package/src/platforms/teams/types.test.ts +226 -0
  334. package/src/platforms/teams/types.ts +140 -0
  335. package/src/shared/utils/derived-key-cache.test.ts +136 -0
  336. package/src/shared/utils/derived-key-cache.ts +63 -0
  337. package/tsconfig.json +1 -1
  338. package/dist/cli.d.ts.map +0 -1
  339. package/dist/cli.js.map +0 -1
  340. package/dist/commands/auth.d.ts +0 -3
  341. package/dist/commands/auth.d.ts.map +0 -1
  342. package/dist/commands/auth.js +0 -140
  343. package/dist/commands/auth.js.map +0 -1
  344. package/dist/commands/channel.d.ts +0 -3
  345. package/dist/commands/channel.d.ts.map +0 -1
  346. package/dist/commands/channel.js +0 -118
  347. package/dist/commands/channel.js.map +0 -1
  348. package/dist/commands/file.d.ts +0 -3
  349. package/dist/commands/file.d.ts.map +0 -1
  350. package/dist/commands/file.js +0 -113
  351. package/dist/commands/file.js.map +0 -1
  352. package/dist/commands/index.d.ts.map +0 -1
  353. package/dist/commands/index.js.map +0 -1
  354. package/dist/commands/message.d.ts +0 -3
  355. package/dist/commands/message.d.ts.map +0 -1
  356. package/dist/commands/message.js +0 -214
  357. package/dist/commands/message.js.map +0 -1
  358. package/dist/commands/reaction.d.ts +0 -3
  359. package/dist/commands/reaction.d.ts.map +0 -1
  360. package/dist/commands/reaction.js +0 -100
  361. package/dist/commands/reaction.js.map +0 -1
  362. package/dist/commands/snapshot.d.ts +0 -3
  363. package/dist/commands/snapshot.d.ts.map +0 -1
  364. package/dist/commands/snapshot.js +0 -88
  365. package/dist/commands/snapshot.js.map +0 -1
  366. package/dist/commands/user.d.ts.map +0 -1
  367. package/dist/commands/user.js +0 -96
  368. package/dist/commands/user.js.map +0 -1
  369. package/dist/commands/workspace.d.ts +0 -3
  370. package/dist/commands/workspace.d.ts.map +0 -1
  371. package/dist/commands/workspace.js +0 -89
  372. package/dist/commands/workspace.js.map +0 -1
  373. package/dist/lib/credential-manager.d.ts +0 -13
  374. package/dist/lib/credential-manager.d.ts.map +0 -1
  375. package/dist/lib/credential-manager.js +0 -58
  376. package/dist/lib/credential-manager.js.map +0 -1
  377. package/dist/lib/index.d.ts +0 -3
  378. package/dist/lib/index.d.ts.map +0 -1
  379. package/dist/lib/index.js +0 -3
  380. package/dist/lib/index.js.map +0 -1
  381. package/dist/lib/ref-manager.d.ts +0 -26
  382. package/dist/lib/ref-manager.d.ts.map +0 -1
  383. package/dist/lib/ref-manager.js +0 -92
  384. package/dist/lib/ref-manager.js.map +0 -1
  385. package/dist/lib/slack-client.d.ts +0 -37
  386. package/dist/lib/slack-client.d.ts.map +0 -1
  387. package/dist/lib/slack-client.js +0 -379
  388. package/dist/lib/slack-client.js.map +0 -1
  389. package/dist/lib/token-extractor.d.ts +0 -28
  390. package/dist/lib/token-extractor.d.ts.map +0 -1
  391. package/dist/lib/token-extractor.js +0 -401
  392. package/dist/lib/token-extractor.js.map +0 -1
  393. package/dist/src/platforms/discord/client.test.d.ts +0 -2
  394. package/dist/src/platforms/discord/client.test.d.ts.map +0 -1
  395. package/dist/src/platforms/discord/client.test.js +0 -367
  396. package/dist/src/platforms/discord/client.test.js.map +0 -1
  397. package/dist/src/platforms/discord/commands/auth.test.d.ts +0 -2
  398. package/dist/src/platforms/discord/commands/auth.test.d.ts.map +0 -1
  399. package/dist/src/platforms/discord/commands/auth.test.js +0 -65
  400. package/dist/src/platforms/discord/commands/auth.test.js.map +0 -1
  401. package/dist/src/platforms/discord/commands/channel.test.d.ts +0 -2
  402. package/dist/src/platforms/discord/commands/channel.test.d.ts.map +0 -1
  403. package/dist/src/platforms/discord/commands/channel.test.js +0 -136
  404. package/dist/src/platforms/discord/commands/channel.test.js.map +0 -1
  405. package/dist/src/platforms/discord/commands/file.test.d.ts +0 -2
  406. package/dist/src/platforms/discord/commands/file.test.d.ts.map +0 -1
  407. package/dist/src/platforms/discord/commands/file.test.js +0 -83
  408. package/dist/src/platforms/discord/commands/file.test.js.map +0 -1
  409. package/dist/src/platforms/discord/commands/guild.test.d.ts +0 -2
  410. package/dist/src/platforms/discord/commands/guild.test.d.ts.map +0 -1
  411. package/dist/src/platforms/discord/commands/guild.test.js +0 -100
  412. package/dist/src/platforms/discord/commands/guild.test.js.map +0 -1
  413. package/dist/src/platforms/discord/commands/message.test.d.ts +0 -2
  414. package/dist/src/platforms/discord/commands/message.test.d.ts.map +0 -1
  415. package/dist/src/platforms/discord/commands/message.test.js +0 -91
  416. package/dist/src/platforms/discord/commands/message.test.js.map +0 -1
  417. package/dist/src/platforms/discord/commands/reaction.test.d.ts +0 -2
  418. package/dist/src/platforms/discord/commands/reaction.test.d.ts.map +0 -1
  419. package/dist/src/platforms/discord/commands/reaction.test.js +0 -115
  420. package/dist/src/platforms/discord/commands/reaction.test.js.map +0 -1
  421. package/dist/src/platforms/discord/commands/snapshot.test.d.ts +0 -2
  422. package/dist/src/platforms/discord/commands/snapshot.test.d.ts.map +0 -1
  423. package/dist/src/platforms/discord/commands/snapshot.test.js +0 -25
  424. package/dist/src/platforms/discord/commands/snapshot.test.js.map +0 -1
  425. package/dist/src/platforms/discord/commands/user.test.d.ts +0 -2
  426. package/dist/src/platforms/discord/commands/user.test.d.ts.map +0 -1
  427. package/dist/src/platforms/discord/commands/user.test.js +0 -103
  428. package/dist/src/platforms/discord/commands/user.test.js.map +0 -1
  429. package/dist/src/platforms/discord/credential-manager.test.d.ts +0 -2
  430. package/dist/src/platforms/discord/credential-manager.test.d.ts.map +0 -1
  431. package/dist/src/platforms/discord/credential-manager.test.js +0 -136
  432. package/dist/src/platforms/discord/credential-manager.test.js.map +0 -1
  433. package/dist/src/platforms/discord/token-extractor.test.d.ts +0 -2
  434. package/dist/src/platforms/discord/token-extractor.test.d.ts.map +0 -1
  435. package/dist/src/platforms/discord/token-extractor.test.js +0 -789
  436. package/dist/src/platforms/discord/token-extractor.test.js.map +0 -1
  437. package/dist/src/platforms/discord/types.test.d.ts +0 -2
  438. package/dist/src/platforms/discord/types.test.d.ts.map +0 -1
  439. package/dist/src/platforms/discord/types.test.js +0 -211
  440. package/dist/src/platforms/discord/types.test.js.map +0 -1
  441. package/dist/src/shared/utils/concurrency.test.d.ts +0 -2
  442. package/dist/src/shared/utils/concurrency.test.d.ts.map +0 -1
  443. package/dist/src/shared/utils/concurrency.test.js +0 -39
  444. package/dist/src/shared/utils/concurrency.test.js.map +0 -1
  445. package/dist/tests/cli.test.d.ts +0 -2
  446. package/dist/tests/cli.test.d.ts.map +0 -1
  447. package/dist/tests/cli.test.js +0 -83
  448. package/dist/tests/cli.test.js.map +0 -1
  449. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/CURRENT +0 -1
  450. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOCK +0 -0
  451. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG +0 -3
  452. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG.old +0 -1
  453. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/MANIFEST-000004 +0 -0
  454. package/dist/tests/commands/auth.test.d.ts +0 -2
  455. package/dist/tests/commands/auth.test.d.ts.map +0 -1
  456. package/dist/tests/commands/auth.test.js +0 -304
  457. package/dist/tests/commands/auth.test.js.map +0 -1
  458. package/dist/tests/commands/channel.test.d.ts +0 -2
  459. package/dist/tests/commands/channel.test.d.ts.map +0 -1
  460. package/dist/tests/commands/channel.test.js +0 -166
  461. package/dist/tests/commands/channel.test.js.map +0 -1
  462. package/dist/tests/commands/file.test.d.ts +0 -2
  463. package/dist/tests/commands/file.test.d.ts.map +0 -1
  464. package/dist/tests/commands/file.test.js +0 -175
  465. package/dist/tests/commands/file.test.js.map +0 -1
  466. package/dist/tests/commands/message.test.d.ts +0 -2
  467. package/dist/tests/commands/message.test.d.ts.map +0 -1
  468. package/dist/tests/commands/message.test.js +0 -293
  469. package/dist/tests/commands/message.test.js.map +0 -1
  470. package/dist/tests/commands/reaction.test.d.ts +0 -2
  471. package/dist/tests/commands/reaction.test.d.ts.map +0 -1
  472. package/dist/tests/commands/reaction.test.js +0 -84
  473. package/dist/tests/commands/reaction.test.js.map +0 -1
  474. package/dist/tests/commands/snapshot.test.d.ts +0 -2
  475. package/dist/tests/commands/snapshot.test.d.ts.map +0 -1
  476. package/dist/tests/commands/snapshot.test.js +0 -280
  477. package/dist/tests/commands/snapshot.test.js.map +0 -1
  478. package/dist/tests/commands/user.test.d.ts +0 -2
  479. package/dist/tests/commands/user.test.d.ts.map +0 -1
  480. package/dist/tests/commands/user.test.js +0 -117
  481. package/dist/tests/commands/user.test.js.map +0 -1
  482. package/dist/tests/commands/workspace.test.d.ts +0 -2
  483. package/dist/tests/commands/workspace.test.d.ts.map +0 -1
  484. package/dist/tests/commands/workspace.test.js +0 -453
  485. package/dist/tests/commands/workspace.test.js.map +0 -1
  486. package/dist/tests/credential-manager.test.d.ts +0 -2
  487. package/dist/tests/credential-manager.test.d.ts.map +0 -1
  488. package/dist/tests/credential-manager.test.js +0 -199
  489. package/dist/tests/credential-manager.test.js.map +0 -1
  490. package/dist/tests/slack-client.test.d.ts +0 -2
  491. package/dist/tests/slack-client.test.d.ts.map +0 -1
  492. package/dist/tests/slack-client.test.js +0 -741
  493. package/dist/tests/slack-client.test.js.map +0 -1
  494. package/dist/tests/types.test.d.ts +0 -2
  495. package/dist/tests/types.test.d.ts.map +0 -1
  496. package/dist/tests/types.test.js +0 -215
  497. package/dist/tests/types.test.js.map +0 -1
  498. package/dist/types/index.d.ts +0 -369
  499. package/dist/types/index.d.ts.map +0 -1
  500. package/dist/types/index.js +0 -92
  501. package/dist/types/index.js.map +0 -1
  502. package/dist/utils/error-handler.d.ts +0 -2
  503. package/dist/utils/error-handler.d.ts.map +0 -1
  504. package/dist/utils/error-handler.js +0 -5
  505. package/dist/utils/error-handler.js.map +0 -1
  506. package/dist/utils/output.d.ts +0 -2
  507. package/dist/utils/output.d.ts.map +0 -1
  508. package/dist/utils/output.js +0 -4
  509. package/dist/utils/output.js.map +0 -1
  510. package/src/platforms/discord/commands/guild.test.ts +0 -117
  511. /package/dist/{cli.d.ts → src/platforms/teams/cli.d.ts} +0 -0
  512. /package/dist/{commands → src/platforms/teams/commands}/user.d.ts +0 -0
package/e2e/README.md ADDED
@@ -0,0 +1,256 @@
1
+ # E2E Tests
2
+
3
+ End-to-end tests that run every CLI command against real Slack and Discord APIs.
4
+
5
+ ## Prerequisites
6
+
7
+ Before running E2E tests, you need:
8
+
9
+ 1. **Dedicated Test Workspaces** - Create separate Slack and Discord test workspaces/servers
10
+ - **Never run E2E tests against your business or personal accounts**
11
+ - Tests create and delete messages, which could interfere with real work
12
+
13
+ 2. **Test Channels** - Create an `e2e-test` channel in each test workspace/server
14
+ - Slack: Channel named `e2e-test`
15
+ - Discord: Text channel named `e2e-test`
16
+
17
+ 3. **Authentication** - Either:
18
+ - Local credentials from desktop apps (via `auth extract`)
19
+ - Environment variables (for CI)
20
+
21
+ ## Test Infrastructure
22
+
23
+ | File | Description |
24
+ |------|-------------|
25
+ | `config.ts` | Hardcoded test workspace/server IDs and validation |
26
+ | `helpers.ts` | CLI runner, JSON parser, message cleanup utilities |
27
+ | `slack.e2e.test.ts` | Slack command tests (23 tests) |
28
+ | `discord.e2e.test.ts` | Discord command tests (20 tests) |
29
+
30
+ ## Running E2E Tests Locally
31
+
32
+ ### Step 1: Extract Credentials
33
+
34
+ First, make sure the desktop apps (Slack/Discord) are running and logged into your **test** workspaces.
35
+
36
+ ```bash
37
+ # Extract Slack credentials
38
+ agent-slack auth extract
39
+
40
+ # Extract Discord credentials
41
+ agent-discord auth extract
42
+ ```
43
+
44
+ ### Step 2: Switch to Test Workspace
45
+
46
+ Ensure you're targeting the correct test workspace:
47
+
48
+ ```bash
49
+ # Verify Slack workspace
50
+ agent-slack workspace current
51
+ # Should show: "Agent Messenger" (T0AC55BSF6E)
52
+
53
+ # Verify Discord server
54
+ agent-discord server current
55
+ # Should show: "Agent Messenger" (1467039439770357844)
56
+ ```
57
+
58
+ If wrong, switch workspaces:
59
+
60
+ ```bash
61
+ agent-slack workspace switch <test-workspace-id>
62
+ agent-discord server switch <test-server-id>
63
+ ```
64
+
65
+ ### Step 3: Run Tests
66
+
67
+ ```bash
68
+ # Run all E2E tests
69
+ bun test e2e/
70
+
71
+ # Run only Slack tests
72
+ bun test e2e/slack.e2e.test.ts
73
+
74
+ # Run only Discord tests
75
+ bun test e2e/discord.e2e.test.ts
76
+
77
+ # Run specific test by name
78
+ bun test e2e/slack.e2e.test.ts --test-name-pattern "message send"
79
+ ```
80
+
81
+ ## Running E2E Tests in CI (GitHub Actions)
82
+
83
+ ### Required Secrets
84
+
85
+ Set these secrets in your GitHub repository settings:
86
+
87
+ #### Slack Secrets
88
+
89
+ | Secret | Description | How to Get |
90
+ |--------|-------------|------------|
91
+ | `E2E_SLACK_TOKEN` | Slack auth token (xoxc-...) | `agent-slack auth extract` → check output |
92
+ | `E2E_SLACK_COOKIE` | Slack cookie (xoxd-...) | Same as above |
93
+ | `E2E_SLACK_WORKSPACE_ID` | Test workspace ID | `agent-slack workspace current` |
94
+ | `E2E_SLACK_WORKSPACE_NAME` | Test workspace name | Same as above |
95
+
96
+ #### Discord Secrets
97
+
98
+ | Secret | Description | How to Get |
99
+ |--------|-------------|------------|
100
+ | `E2E_DISCORD_TOKEN` | Discord auth token | `agent-discord auth extract` → check output |
101
+ | `E2E_DISCORD_SERVER_ID` | Test server ID | `agent-discord server current` |
102
+
103
+ ### Getting Credentials for CI
104
+
105
+ Run locally to extract credentials, then copy them to GitHub Secrets:
106
+
107
+ ```bash
108
+ # Slack - extract and view credentials
109
+ agent-slack auth extract
110
+ cat ~/.agent-messenger/slack/credentials.json
111
+ # Copy token and cookie values
112
+
113
+ # Discord - extract and view credentials
114
+ agent-discord auth extract
115
+ cat ~/.agent-messenger/discord/credentials.json
116
+ # Copy token value
117
+ ```
118
+
119
+ ### Workflow Triggers
120
+
121
+ The E2E workflow (`.github/workflows/e2e.yml`) runs:
122
+
123
+ - **Manually**: Via `workflow_dispatch` (Actions tab → Run workflow)
124
+ - **On PRs**: When changes are made to `src/`, `e2e/`, or `package.json`
125
+
126
+ ### Manual Trigger Options
127
+
128
+ When triggering manually, you can select which platform to test:
129
+
130
+ - `all` - Run both Slack and Discord tests (default)
131
+ - `slack` - Run only Slack tests
132
+ - `discord` - Run only Discord tests
133
+
134
+ ## Test Coverage
135
+
136
+ ### Slack Tests (23 tests)
137
+
138
+ | Command Group | Tests |
139
+ |---------------|-------|
140
+ | `auth` | status |
141
+ | `workspace` | list, current |
142
+ | `message` | send, list, get, update, delete, thread reply, replies, search |
143
+ | `channel` | list, list --type, info |
144
+ | `user` | list, me, info |
145
+ | `reaction` | add, list, remove |
146
+ | `file` | upload, list, list --channel, info |
147
+ | `snapshot` | default, --channels-only, --users-only, --limit |
148
+
149
+ ### Discord Tests (20 tests)
150
+
151
+ | Command Group | Tests |
152
+ |---------------|-------|
153
+ | `auth` | status |
154
+ | `server` | list, current, info |
155
+ | `message` | send, list, get*, delete |
156
+ | `channel` | list, info, history |
157
+ | `user` | list, me, info* |
158
+ | `reaction` | add*, list*, remove* |
159
+ | `file` | upload, list |
160
+ | `snapshot` | default, --channels-only, --users-only |
161
+
162
+ \* Some Discord tests are skipped because they require Bot Token permissions not available to user tokens.
163
+
164
+ ## Troubleshooting
165
+
166
+ ### "Wrong workspace" / "Wrong server" Error
167
+
168
+ The tests detected you're not in the designated test workspace:
169
+
170
+ ```
171
+ Error: Wrong Slack workspace. Expected: Agent Messenger (T0AC55BSF6E), Got: My Company (TXXXXXX)
172
+ ```
173
+
174
+ **Solution**: Switch to the correct test workspace before running tests.
175
+
176
+ ### Authentication Failed
177
+
178
+ ```
179
+ Error: Slack authentication failed. Please run: agent-messenger slack auth login
180
+ ```
181
+
182
+ **Solution**:
183
+ 1. Make sure the desktop app is running
184
+ 2. Run `agent-slack auth extract` or `agent-discord auth extract`
185
+ 3. For CI, check that secrets are correctly configured
186
+
187
+ ### Rate Limiting
188
+
189
+ If tests fail intermittently with rate limit errors, try running fewer tests at once:
190
+
191
+ ```bash
192
+ bun test e2e/slack.e2e.test.ts --test-name-pattern "auth"
193
+ ```
194
+
195
+ The test harness includes automatic delays between API calls, but heavy testing may still hit limits.
196
+
197
+ ### Orphaned Test Messages
198
+
199
+ If tests crash before cleanup, you may have leftover messages in the `e2e-test` channel. Clean them up manually:
200
+
201
+ ```bash
202
+ # List recent messages
203
+ agent-slack message list e2e-test --limit 20 --pretty
204
+
205
+ # Delete specific message
206
+ agent-slack message delete e2e-test <timestamp> --force
207
+ ```
208
+
209
+ ### CI Environment Variables Not Working
210
+
211
+ Verify the credential managers are reading env vars:
212
+
213
+ ```bash
214
+ # Test locally with env vars
215
+ E2E_SLACK_TOKEN=xoxc-test E2E_SLACK_COOKIE=xoxd-test bun -e "
216
+ import { CredentialManager } from './src/platforms/slack/credential-manager.ts';
217
+ const cm = new CredentialManager();
218
+ const creds = await cm.getWorkspace();
219
+ console.log(creds);
220
+ "
221
+ ```
222
+
223
+ If this shows your test credentials, env var support is working.
224
+
225
+ ## Safety Features
226
+
227
+ 1. **Hardcoded Test IDs**: Test workspace/server IDs are hardcoded in `config.ts`. Tests will refuse to run against other workspaces.
228
+
229
+ 2. **Environment Validation**: Before any write operations, tests call `validateSlackEnvironment()` or `validateDiscordEnvironment()` to verify the correct workspace.
230
+
231
+ 3. **Automatic Cleanup**: Tests track created messages and delete them in `afterEach` hooks.
232
+
233
+ 4. **Rate Limiting**: Built-in delays between API calls prevent hitting rate limits.
234
+
235
+ ## Adding New Tests
236
+
237
+ 1. Follow existing patterns in `slack.e2e.test.ts` or `discord.e2e.test.ts`
238
+ 2. Use helpers from `helpers.ts` for CLI execution
239
+ 3. Track created resources for cleanup in `afterEach`
240
+ 4. Add appropriate delays with `waitForRateLimit()`
241
+
242
+ Example:
243
+
244
+ ```typescript
245
+ test('my new test', async () => {
246
+ const testId = generateTestId()
247
+ const { id } = await createTestMessage('slack', SLACK_TEST_CHANNEL_ID, `Test ${testId}`)
248
+ testMessages.push(id) // Track for cleanup
249
+
250
+ await waitForRateLimit()
251
+
252
+ // Your test assertions here
253
+ const result = await runCLI('slack', ['some', 'command', id])
254
+ expect(result.exitCode).toBe(0)
255
+ })
256
+ ```
package/e2e/config.ts ADDED
@@ -0,0 +1,51 @@
1
+ export const SLACK_TEST_WORKSPACE_ID = 'T0AC55BSF6E'
2
+ export const SLACK_TEST_WORKSPACE_NAME = 'Agent Messenger'
3
+ export const SLACK_TEST_CHANNEL_ID = 'C0ACZKTDDC0'
4
+ export const SLACK_TEST_CHANNEL = 'e2e-test'
5
+
6
+ // Discord Test Environment
7
+ export const DISCORD_TEST_SERVER_ID = '1467039439770357844'
8
+ export const DISCORD_TEST_SERVER_NAME = 'Agent Messenger'
9
+ export const DISCORD_TEST_CHANNEL_ID = '1467062262996144162'
10
+ export const DISCORD_TEST_CHANNEL = 'e2e-test'
11
+
12
+ export async function validateSlackEnvironment() {
13
+ const { runCLI, parseJSON } = await import('./helpers')
14
+
15
+ const result = await runCLI('slack', ['auth', 'status'])
16
+ if (result.exitCode !== 0) {
17
+ throw new Error('Slack authentication failed. Please run: agent-messenger slack auth login')
18
+ }
19
+
20
+ const data = parseJSON<{ workspace_id: string; workspace_name: string }>(result.stdout)
21
+ if (data?.workspace_id !== SLACK_TEST_WORKSPACE_ID) {
22
+ const switchResult = await runCLI('slack', ['workspace', 'switch', SLACK_TEST_WORKSPACE_ID])
23
+ if (switchResult.exitCode !== 0) {
24
+ throw new Error(
25
+ `Failed to switch to test workspace. Expected: ${SLACK_TEST_WORKSPACE_NAME} (${SLACK_TEST_WORKSPACE_ID}). ` +
26
+ `Make sure you have access to the test workspace.`
27
+ )
28
+ }
29
+ }
30
+ }
31
+
32
+ export async function validateDiscordEnvironment() {
33
+ const { runCLI, parseJSON } = await import('./helpers')
34
+
35
+ const result = await runCLI('discord', ['auth', 'status'])
36
+ if (result.exitCode !== 0) {
37
+ throw new Error('Discord authentication failed. Please run: agent-messenger discord auth login')
38
+ }
39
+
40
+ const currentResult = await runCLI('discord', ['server', 'current'])
41
+ const data = parseJSON<{ server_id: string; server_name: string }>(currentResult.stdout)
42
+ if (data?.server_id !== DISCORD_TEST_SERVER_ID) {
43
+ const switchResult = await runCLI('discord', ['server', 'switch', DISCORD_TEST_SERVER_ID])
44
+ if (switchResult.exitCode !== 0) {
45
+ throw new Error(
46
+ `Failed to switch to test server. Expected: ${DISCORD_TEST_SERVER_NAME} (${DISCORD_TEST_SERVER_ID}). ` +
47
+ `Make sure you have access to the test server.`
48
+ )
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,252 @@
1
+ import { describe, test, expect, beforeAll, afterEach } from 'bun:test'
2
+ import {
3
+ runCLI, parseJSON, generateTestId, createTestMessage,
4
+ deleteTestMessage, waitForRateLimit, cleanupMessages
5
+ } from './helpers'
6
+ import {
7
+ DISCORD_TEST_CHANNEL_ID,
8
+ DISCORD_TEST_SERVER_ID,
9
+ validateDiscordEnvironment
10
+ } from './config'
11
+
12
+ // Track messages created during tests for cleanup
13
+ let testMessages: string[] = []
14
+
15
+ describe('Discord E2E Tests', () => {
16
+ beforeAll(async () => {
17
+ await validateDiscordEnvironment()
18
+ })
19
+
20
+ afterEach(async () => {
21
+ if (testMessages.length > 0) {
22
+ await cleanupMessages('discord', DISCORD_TEST_CHANNEL_ID, testMessages)
23
+ testMessages = []
24
+ }
25
+ await waitForRateLimit()
26
+ })
27
+
28
+ describe('auth', () => {
29
+ test('auth status returns authenticated status', async () => {
30
+ const result = await runCLI('discord', ['auth', 'status'])
31
+ expect(result.exitCode).toBe(0)
32
+
33
+ const data = parseJSON<{ authenticated: boolean }>(result.stdout)
34
+ expect(data?.authenticated).toBe(true)
35
+ })
36
+ })
37
+
38
+ describe('server', () => {
39
+ test('server list returns array', async () => {
40
+ const result = await runCLI('discord', ['server', 'list'])
41
+ expect(result.exitCode).toBe(0)
42
+
43
+ const data = parseJSON<Array<{ server_id: string }>>(result.stdout)
44
+ expect(Array.isArray(data)).toBe(true)
45
+ })
46
+
47
+ test('server current returns current server', async () => {
48
+ const result = await runCLI('discord', ['server', 'current'])
49
+ expect(result.exitCode).toBe(0)
50
+
51
+ const data = parseJSON<{ server_id: string }>(result.stdout)
52
+ expect(data?.server_id).toBe(DISCORD_TEST_SERVER_ID)
53
+ })
54
+
55
+ test('server info returns server details', async () => {
56
+ const result = await runCLI('discord', ['server', 'info', DISCORD_TEST_SERVER_ID])
57
+ expect(result.exitCode).toBe(0)
58
+
59
+ const data = parseJSON<{ id: string }>(result.stdout)
60
+ expect(data?.id).toBeTruthy()
61
+ })
62
+ })
63
+
64
+ describe('message', () => {
65
+ test('message send creates message', async () => {
66
+ const testId = generateTestId()
67
+ const result = await runCLI('discord', ['message', 'send', DISCORD_TEST_CHANNEL_ID, `Test message ${testId}`])
68
+ expect(result.exitCode).toBe(0)
69
+
70
+ const data = parseJSON<{ id: string }>(result.stdout)
71
+ expect(data?.id).toBeTruthy()
72
+
73
+ if (data?.id) testMessages.push(data.id)
74
+ })
75
+
76
+ test('message list returns messages array', async () => {
77
+ const result = await runCLI('discord', ['message', 'list', DISCORD_TEST_CHANNEL_ID, '--limit', '5'])
78
+ expect(result.exitCode).toBe(0)
79
+
80
+ const data = parseJSON<Array<{ id: string }>>(result.stdout)
81
+ expect(Array.isArray(data)).toBe(true)
82
+ })
83
+
84
+ test.skip('message get retrieves specific message (requires bot token)', async () => {
85
+ const testId = generateTestId()
86
+ const { id } = await createTestMessage('discord', DISCORD_TEST_CHANNEL_ID, `Get test ${testId}`)
87
+ testMessages.push(id)
88
+
89
+ await waitForRateLimit()
90
+
91
+ const result = await runCLI('discord', ['message', 'get', DISCORD_TEST_CHANNEL_ID, id])
92
+ expect(result.exitCode).toBe(0)
93
+
94
+ const data = parseJSON<{ content: string }>(result.stdout)
95
+ expect(data?.content).toContain(testId)
96
+ })
97
+
98
+ test('message delete removes message', async () => {
99
+ const testId = generateTestId()
100
+ const { id } = await createTestMessage('discord', DISCORD_TEST_CHANNEL_ID, `Delete me ${testId}`)
101
+
102
+ await waitForRateLimit()
103
+
104
+ const result = await runCLI('discord', ['message', 'delete', DISCORD_TEST_CHANNEL_ID, id, '--force'])
105
+ expect(result.exitCode).toBe(0)
106
+ })
107
+ })
108
+
109
+ describe('channel', () => {
110
+ test('channel list returns channels array', async () => {
111
+ const result = await runCLI('discord', ['channel', 'list'])
112
+ expect(result.exitCode).toBe(0)
113
+
114
+ const data = parseJSON<Array<{ id: string }>>(result.stdout)
115
+ expect(Array.isArray(data)).toBe(true)
116
+ })
117
+
118
+ test('channel info returns channel details', async () => {
119
+ const result = await runCLI('discord', ['channel', 'info', DISCORD_TEST_CHANNEL_ID])
120
+ expect(result.exitCode).toBe(0)
121
+
122
+ const data = parseJSON<{ id: string }>(result.stdout)
123
+ expect(data?.id).toBe(DISCORD_TEST_CHANNEL_ID)
124
+ })
125
+
126
+ test('channel history returns messages', async () => {
127
+ const result = await runCLI('discord', ['channel', 'history', DISCORD_TEST_CHANNEL_ID, '--limit', '5'])
128
+ expect(result.exitCode).toBe(0)
129
+
130
+ const data = parseJSON<Array<{ id: string }>>(result.stdout)
131
+ expect(Array.isArray(data)).toBe(true)
132
+ })
133
+ })
134
+
135
+ describe('user', () => {
136
+ test.skip('user list returns users array (requires bot token)', async () => {
137
+ const result = await runCLI('discord', ['user', 'list'])
138
+ expect(result.exitCode).toBe(0)
139
+
140
+ const data = parseJSON<Array<{ id: string }>>(result.stdout)
141
+ expect(Array.isArray(data)).toBe(true)
142
+ })
143
+
144
+ test('user me returns current user', async () => {
145
+ const result = await runCLI('discord', ['user', 'me'])
146
+ expect(result.exitCode).toBe(0)
147
+
148
+ const data = parseJSON<{ id: string; username: string }>(result.stdout)
149
+ expect(data?.id).toBeTruthy()
150
+ expect(data?.username).toBeTruthy()
151
+ })
152
+
153
+ test('user info returns user details', async () => {
154
+ // First get current user ID
155
+ const meResult = await runCLI('discord', ['user', 'me'])
156
+ expect(meResult.exitCode).toBe(0)
157
+
158
+ const me = parseJSON<{ id: string }>(meResult.stdout)
159
+ expect(me?.id).toBeTruthy()
160
+
161
+ await waitForRateLimit()
162
+
163
+ const result = await runCLI('discord', ['user', 'info', me!.id])
164
+ expect(result.exitCode).toBe(0)
165
+
166
+ const data = parseJSON<{ id: string }>(result.stdout)
167
+ expect(data?.id).toBe(me?.id)
168
+ })
169
+ })
170
+
171
+ describe('reaction', () => {
172
+ test.skip('reaction add/list/remove lifecycle (requires bot token)', async () => {
173
+ const testId = generateTestId()
174
+ const { id } = await createTestMessage('discord', DISCORD_TEST_CHANNEL_ID, `Reaction test ${testId}`)
175
+ testMessages.push(id)
176
+
177
+ await waitForRateLimit()
178
+
179
+ // Add reaction (using emoji name without colons)
180
+ const addResult = await runCLI('discord', ['reaction', 'add', DISCORD_TEST_CHANNEL_ID, id, '👍'])
181
+ expect(addResult.exitCode).toBe(0)
182
+
183
+ await waitForRateLimit()
184
+
185
+ // List reactions
186
+ const listResult = await runCLI('discord', ['reaction', 'list', DISCORD_TEST_CHANNEL_ID, id])
187
+ expect(listResult.exitCode).toBe(0)
188
+
189
+ await waitForRateLimit()
190
+
191
+ // Remove reaction
192
+ const removeResult = await runCLI('discord', ['reaction', 'remove', DISCORD_TEST_CHANNEL_ID, id, '👍'])
193
+ expect(removeResult.exitCode).toBe(0)
194
+ }, 15000) // Longer timeout for multiple operations
195
+ })
196
+
197
+ describe('file', () => {
198
+ test('file list returns files array', async () => {
199
+ const result = await runCLI('discord', ['file', 'list', DISCORD_TEST_CHANNEL_ID])
200
+ expect(result.exitCode).toBe(0)
201
+
202
+ const data = parseJSON<Array<{ id: string }>>(result.stdout)
203
+ expect(Array.isArray(data)).toBe(true)
204
+ })
205
+
206
+ test('file upload uploads file', async () => {
207
+ const testId = generateTestId()
208
+ const testFilePath = `/tmp/discord-e2e-${testId}.txt`
209
+ await Bun.write(testFilePath, `Discord E2E test file ${testId}`)
210
+
211
+ try {
212
+ const result = await runCLI('discord', ['file', 'upload', DISCORD_TEST_CHANNEL_ID, testFilePath])
213
+ expect(result.exitCode).toBe(0)
214
+
215
+ const data = parseJSON<{ id: string }>(result.stdout)
216
+ expect(data?.id).toBeTruthy()
217
+
218
+ // Track message for cleanup (file uploads create messages)
219
+ if (data?.id) testMessages.push(data.id)
220
+ } finally {
221
+ await Bun.$`rm -f ${testFilePath}`.quiet()
222
+ }
223
+ })
224
+ })
225
+
226
+ describe('snapshot', () => {
227
+ test.skip('snapshot returns full server data (requires bot token)', async () => {
228
+ const result = await runCLI('discord', ['snapshot', '--limit', '2'])
229
+ expect(result.exitCode).toBe(0)
230
+
231
+ const data = parseJSON<{ channels: unknown[]; users: unknown[] }>(result.stdout)
232
+ expect(data?.channels).toBeDefined()
233
+ expect(data?.users).toBeDefined()
234
+ })
235
+
236
+ test('snapshot --channels-only returns only channels', async () => {
237
+ const result = await runCLI('discord', ['snapshot', '--channels-only'])
238
+ expect(result.exitCode).toBe(0)
239
+
240
+ const data = parseJSON<{ channels: unknown[] }>(result.stdout)
241
+ expect(data?.channels).toBeDefined()
242
+ })
243
+
244
+ test.skip('snapshot --users-only returns only users (requires bot token)', async () => {
245
+ const result = await runCLI('discord', ['snapshot', '--users-only'])
246
+ expect(result.exitCode).toBe(0)
247
+
248
+ const data = parseJSON<{ users: unknown[] }>(result.stdout)
249
+ expect(data?.users).toBeDefined()
250
+ })
251
+ })
252
+ })
package/e2e/helpers.ts ADDED
@@ -0,0 +1,107 @@
1
+ import { $ } from 'bun'
2
+
3
+ export interface CLIResult {
4
+ exitCode: number
5
+ stdout: string
6
+ stderr: string
7
+ }
8
+
9
+ export async function runCLI(platform: string, args: string[]): Promise<CLIResult> {
10
+ const command = platform === 'slack' ? 'agent-slack' : 'agent-discord'
11
+
12
+ try {
13
+ const result = await $`${command} ${args}`.quiet()
14
+ return {
15
+ exitCode: result.exitCode,
16
+ stdout: result.stdout.toString(),
17
+ stderr: result.stderr.toString(),
18
+ }
19
+ } catch (error: any) {
20
+ return {
21
+ exitCode: error.exitCode || 1,
22
+ stdout: error.stdout?.toString() || '',
23
+ stderr: error.stderr?.toString() || '',
24
+ }
25
+ }
26
+ }
27
+
28
+ export function parseJSON<T>(output: string): T | null {
29
+ try {
30
+ return JSON.parse(output) as T
31
+ } catch {
32
+ return null
33
+ }
34
+ }
35
+
36
+ export function generateTestId(): string {
37
+ return `e2e-${Date.now()}-${Math.random().toString(36).substring(7)}`
38
+ }
39
+
40
+ export async function createTestMessage(
41
+ platform: string,
42
+ channel: string,
43
+ text: string
44
+ ): Promise<{ id: string }> {
45
+ const result = await runCLI(platform, ['message', 'send', channel, text])
46
+ if (result.exitCode !== 0) {
47
+ throw new Error(`Failed to create test message: ${result.stderr}`)
48
+ }
49
+
50
+ const data = parseJSON<{ ts?: string; id?: string }>(result.stdout)
51
+ const messageId = data?.ts || data?.id
52
+ if (!messageId) {
53
+ throw new Error('No message ID returned')
54
+ }
55
+
56
+ return { id: messageId }
57
+ }
58
+
59
+ export async function deleteTestMessage(
60
+ platform: string,
61
+ channel: string,
62
+ messageId: string
63
+ ): Promise<void> {
64
+ // For Slack, check for thread replies and delete them first
65
+ if (platform === 'slack') {
66
+ try {
67
+ const repliesResult = await runCLI(platform, ['message', 'replies', channel, messageId])
68
+ if (repliesResult.exitCode === 0) {
69
+ const replies = parseJSON<Array<{ ts?: string; id?: string }>>(repliesResult.stdout)
70
+ if (replies && replies.length > 0) {
71
+ // Delete replies in reverse order (newest first), skip parent
72
+ const threadReplies = replies.filter(r => (r.ts || r.id) !== messageId)
73
+ for (const reply of threadReplies.reverse()) {
74
+ const replyId = reply.ts || reply.id
75
+ if (replyId) {
76
+ await runCLI(platform, ['message', 'delete', channel, replyId, '--force'])
77
+ }
78
+ }
79
+ }
80
+ }
81
+ } catch {
82
+ // Continue with parent deletion even if replies fail
83
+ }
84
+ }
85
+
86
+ // Delete the parent message
87
+ await runCLI(platform, ['message', 'delete', channel, messageId, '--force'])
88
+ }
89
+
90
+ export async function waitForRateLimit(ms: number = 1000): Promise<void> {
91
+ await new Promise(resolve => setTimeout(resolve, ms))
92
+ }
93
+
94
+ export async function cleanupMessages(
95
+ platform: string,
96
+ channel: string,
97
+ messageIds: string[]
98
+ ): Promise<void> {
99
+ for (const id of messageIds) {
100
+ try {
101
+ await deleteTestMessage(platform, channel, id)
102
+ await waitForRateLimit(500)
103
+ } catch (error) {
104
+ console.warn(`Failed to cleanup message ${id}:`, error)
105
+ }
106
+ }
107
+ }