agent-messenger 1.0.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 (394) hide show
  1. package/.claude/commands/release.md +92 -0
  2. package/.claude-plugin/README.md +144 -0
  3. package/.claude-plugin/marketplace.json +37 -0
  4. package/.claude-plugin/plugin.json +17 -0
  5. package/.github/workflows/ci.yml +30 -0
  6. package/CLAUDE.md +106 -0
  7. package/CONTRIBUTING.md +131 -0
  8. package/README.md +140 -0
  9. package/biome.json +34 -0
  10. package/bun.lock +252 -0
  11. package/dist/cli.d.ts +5 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +21 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/commands/auth.d.ts +3 -0
  16. package/dist/commands/auth.d.ts.map +1 -0
  17. package/dist/commands/auth.js +140 -0
  18. package/dist/commands/auth.js.map +1 -0
  19. package/dist/commands/channel.d.ts +3 -0
  20. package/dist/commands/channel.d.ts.map +1 -0
  21. package/dist/commands/channel.js +118 -0
  22. package/dist/commands/channel.js.map +1 -0
  23. package/dist/commands/file.d.ts +3 -0
  24. package/dist/commands/file.d.ts.map +1 -0
  25. package/dist/commands/file.js +113 -0
  26. package/dist/commands/file.js.map +1 -0
  27. package/dist/commands/index.d.ts +9 -0
  28. package/dist/commands/index.d.ts.map +1 -0
  29. package/dist/commands/index.js +9 -0
  30. package/dist/commands/index.js.map +1 -0
  31. package/dist/commands/message.d.ts +3 -0
  32. package/dist/commands/message.d.ts.map +1 -0
  33. package/dist/commands/message.js +214 -0
  34. package/dist/commands/message.js.map +1 -0
  35. package/dist/commands/reaction.d.ts +3 -0
  36. package/dist/commands/reaction.d.ts.map +1 -0
  37. package/dist/commands/reaction.js +100 -0
  38. package/dist/commands/reaction.js.map +1 -0
  39. package/dist/commands/snapshot.d.ts +3 -0
  40. package/dist/commands/snapshot.d.ts.map +1 -0
  41. package/dist/commands/snapshot.js +88 -0
  42. package/dist/commands/snapshot.js.map +1 -0
  43. package/dist/commands/user.d.ts +3 -0
  44. package/dist/commands/user.d.ts.map +1 -0
  45. package/dist/commands/user.js +96 -0
  46. package/dist/commands/user.js.map +1 -0
  47. package/dist/commands/workspace.d.ts +3 -0
  48. package/dist/commands/workspace.d.ts.map +1 -0
  49. package/dist/commands/workspace.js +89 -0
  50. package/dist/commands/workspace.js.map +1 -0
  51. package/dist/lib/credential-manager.d.ts +13 -0
  52. package/dist/lib/credential-manager.d.ts.map +1 -0
  53. package/dist/lib/credential-manager.js +58 -0
  54. package/dist/lib/credential-manager.js.map +1 -0
  55. package/dist/lib/index.d.ts +3 -0
  56. package/dist/lib/index.d.ts.map +1 -0
  57. package/dist/lib/index.js +3 -0
  58. package/dist/lib/index.js.map +1 -0
  59. package/dist/lib/ref-manager.d.ts +26 -0
  60. package/dist/lib/ref-manager.d.ts.map +1 -0
  61. package/dist/lib/ref-manager.js +92 -0
  62. package/dist/lib/ref-manager.js.map +1 -0
  63. package/dist/lib/slack-client.d.ts +37 -0
  64. package/dist/lib/slack-client.d.ts.map +1 -0
  65. package/dist/lib/slack-client.js +379 -0
  66. package/dist/lib/slack-client.js.map +1 -0
  67. package/dist/lib/token-extractor.d.ts +28 -0
  68. package/dist/lib/token-extractor.d.ts.map +1 -0
  69. package/dist/lib/token-extractor.js +401 -0
  70. package/dist/lib/token-extractor.js.map +1 -0
  71. package/dist/package.json +37 -0
  72. package/dist/src/cli.d.ts +5 -0
  73. package/dist/src/cli.d.ts.map +1 -0
  74. package/dist/src/cli.js +22 -0
  75. package/dist/src/cli.js.map +1 -0
  76. package/dist/src/platforms/discord/cli.d.ts +5 -0
  77. package/dist/src/platforms/discord/cli.d.ts.map +1 -0
  78. package/dist/src/platforms/discord/cli.js +22 -0
  79. package/dist/src/platforms/discord/cli.js.map +1 -0
  80. package/dist/src/platforms/discord/client.d.ts +34 -0
  81. package/dist/src/platforms/discord/client.d.ts.map +1 -0
  82. package/dist/src/platforms/discord/client.js +187 -0
  83. package/dist/src/platforms/discord/client.js.map +1 -0
  84. package/dist/src/platforms/discord/client.test.d.ts +2 -0
  85. package/dist/src/platforms/discord/client.test.d.ts.map +1 -0
  86. package/dist/src/platforms/discord/client.test.js +367 -0
  87. package/dist/src/platforms/discord/client.test.js.map +1 -0
  88. package/dist/src/platforms/discord/commands/auth.d.ts +13 -0
  89. package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -0
  90. package/dist/src/platforms/discord/commands/auth.js +155 -0
  91. package/dist/src/platforms/discord/commands/auth.js.map +1 -0
  92. package/dist/src/platforms/discord/commands/auth.test.d.ts +2 -0
  93. package/dist/src/platforms/discord/commands/auth.test.d.ts.map +1 -0
  94. package/dist/src/platforms/discord/commands/auth.test.js +65 -0
  95. package/dist/src/platforms/discord/commands/auth.test.js.map +1 -0
  96. package/dist/src/platforms/discord/commands/channel.d.ts +13 -0
  97. package/dist/src/platforms/discord/commands/channel.d.ts.map +1 -0
  98. package/dist/src/platforms/discord/commands/channel.js +99 -0
  99. package/dist/src/platforms/discord/commands/channel.js.map +1 -0
  100. package/dist/src/platforms/discord/commands/channel.test.d.ts +2 -0
  101. package/dist/src/platforms/discord/commands/channel.test.d.ts.map +1 -0
  102. package/dist/src/platforms/discord/commands/channel.test.js +136 -0
  103. package/dist/src/platforms/discord/commands/channel.test.js.map +1 -0
  104. package/dist/src/platforms/discord/commands/file.d.ts +13 -0
  105. package/dist/src/platforms/discord/commands/file.d.ts.map +1 -0
  106. package/dist/src/platforms/discord/commands/file.js +99 -0
  107. package/dist/src/platforms/discord/commands/file.js.map +1 -0
  108. package/dist/src/platforms/discord/commands/file.test.d.ts +2 -0
  109. package/dist/src/platforms/discord/commands/file.test.d.ts.map +1 -0
  110. package/dist/src/platforms/discord/commands/file.test.js +83 -0
  111. package/dist/src/platforms/discord/commands/file.test.js.map +1 -0
  112. package/dist/src/platforms/discord/commands/guild.d.ts +15 -0
  113. package/dist/src/platforms/discord/commands/guild.d.ts.map +1 -0
  114. package/dist/src/platforms/discord/commands/guild.js +102 -0
  115. package/dist/src/platforms/discord/commands/guild.js.map +1 -0
  116. package/dist/src/platforms/discord/commands/guild.test.d.ts +2 -0
  117. package/dist/src/platforms/discord/commands/guild.test.d.ts.map +1 -0
  118. package/dist/src/platforms/discord/commands/guild.test.js +100 -0
  119. package/dist/src/platforms/discord/commands/guild.test.js.map +1 -0
  120. package/dist/src/platforms/discord/commands/index.d.ts +9 -0
  121. package/dist/src/platforms/discord/commands/index.d.ts.map +1 -0
  122. package/dist/src/platforms/discord/commands/index.js +9 -0
  123. package/dist/src/platforms/discord/commands/index.js.map +1 -0
  124. package/dist/src/platforms/discord/commands/message.d.ts +17 -0
  125. package/dist/src/platforms/discord/commands/message.d.ts.map +1 -0
  126. package/dist/src/platforms/discord/commands/message.js +131 -0
  127. package/dist/src/platforms/discord/commands/message.js.map +1 -0
  128. package/dist/src/platforms/discord/commands/message.test.d.ts +2 -0
  129. package/dist/src/platforms/discord/commands/message.test.d.ts.map +1 -0
  130. package/dist/src/platforms/discord/commands/message.test.js +91 -0
  131. package/dist/src/platforms/discord/commands/message.test.js.map +1 -0
  132. package/dist/src/platforms/discord/commands/reaction.d.ts +12 -0
  133. package/dist/src/platforms/discord/commands/reaction.d.ts.map +1 -0
  134. package/dist/src/platforms/discord/commands/reaction.js +99 -0
  135. package/dist/src/platforms/discord/commands/reaction.js.map +1 -0
  136. package/dist/src/platforms/discord/commands/reaction.test.d.ts +2 -0
  137. package/dist/src/platforms/discord/commands/reaction.test.d.ts.map +1 -0
  138. package/dist/src/platforms/discord/commands/reaction.test.js +115 -0
  139. package/dist/src/platforms/discord/commands/reaction.test.js.map +1 -0
  140. package/dist/src/platforms/discord/commands/snapshot.d.ts +9 -0
  141. package/dist/src/platforms/discord/commands/snapshot.d.ts.map +1 -0
  142. package/dist/src/platforms/discord/commands/snapshot.js +80 -0
  143. package/dist/src/platforms/discord/commands/snapshot.js.map +1 -0
  144. package/dist/src/platforms/discord/commands/snapshot.test.d.ts +2 -0
  145. package/dist/src/platforms/discord/commands/snapshot.test.d.ts.map +1 -0
  146. package/dist/src/platforms/discord/commands/snapshot.test.js +25 -0
  147. package/dist/src/platforms/discord/commands/snapshot.test.js.map +1 -0
  148. package/dist/src/platforms/discord/commands/user.d.ts +3 -0
  149. package/dist/src/platforms/discord/commands/user.d.ts.map +1 -0
  150. package/dist/src/platforms/discord/commands/user.js +94 -0
  151. package/dist/src/platforms/discord/commands/user.js.map +1 -0
  152. package/dist/src/platforms/discord/commands/user.test.d.ts +2 -0
  153. package/dist/src/platforms/discord/commands/user.test.d.ts.map +1 -0
  154. package/dist/src/platforms/discord/commands/user.test.js +103 -0
  155. package/dist/src/platforms/discord/commands/user.test.js.map +1 -0
  156. package/dist/src/platforms/discord/credential-manager.d.ts +33 -0
  157. package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -0
  158. package/dist/src/platforms/discord/credential-manager.js +73 -0
  159. package/dist/src/platforms/discord/credential-manager.js.map +1 -0
  160. package/dist/src/platforms/discord/credential-manager.test.d.ts +2 -0
  161. package/dist/src/platforms/discord/credential-manager.test.d.ts.map +1 -0
  162. package/dist/src/platforms/discord/credential-manager.test.js +136 -0
  163. package/dist/src/platforms/discord/credential-manager.test.js.map +1 -0
  164. package/dist/src/platforms/discord/token-extractor.d.ts +55 -0
  165. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -0
  166. package/dist/src/platforms/discord/token-extractor.js +462 -0
  167. package/dist/src/platforms/discord/token-extractor.js.map +1 -0
  168. package/dist/src/platforms/discord/token-extractor.test.d.ts +2 -0
  169. package/dist/src/platforms/discord/token-extractor.test.d.ts.map +1 -0
  170. package/dist/src/platforms/discord/token-extractor.test.js +789 -0
  171. package/dist/src/platforms/discord/token-extractor.test.js.map +1 -0
  172. package/dist/src/platforms/discord/types.d.ts +251 -0
  173. package/dist/src/platforms/discord/types.d.ts.map +1 -0
  174. package/dist/src/platforms/discord/types.js +74 -0
  175. package/dist/src/platforms/discord/types.js.map +1 -0
  176. package/dist/src/platforms/discord/types.test.d.ts +2 -0
  177. package/dist/src/platforms/discord/types.test.d.ts.map +1 -0
  178. package/dist/src/platforms/discord/types.test.js +211 -0
  179. package/dist/src/platforms/discord/types.test.js.map +1 -0
  180. package/dist/src/platforms/slack/cli.d.ts +5 -0
  181. package/dist/src/platforms/slack/cli.d.ts.map +1 -0
  182. package/dist/src/platforms/slack/cli.js +22 -0
  183. package/dist/src/platforms/slack/cli.js.map +1 -0
  184. package/dist/src/platforms/slack/client.d.ts +47 -0
  185. package/dist/src/platforms/slack/client.d.ts.map +1 -0
  186. package/dist/src/platforms/slack/client.js +412 -0
  187. package/dist/src/platforms/slack/client.js.map +1 -0
  188. package/dist/src/platforms/slack/commands/auth.d.ts +3 -0
  189. package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -0
  190. package/dist/src/platforms/slack/commands/auth.js +156 -0
  191. package/dist/src/platforms/slack/commands/auth.js.map +1 -0
  192. package/dist/src/platforms/slack/commands/channel.d.ts +3 -0
  193. package/dist/src/platforms/slack/commands/channel.d.ts.map +1 -0
  194. package/dist/src/platforms/slack/commands/channel.js +118 -0
  195. package/dist/src/platforms/slack/commands/channel.js.map +1 -0
  196. package/dist/src/platforms/slack/commands/file.d.ts +3 -0
  197. package/dist/src/platforms/slack/commands/file.d.ts.map +1 -0
  198. package/dist/src/platforms/slack/commands/file.js +113 -0
  199. package/dist/src/platforms/slack/commands/file.js.map +1 -0
  200. package/dist/src/platforms/slack/commands/index.d.ts +9 -0
  201. package/dist/src/platforms/slack/commands/index.d.ts.map +1 -0
  202. package/dist/src/platforms/slack/commands/index.js +9 -0
  203. package/dist/src/platforms/slack/commands/index.js.map +1 -0
  204. package/dist/src/platforms/slack/commands/message.d.ts +3 -0
  205. package/dist/src/platforms/slack/commands/message.d.ts.map +1 -0
  206. package/dist/src/platforms/slack/commands/message.js +263 -0
  207. package/dist/src/platforms/slack/commands/message.js.map +1 -0
  208. package/dist/src/platforms/slack/commands/reaction.d.ts +3 -0
  209. package/dist/src/platforms/slack/commands/reaction.d.ts.map +1 -0
  210. package/dist/src/platforms/slack/commands/reaction.js +100 -0
  211. package/dist/src/platforms/slack/commands/reaction.js.map +1 -0
  212. package/dist/src/platforms/slack/commands/snapshot.d.ts +3 -0
  213. package/dist/src/platforms/slack/commands/snapshot.d.ts.map +1 -0
  214. package/dist/src/platforms/slack/commands/snapshot.js +87 -0
  215. package/dist/src/platforms/slack/commands/snapshot.js.map +1 -0
  216. package/dist/src/platforms/slack/commands/user.d.ts +3 -0
  217. package/dist/src/platforms/slack/commands/user.d.ts.map +1 -0
  218. package/dist/src/platforms/slack/commands/user.js +96 -0
  219. package/dist/src/platforms/slack/commands/user.js.map +1 -0
  220. package/dist/src/platforms/slack/commands/workspace.d.ts +3 -0
  221. package/dist/src/platforms/slack/commands/workspace.d.ts.map +1 -0
  222. package/dist/src/platforms/slack/commands/workspace.js +89 -0
  223. package/dist/src/platforms/slack/commands/workspace.js.map +1 -0
  224. package/dist/src/platforms/slack/credential-manager.d.ts +13 -0
  225. package/dist/src/platforms/slack/credential-manager.d.ts.map +1 -0
  226. package/dist/src/platforms/slack/credential-manager.js +58 -0
  227. package/dist/src/platforms/slack/credential-manager.js.map +1 -0
  228. package/dist/src/platforms/slack/index.d.ts +3 -0
  229. package/dist/src/platforms/slack/index.d.ts.map +1 -0
  230. package/dist/src/platforms/slack/index.js +3 -0
  231. package/dist/src/platforms/slack/index.js.map +1 -0
  232. package/dist/src/platforms/slack/token-extractor.d.ts +28 -0
  233. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -0
  234. package/dist/src/platforms/slack/token-extractor.js +401 -0
  235. package/dist/src/platforms/slack/token-extractor.js.map +1 -0
  236. package/dist/src/platforms/slack/types.d.ts +369 -0
  237. package/dist/src/platforms/slack/types.d.ts.map +1 -0
  238. package/dist/src/platforms/slack/types.js +92 -0
  239. package/dist/src/platforms/slack/types.js.map +1 -0
  240. package/dist/src/shared/utils/concurrency.d.ts +2 -0
  241. package/dist/src/shared/utils/concurrency.d.ts.map +1 -0
  242. package/dist/src/shared/utils/concurrency.js +14 -0
  243. package/dist/src/shared/utils/concurrency.js.map +1 -0
  244. package/dist/src/shared/utils/concurrency.test.d.ts +2 -0
  245. package/dist/src/shared/utils/concurrency.test.d.ts.map +1 -0
  246. package/dist/src/shared/utils/concurrency.test.js +39 -0
  247. package/dist/src/shared/utils/concurrency.test.js.map +1 -0
  248. package/dist/src/shared/utils/error-handler.d.ts +2 -0
  249. package/dist/src/shared/utils/error-handler.d.ts.map +1 -0
  250. package/dist/src/shared/utils/error-handler.js +5 -0
  251. package/dist/src/shared/utils/error-handler.js.map +1 -0
  252. package/dist/src/shared/utils/output.d.ts +2 -0
  253. package/dist/src/shared/utils/output.d.ts.map +1 -0
  254. package/dist/src/shared/utils/output.js +4 -0
  255. package/dist/src/shared/utils/output.js.map +1 -0
  256. package/dist/tests/cli.test.d.ts +2 -0
  257. package/dist/tests/cli.test.d.ts.map +1 -0
  258. package/dist/tests/cli.test.js +83 -0
  259. package/dist/tests/cli.test.js.map +1 -0
  260. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/CURRENT +1 -0
  261. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOCK +0 -0
  262. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG +3 -0
  263. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG.old +1 -0
  264. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/MANIFEST-000004 +0 -0
  265. package/dist/tests/commands/auth.test.d.ts +2 -0
  266. package/dist/tests/commands/auth.test.d.ts.map +1 -0
  267. package/dist/tests/commands/auth.test.js +304 -0
  268. package/dist/tests/commands/auth.test.js.map +1 -0
  269. package/dist/tests/commands/channel.test.d.ts +2 -0
  270. package/dist/tests/commands/channel.test.d.ts.map +1 -0
  271. package/dist/tests/commands/channel.test.js +166 -0
  272. package/dist/tests/commands/channel.test.js.map +1 -0
  273. package/dist/tests/commands/file.test.d.ts +2 -0
  274. package/dist/tests/commands/file.test.d.ts.map +1 -0
  275. package/dist/tests/commands/file.test.js +175 -0
  276. package/dist/tests/commands/file.test.js.map +1 -0
  277. package/dist/tests/commands/message.test.d.ts +2 -0
  278. package/dist/tests/commands/message.test.d.ts.map +1 -0
  279. package/dist/tests/commands/message.test.js +293 -0
  280. package/dist/tests/commands/message.test.js.map +1 -0
  281. package/dist/tests/commands/reaction.test.d.ts +2 -0
  282. package/dist/tests/commands/reaction.test.d.ts.map +1 -0
  283. package/dist/tests/commands/reaction.test.js +84 -0
  284. package/dist/tests/commands/reaction.test.js.map +1 -0
  285. package/dist/tests/commands/snapshot.test.d.ts +2 -0
  286. package/dist/tests/commands/snapshot.test.d.ts.map +1 -0
  287. package/dist/tests/commands/snapshot.test.js +280 -0
  288. package/dist/tests/commands/snapshot.test.js.map +1 -0
  289. package/dist/tests/commands/user.test.d.ts +2 -0
  290. package/dist/tests/commands/user.test.d.ts.map +1 -0
  291. package/dist/tests/commands/user.test.js +117 -0
  292. package/dist/tests/commands/user.test.js.map +1 -0
  293. package/dist/tests/commands/workspace.test.d.ts +2 -0
  294. package/dist/tests/commands/workspace.test.d.ts.map +1 -0
  295. package/dist/tests/commands/workspace.test.js +453 -0
  296. package/dist/tests/commands/workspace.test.js.map +1 -0
  297. package/dist/tests/credential-manager.test.d.ts +2 -0
  298. package/dist/tests/credential-manager.test.d.ts.map +1 -0
  299. package/dist/tests/credential-manager.test.js +199 -0
  300. package/dist/tests/credential-manager.test.js.map +1 -0
  301. package/dist/tests/slack-client.test.d.ts +2 -0
  302. package/dist/tests/slack-client.test.d.ts.map +1 -0
  303. package/dist/tests/slack-client.test.js +741 -0
  304. package/dist/tests/slack-client.test.js.map +1 -0
  305. package/dist/tests/types.test.d.ts +2 -0
  306. package/dist/tests/types.test.d.ts.map +1 -0
  307. package/dist/tests/types.test.js +215 -0
  308. package/dist/tests/types.test.js.map +1 -0
  309. package/dist/types/index.d.ts +369 -0
  310. package/dist/types/index.d.ts.map +1 -0
  311. package/dist/types/index.js +92 -0
  312. package/dist/types/index.js.map +1 -0
  313. package/dist/utils/error-handler.d.ts +2 -0
  314. package/dist/utils/error-handler.d.ts.map +1 -0
  315. package/dist/utils/error-handler.js +5 -0
  316. package/dist/utils/error-handler.js.map +1 -0
  317. package/dist/utils/output.d.ts +2 -0
  318. package/dist/utils/output.d.ts.map +1 -0
  319. package/dist/utils/output.js +4 -0
  320. package/dist/utils/output.js.map +1 -0
  321. package/docs/discord.md +182 -0
  322. package/docs/slack.md +160 -0
  323. package/package.json +37 -0
  324. package/skills/agent-discord/SKILL.md +273 -0
  325. package/skills/agent-discord/references/authentication.md +294 -0
  326. package/skills/agent-discord/references/common-patterns.md +455 -0
  327. package/skills/agent-discord/templates/guild-summary.sh +167 -0
  328. package/skills/agent-discord/templates/monitor-channel.sh +180 -0
  329. package/skills/agent-discord/templates/post-message.sh +173 -0
  330. package/skills/agent-slack/SKILL.md +268 -0
  331. package/skills/agent-slack/references/authentication.md +332 -0
  332. package/skills/agent-slack/references/common-patterns.md +527 -0
  333. package/skills/agent-slack/templates/monitor-channel.sh +186 -0
  334. package/skills/agent-slack/templates/post-message.sh +130 -0
  335. package/skills/agent-slack/templates/workspace-summary.sh +149 -0
  336. package/src/cli.ts +29 -0
  337. package/src/platforms/discord/cli.ts +36 -0
  338. package/src/platforms/discord/client.test.ts +456 -0
  339. package/src/platforms/discord/client.ts +281 -0
  340. package/src/platforms/discord/commands/auth.test.ts +72 -0
  341. package/src/platforms/discord/commands/auth.ts +206 -0
  342. package/src/platforms/discord/commands/channel.test.ts +153 -0
  343. package/src/platforms/discord/commands/channel.ts +127 -0
  344. package/src/platforms/discord/commands/file.test.ts +98 -0
  345. package/src/platforms/discord/commands/file.ts +134 -0
  346. package/src/platforms/discord/commands/guild.test.ts +117 -0
  347. package/src/platforms/discord/commands/guild.ts +129 -0
  348. package/src/platforms/discord/commands/index.ts +8 -0
  349. package/src/platforms/discord/commands/message.test.ts +107 -0
  350. package/src/platforms/discord/commands/message.ts +182 -0
  351. package/src/platforms/discord/commands/reaction.test.ts +123 -0
  352. package/src/platforms/discord/commands/reaction.ts +156 -0
  353. package/src/platforms/discord/commands/snapshot.test.ts +29 -0
  354. package/src/platforms/discord/commands/snapshot.ts +104 -0
  355. package/src/platforms/discord/commands/user.test.ts +115 -0
  356. package/src/platforms/discord/commands/user.ts +124 -0
  357. package/src/platforms/discord/credential-manager.test.ts +173 -0
  358. package/src/platforms/discord/credential-manager.ts +95 -0
  359. package/src/platforms/discord/token-extractor.test.ts +918 -0
  360. package/src/platforms/discord/token-extractor.ts +549 -0
  361. package/src/platforms/discord/types.test.ts +245 -0
  362. package/src/platforms/discord/types.ts +158 -0
  363. package/src/platforms/slack/cli.ts +36 -0
  364. package/src/platforms/slack/client.ts +466 -0
  365. package/src/platforms/slack/commands/auth.ts +211 -0
  366. package/src/platforms/slack/commands/channel.ts +158 -0
  367. package/src/platforms/slack/commands/file.ts +153 -0
  368. package/src/platforms/slack/commands/index.ts +8 -0
  369. package/src/platforms/slack/commands/message.ts +369 -0
  370. package/src/platforms/slack/commands/reaction.ts +166 -0
  371. package/src/platforms/slack/commands/snapshot.ts +114 -0
  372. package/src/platforms/slack/commands/user.ts +110 -0
  373. package/src/platforms/slack/commands/workspace.ts +111 -0
  374. package/src/platforms/slack/credential-manager.ts +74 -0
  375. package/src/platforms/slack/index.ts +2 -0
  376. package/src/platforms/slack/token-extractor.ts +496 -0
  377. package/src/platforms/slack/types.ts +193 -0
  378. package/src/shared/utils/concurrency.test.ts +53 -0
  379. package/src/shared/utils/concurrency.ts +20 -0
  380. package/src/shared/utils/error-handler.ts +4 -0
  381. package/src/shared/utils/output.ts +3 -0
  382. package/tests/cli.test.ts +94 -0
  383. package/tests/commands/auth.test.ts +383 -0
  384. package/tests/commands/channel.test.ts +185 -0
  385. package/tests/commands/file.test.ts +204 -0
  386. package/tests/commands/message.test.ts +344 -0
  387. package/tests/commands/reaction.test.ts +101 -0
  388. package/tests/commands/snapshot.test.ts +308 -0
  389. package/tests/commands/user.test.ts +138 -0
  390. package/tests/commands/workspace.test.ts +528 -0
  391. package/tests/credential-manager.test.ts +241 -0
  392. package/tests/slack-client.test.ts +916 -0
  393. package/tests/types.test.ts +241 -0
  394. package/tsconfig.json +36 -0
@@ -0,0 +1,528 @@
1
+ import { afterAll, beforeEach, describe, expect, test } from 'bun:test'
2
+ import { rmSync } from 'node:fs'
3
+ import { join } from 'node:path'
4
+ import { CredentialManager } from '../../src/platforms/slack/credential-manager'
5
+ import type { WorkspaceCredentials } from '../../src/platforms/slack/types'
6
+
7
+ const testConfigDir = join(import.meta.dir, '.test-workspace-config')
8
+
9
+ describe('Workspace Commands', () => {
10
+ let credManager: CredentialManager
11
+
12
+ beforeEach(() => {
13
+ rmSync(testConfigDir, { recursive: true, force: true })
14
+ credManager = new CredentialManager(testConfigDir)
15
+ })
16
+
17
+ afterAll(() => {
18
+ rmSync(testConfigDir, { recursive: true, force: true })
19
+ })
20
+
21
+ describe('workspace list', () => {
22
+ test('returns empty list when no workspaces exist', async () => {
23
+ // Given: No workspaces configured
24
+ // When: Loading config
25
+ const config = await credManager.load()
26
+
27
+ // Then: Should have empty workspaces
28
+ expect(Object.keys(config.workspaces)).toHaveLength(0)
29
+ })
30
+
31
+ test('lists all workspaces with current marker', async () => {
32
+ // Given: Multiple workspaces with one as current
33
+ const ws1: WorkspaceCredentials = {
34
+ workspace_id: 'T123',
35
+ workspace_name: 'acme-corp',
36
+ token: 'xoxc-123',
37
+ cookie: 'xoxd-123',
38
+ }
39
+ const ws2: WorkspaceCredentials = {
40
+ workspace_id: 'T456',
41
+ workspace_name: 'side-project',
42
+ token: 'xoxc-456',
43
+ cookie: 'xoxd-456',
44
+ }
45
+
46
+ await credManager.setWorkspace(ws1)
47
+ await credManager.setWorkspace(ws2)
48
+ await credManager.setCurrentWorkspace('T123')
49
+
50
+ // When: Loading config
51
+ const config = await credManager.load()
52
+ const workspaces = Object.values(config.workspaces)
53
+
54
+ // Then: Should list all workspaces
55
+ expect(workspaces).toHaveLength(2)
56
+ expect(workspaces.map((w) => w.workspace_id)).toContain('T123')
57
+ expect(workspaces.map((w) => w.workspace_id)).toContain('T456')
58
+ expect(config.current_workspace).toBe('T123')
59
+ })
60
+
61
+ test('shows current marker for active workspace', async () => {
62
+ // Given: Workspace set as current
63
+ const ws: WorkspaceCredentials = {
64
+ workspace_id: 'T789',
65
+ workspace_name: 'current-ws',
66
+ token: 'xoxc-789',
67
+ cookie: 'xoxd-789',
68
+ }
69
+ await credManager.setWorkspace(ws)
70
+ await credManager.setCurrentWorkspace('T789')
71
+
72
+ // When: Loading config
73
+ const config = await credManager.load()
74
+
75
+ // Then: Current workspace should match
76
+ expect(config.current_workspace).toBe('T789')
77
+ expect(config.workspaces.T789).toBeDefined()
78
+ })
79
+
80
+ test('handles list with no current workspace', async () => {
81
+ // Given: Workspaces exist but none is current
82
+ const ws: WorkspaceCredentials = {
83
+ workspace_id: 'T999',
84
+ workspace_name: 'no-current',
85
+ token: 'xoxc-999',
86
+ cookie: 'xoxd-999',
87
+ }
88
+ await credManager.setWorkspace(ws)
89
+
90
+ // When: Loading config
91
+ const config = await credManager.load()
92
+
93
+ // Then: current_workspace should be null
94
+ expect(config.current_workspace).toBeNull()
95
+ expect(config.workspaces.T999).toBeDefined()
96
+ })
97
+ })
98
+
99
+ describe('workspace switch', () => {
100
+ test('switches to existing workspace', async () => {
101
+ // Given: Multiple workspaces exist
102
+ const ws1: WorkspaceCredentials = {
103
+ workspace_id: 'T111',
104
+ workspace_name: 'first',
105
+ token: 'xoxc-111',
106
+ cookie: 'xoxd-111',
107
+ }
108
+ const ws2: WorkspaceCredentials = {
109
+ workspace_id: 'T222',
110
+ workspace_name: 'second',
111
+ token: 'xoxc-222',
112
+ cookie: 'xoxd-222',
113
+ }
114
+ await credManager.setWorkspace(ws1)
115
+ await credManager.setWorkspace(ws2)
116
+ await credManager.setCurrentWorkspace('T111')
117
+
118
+ // When: Switching to second workspace
119
+ await credManager.setCurrentWorkspace('T222')
120
+
121
+ // Then: Current should be updated
122
+ const config = await credManager.load()
123
+ expect(config.current_workspace).toBe('T222')
124
+ })
125
+
126
+ test('fails when workspace does not exist', async () => {
127
+ // Given: Workspace does not exist
128
+ // When: Trying to get non-existent workspace
129
+ const ws = await credManager.getWorkspace('nonexistent')
130
+
131
+ // Then: Should return null
132
+ expect(ws).toBeNull()
133
+ })
134
+
135
+ test('validates workspace exists before switching', async () => {
136
+ // Given: Only one workspace exists
137
+ const ws: WorkspaceCredentials = {
138
+ workspace_id: 'T333',
139
+ workspace_name: 'only-one',
140
+ token: 'xoxc-333',
141
+ cookie: 'xoxd-333',
142
+ }
143
+ await credManager.setWorkspace(ws)
144
+ await credManager.setCurrentWorkspace('T333')
145
+
146
+ // When: Trying to switch to non-existent workspace
147
+ const config = await credManager.load()
148
+ const targetExists = 'T999' in config.workspaces
149
+
150
+ // Then: Should not exist
151
+ expect(targetExists).toBe(false)
152
+ })
153
+
154
+ test('preserves workspace credentials when switching', async () => {
155
+ // Given: Multiple workspaces with different credentials
156
+ const ws1: WorkspaceCredentials = {
157
+ workspace_id: 'T444',
158
+ workspace_name: 'first',
159
+ token: 'token-444',
160
+ cookie: 'cookie-444',
161
+ }
162
+ const ws2: WorkspaceCredentials = {
163
+ workspace_id: 'T555',
164
+ workspace_name: 'second',
165
+ token: 'token-555',
166
+ cookie: 'cookie-555',
167
+ }
168
+ await credManager.setWorkspace(ws1)
169
+ await credManager.setWorkspace(ws2)
170
+
171
+ // When: Switching between workspaces
172
+ await credManager.setCurrentWorkspace('T444')
173
+ let config = await credManager.load()
174
+ expect(config.current_workspace).toBe('T444')
175
+
176
+ await credManager.setCurrentWorkspace('T555')
177
+ config = await credManager.load()
178
+
179
+ // Then: Both workspaces should still have their credentials
180
+ expect(config.workspaces.T444.token).toBe('token-444')
181
+ expect(config.workspaces.T555.token).toBe('token-555')
182
+ expect(config.current_workspace).toBe('T555')
183
+ })
184
+ })
185
+
186
+ describe('workspace current', () => {
187
+ test('returns current workspace details', async () => {
188
+ // Given: A current workspace is set
189
+ const ws: WorkspaceCredentials = {
190
+ workspace_id: 'T666',
191
+ workspace_name: 'current-workspace',
192
+ token: 'xoxc-666',
193
+ cookie: 'xoxd-666',
194
+ }
195
+ await credManager.setWorkspace(ws)
196
+ await credManager.setCurrentWorkspace('T666')
197
+
198
+ // When: Getting current workspace
199
+ const current = await credManager.getWorkspace()
200
+
201
+ // Then: Should return workspace details
202
+ expect(current).not.toBeNull()
203
+ expect(current?.workspace_id).toBe('T666')
204
+ expect(current?.workspace_name).toBe('current-workspace')
205
+ expect(current?.token).toBe('xoxc-666')
206
+ expect(current?.cookie).toBe('xoxd-666')
207
+ })
208
+
209
+ test('returns null when no current workspace set', async () => {
210
+ // Given: No current workspace
211
+ // When: Getting current workspace
212
+ const current = await credManager.getWorkspace()
213
+
214
+ // Then: Should return null
215
+ expect(current).toBeNull()
216
+ })
217
+
218
+ test('returns null when current workspace is deleted', async () => {
219
+ // Given: Current workspace is set
220
+ const ws: WorkspaceCredentials = {
221
+ workspace_id: 'T777',
222
+ workspace_name: 'to-delete',
223
+ token: 'xoxc-777',
224
+ cookie: 'xoxd-777',
225
+ }
226
+ await credManager.setWorkspace(ws)
227
+ await credManager.setCurrentWorkspace('T777')
228
+
229
+ // When: Workspace is removed
230
+ await credManager.removeWorkspace('T777')
231
+
232
+ // Then: Current should be null
233
+ const current = await credManager.getWorkspace()
234
+ expect(current).toBeNull()
235
+ })
236
+
237
+ test('shows correct workspace after switching', async () => {
238
+ // Given: Multiple workspaces with one as current
239
+ const ws1: WorkspaceCredentials = {
240
+ workspace_id: 'T888',
241
+ workspace_name: 'first',
242
+ token: 'token-888',
243
+ cookie: 'cookie-888',
244
+ }
245
+ const ws2: WorkspaceCredentials = {
246
+ workspace_id: 'T999',
247
+ workspace_name: 'second',
248
+ token: 'token-999',
249
+ cookie: 'cookie-999',
250
+ }
251
+ await credManager.setWorkspace(ws1)
252
+ await credManager.setWorkspace(ws2)
253
+ await credManager.setCurrentWorkspace('T888')
254
+
255
+ // When: Switching to second workspace
256
+ await credManager.setCurrentWorkspace('T999')
257
+ const current = await credManager.getWorkspace()
258
+
259
+ // Then: Should return second workspace
260
+ expect(current?.workspace_id).toBe('T999')
261
+ expect(current?.workspace_name).toBe('second')
262
+ })
263
+ })
264
+
265
+ describe('workspace remove', () => {
266
+ test('removes workspace by id', async () => {
267
+ // Given: A workspace exists
268
+ const ws: WorkspaceCredentials = {
269
+ workspace_id: 'T-remove',
270
+ workspace_name: 'to-remove',
271
+ token: 'xoxc-remove',
272
+ cookie: 'xoxd-remove',
273
+ }
274
+ await credManager.setWorkspace(ws)
275
+
276
+ // When: Workspace is removed
277
+ await credManager.removeWorkspace('T-remove')
278
+
279
+ // Then: Workspace should not exist
280
+ const retrieved = await credManager.getWorkspace('T-remove')
281
+ expect(retrieved).toBeNull()
282
+ })
283
+
284
+ test('removes current workspace and clears current', async () => {
285
+ // Given: Current workspace is set
286
+ const ws: WorkspaceCredentials = {
287
+ workspace_id: 'T-current-remove',
288
+ workspace_name: 'current-to-remove',
289
+ token: 'xoxc-current-remove',
290
+ cookie: 'xoxd-current-remove',
291
+ }
292
+ await credManager.setWorkspace(ws)
293
+ await credManager.setCurrentWorkspace('T-current-remove')
294
+
295
+ // When: Current workspace is removed
296
+ await credManager.removeWorkspace('T-current-remove')
297
+
298
+ // Then: Current should be null
299
+ const config = await credManager.load()
300
+ expect(config.current_workspace).toBeNull()
301
+ })
302
+
303
+ test('removes workspace without affecting others', async () => {
304
+ // Given: Multiple workspaces exist
305
+ const ws1: WorkspaceCredentials = {
306
+ workspace_id: 'T-keep',
307
+ workspace_name: 'keep',
308
+ token: 'token-keep',
309
+ cookie: 'cookie-keep',
310
+ }
311
+ const ws2: WorkspaceCredentials = {
312
+ workspace_id: 'T-remove-one',
313
+ workspace_name: 'remove-one',
314
+ token: 'token-remove',
315
+ cookie: 'cookie-remove',
316
+ }
317
+ await credManager.setWorkspace(ws1)
318
+ await credManager.setWorkspace(ws2)
319
+ await credManager.setCurrentWorkspace('T-keep')
320
+
321
+ // When: One workspace is removed
322
+ await credManager.removeWorkspace('T-remove-one')
323
+
324
+ // Then: Other workspace should remain
325
+ const config = await credManager.load()
326
+ expect(config.workspaces['T-keep']).toBeDefined()
327
+ expect(config.workspaces['T-remove-one']).toBeUndefined()
328
+ expect(config.current_workspace).toBe('T-keep')
329
+ })
330
+
331
+ test('handles removing non-existent workspace gracefully', async () => {
332
+ // Given: Workspace does not exist
333
+ // When: Trying to remove non-existent workspace
334
+ await credManager.removeWorkspace('nonexistent')
335
+
336
+ // Then: Should not throw error
337
+ const config = await credManager.load()
338
+ expect(config.workspaces).toEqual({})
339
+ })
340
+
341
+ test('clears current only if removed workspace was current', async () => {
342
+ // Given: Multiple workspaces with one as current
343
+ const ws1: WorkspaceCredentials = {
344
+ workspace_id: 'T-current-1',
345
+ workspace_name: 'current-1',
346
+ token: 'token-1',
347
+ cookie: 'cookie-1',
348
+ }
349
+ const ws2: WorkspaceCredentials = {
350
+ workspace_id: 'T-other',
351
+ workspace_name: 'other',
352
+ token: 'token-other',
353
+ cookie: 'cookie-other',
354
+ }
355
+ await credManager.setWorkspace(ws1)
356
+ await credManager.setWorkspace(ws2)
357
+ await credManager.setCurrentWorkspace('T-current-1')
358
+
359
+ // When: Non-current workspace is removed
360
+ await credManager.removeWorkspace('T-other')
361
+
362
+ // Then: Current should remain unchanged
363
+ const config = await credManager.load()
364
+ expect(config.current_workspace).toBe('T-current-1')
365
+ })
366
+ })
367
+
368
+ describe('Output Formatting', () => {
369
+ test('formats list output correctly', async () => {
370
+ // Given: Multiple workspaces
371
+ const ws1: WorkspaceCredentials = {
372
+ workspace_id: 'T-format-1',
373
+ workspace_name: 'format-1',
374
+ token: 'token-1',
375
+ cookie: 'cookie-1',
376
+ }
377
+ const ws2: WorkspaceCredentials = {
378
+ workspace_id: 'T-format-2',
379
+ workspace_name: 'format-2',
380
+ token: 'token-2',
381
+ cookie: 'cookie-2',
382
+ }
383
+ await credManager.setWorkspace(ws1)
384
+ await credManager.setWorkspace(ws2)
385
+ await credManager.setCurrentWorkspace('T-format-1')
386
+
387
+ // When: Creating list output
388
+ const config = await credManager.load()
389
+ const output = Object.values(config.workspaces).map((ws) => ({
390
+ id: ws.workspace_id,
391
+ name: ws.workspace_name,
392
+ current: ws.workspace_id === config.current_workspace,
393
+ }))
394
+
395
+ // Then: Should be valid JSON
396
+ const json = JSON.stringify(output)
397
+ const parsed = JSON.parse(json)
398
+ expect(parsed).toHaveLength(2)
399
+ expect(parsed[0].current).toBe(true)
400
+ expect(parsed[1].current).toBe(false)
401
+ })
402
+
403
+ test('formats switch output correctly', async () => {
404
+ // Given: Workspace to switch to
405
+ const ws: WorkspaceCredentials = {
406
+ workspace_id: 'T-switch-format',
407
+ workspace_name: 'switch-format',
408
+ token: 'token-switch',
409
+ cookie: 'cookie-switch',
410
+ }
411
+ await credManager.setWorkspace(ws)
412
+ await credManager.setCurrentWorkspace('T-switch-format')
413
+
414
+ // When: Creating switch output
415
+ const output = { current: 'T-switch-format' }
416
+
417
+ // Then: Should be valid JSON
418
+ const json = JSON.stringify(output)
419
+ const parsed = JSON.parse(json)
420
+ expect(parsed.current).toBe('T-switch-format')
421
+ })
422
+
423
+ test('formats current output correctly', async () => {
424
+ // Given: Current workspace
425
+ const ws: WorkspaceCredentials = {
426
+ workspace_id: 'T-current-format',
427
+ workspace_name: 'current-format',
428
+ token: 'token-current',
429
+ cookie: 'cookie-current',
430
+ }
431
+ await credManager.setWorkspace(ws)
432
+ await credManager.setCurrentWorkspace('T-current-format')
433
+
434
+ // When: Creating current output
435
+ const current = await credManager.getWorkspace()
436
+ const output = {
437
+ workspace_id: current?.workspace_id,
438
+ workspace_name: current?.workspace_name,
439
+ }
440
+
441
+ // Then: Should be valid JSON
442
+ const json = JSON.stringify(output)
443
+ const parsed = JSON.parse(json)
444
+ expect(parsed.workspace_id).toBe('T-current-format')
445
+ expect(parsed.workspace_name).toBe('current-format')
446
+ })
447
+
448
+ test('formats remove output correctly', async () => {
449
+ // Given: Workspace to remove
450
+ const ws: WorkspaceCredentials = {
451
+ workspace_id: 'T-remove-format',
452
+ workspace_name: 'remove-format',
453
+ token: 'token-remove',
454
+ cookie: 'cookie-remove',
455
+ }
456
+ await credManager.setWorkspace(ws)
457
+
458
+ // When: Creating remove output
459
+ const output = { removed: 'T-remove-format' }
460
+
461
+ // Then: Should be valid JSON
462
+ const json = JSON.stringify(output)
463
+ const parsed = JSON.parse(json)
464
+ expect(parsed.removed).toBe('T-remove-format')
465
+ })
466
+
467
+ test('pretty prints JSON correctly', async () => {
468
+ // Given: Output data
469
+ const output = {
470
+ id: 'T123',
471
+ name: 'test',
472
+ current: true,
473
+ }
474
+
475
+ // When: Pretty printing
476
+ const pretty = JSON.stringify(output, null, 2)
477
+
478
+ // Then: Should contain newlines and indentation
479
+ expect(pretty).toContain('\n')
480
+ expect(pretty).toContain(' ')
481
+ })
482
+ })
483
+
484
+ describe('Error Handling', () => {
485
+ test('handles missing workspace gracefully', async () => {
486
+ // Given: Workspace does not exist
487
+ // When: Trying to get workspace
488
+ const ws = await credManager.getWorkspace('missing')
489
+
490
+ // Then: Should return null
491
+ expect(ws).toBeNull()
492
+ })
493
+
494
+ test('handles corrupted config gracefully', async () => {
495
+ // Given: Config directory exists
496
+ // When: Loading from empty directory
497
+ const config = await credManager.load()
498
+
499
+ // Then: Should return default config
500
+ expect(config.current_workspace).toBeNull()
501
+ expect(config.workspaces).toEqual({})
502
+ })
503
+
504
+ test('handles concurrent operations', async () => {
505
+ // Given: Multiple workspaces
506
+ const ws1: WorkspaceCredentials = {
507
+ workspace_id: 'T-concurrent-1',
508
+ workspace_name: 'concurrent-1',
509
+ token: 'token-1',
510
+ cookie: 'cookie-1',
511
+ }
512
+ const ws2: WorkspaceCredentials = {
513
+ workspace_id: 'T-concurrent-2',
514
+ workspace_name: 'concurrent-2',
515
+ token: 'token-2',
516
+ cookie: 'cookie-2',
517
+ }
518
+
519
+ // When: Setting workspaces sequentially
520
+ await credManager.setWorkspace(ws1)
521
+ await credManager.setWorkspace(ws2)
522
+
523
+ // Then: Both should be saved
524
+ const config = await credManager.load()
525
+ expect(Object.keys(config.workspaces)).toHaveLength(2)
526
+ })
527
+ })
528
+ })