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,158 @@
1
+ import { Command } from 'commander'
2
+ import { handleError } from '../../../shared/utils/error-handler'
3
+ import { formatOutput } from '../../../shared/utils/output'
4
+ import { SlackClient } from '../client'
5
+ import { CredentialManager } from '../credential-manager'
6
+
7
+ async function listAction(options: {
8
+ type?: string
9
+ includeArchived?: boolean
10
+ pretty?: boolean
11
+ }): Promise<void> {
12
+ try {
13
+ const credManager = new CredentialManager()
14
+ const workspace = await credManager.getWorkspace()
15
+
16
+ if (!workspace) {
17
+ console.log(
18
+ formatOutput(
19
+ { error: 'No current workspace set. Run "auth extract" first.' },
20
+ options.pretty
21
+ )
22
+ )
23
+ process.exit(1)
24
+ }
25
+
26
+ const client = new SlackClient(workspace.token, workspace.cookie)
27
+ let channels = await client.listChannels()
28
+
29
+ if (!options.includeArchived) {
30
+ channels = channels.filter((c) => !c.is_archived)
31
+ }
32
+
33
+ if (options.type === 'public') {
34
+ channels = channels.filter((c) => !c.is_private)
35
+ } else if (options.type === 'private') {
36
+ channels = channels.filter((c) => c.is_private)
37
+ } else if (options.type === 'dm') {
38
+ channels = []
39
+ }
40
+
41
+ const output = channels.map((ch) => ({
42
+ id: ch.id,
43
+ name: ch.name,
44
+ is_private: ch.is_private,
45
+ ...(options.includeArchived && { is_archived: ch.is_archived }),
46
+ created: ch.created,
47
+ topic: ch.topic?.value,
48
+ purpose: ch.purpose?.value,
49
+ }))
50
+
51
+ console.log(formatOutput(output, options.pretty))
52
+ } catch (error) {
53
+ handleError(error as Error)
54
+ }
55
+ }
56
+
57
+ async function infoAction(channel: string, options: { pretty?: boolean }): Promise<void> {
58
+ try {
59
+ const credManager = new CredentialManager()
60
+ const workspace = await credManager.getWorkspace()
61
+
62
+ if (!workspace) {
63
+ console.log(
64
+ formatOutput(
65
+ { error: 'No current workspace set. Run "auth extract" first.' },
66
+ options.pretty
67
+ )
68
+ )
69
+ process.exit(1)
70
+ }
71
+
72
+ const client = new SlackClient(workspace.token, workspace.cookie)
73
+ const ch = await client.getChannel(channel)
74
+
75
+ const output = {
76
+ id: ch.id,
77
+ name: ch.name,
78
+ is_private: ch.is_private,
79
+ is_archived: ch.is_archived,
80
+ created: ch.created,
81
+ creator: ch.creator,
82
+ topic: ch.topic,
83
+ purpose: ch.purpose,
84
+ }
85
+
86
+ console.log(formatOutput(output, options.pretty))
87
+ } catch (error) {
88
+ handleError(error as Error)
89
+ }
90
+ }
91
+
92
+ async function historyAction(
93
+ channel: string,
94
+ options: { limit?: number; pretty?: boolean }
95
+ ): Promise<void> {
96
+ try {
97
+ const credManager = new CredentialManager()
98
+ const workspace = await credManager.getWorkspace()
99
+
100
+ if (!workspace) {
101
+ console.log(
102
+ formatOutput(
103
+ { error: 'No current workspace set. Run "auth extract" first.' },
104
+ options.pretty
105
+ )
106
+ )
107
+ process.exit(1)
108
+ }
109
+
110
+ const client = new SlackClient(workspace.token, workspace.cookie)
111
+ const messages = await client.getMessages(channel, options.limit || 20)
112
+
113
+ const output = messages.map((msg) => ({
114
+ ts: msg.ts,
115
+ text: msg.text,
116
+ user: msg.user,
117
+ username: msg.username,
118
+ type: msg.type,
119
+ thread_ts: msg.thread_ts,
120
+ reply_count: msg.reply_count,
121
+ }))
122
+
123
+ console.log(formatOutput(output, options.pretty))
124
+ } catch (error) {
125
+ handleError(error as Error)
126
+ }
127
+ }
128
+
129
+ export const channelCommand = new Command('channel')
130
+ .description('Channel commands')
131
+ .addCommand(
132
+ new Command('list')
133
+ .description('List channels')
134
+ .option('--type <public|private|dm>', 'Filter by channel type')
135
+ .option('--include-archived', 'Include archived channels')
136
+ .option('--pretty', 'Pretty print JSON output')
137
+ .action(listAction)
138
+ )
139
+ .addCommand(
140
+ new Command('info')
141
+ .description('Get channel info')
142
+ .argument('<channel>', 'Channel ID or name')
143
+ .option('--pretty', 'Pretty print JSON output')
144
+ .action(infoAction)
145
+ )
146
+ .addCommand(
147
+ new Command('history')
148
+ .description('Get channel message history (alias for message list)')
149
+ .argument('<channel>', 'Channel ID or name')
150
+ .option('--limit <n>', 'Number of messages to fetch', '20')
151
+ .option('--pretty', 'Pretty print JSON output')
152
+ .action((channel, options) => {
153
+ historyAction(channel, {
154
+ limit: parseInt(options.limit, 10),
155
+ pretty: options.pretty,
156
+ })
157
+ })
158
+ )
@@ -0,0 +1,153 @@
1
+ import { readFileSync } from 'node:fs'
2
+ import { resolve } from 'node:path'
3
+ import { Command } from 'commander'
4
+ import { handleError } from '../../../shared/utils/error-handler'
5
+ import { formatOutput } from '../../../shared/utils/output'
6
+ import { SlackClient } from '../client'
7
+ import { CredentialManager } from '../credential-manager'
8
+
9
+ async function uploadAction(
10
+ channel: string,
11
+ path: string,
12
+ options: { filename?: string; pretty?: boolean }
13
+ ): Promise<void> {
14
+ try {
15
+ const credManager = new CredentialManager()
16
+ const workspace = await credManager.getWorkspace()
17
+
18
+ if (!workspace) {
19
+ console.log(
20
+ formatOutput(
21
+ { error: 'No current workspace set. Run "auth extract" first.' },
22
+ options.pretty
23
+ )
24
+ )
25
+ process.exit(1)
26
+ }
27
+
28
+ const client = new SlackClient(workspace.token, workspace.cookie)
29
+
30
+ const filePath = resolve(path)
31
+ const fileBuffer = readFileSync(filePath)
32
+ const filename = options.filename || filePath.split('/').pop() || 'file'
33
+
34
+ const file = await client.uploadFile([channel], fileBuffer, filename)
35
+
36
+ const output = {
37
+ id: file.id,
38
+ name: file.name,
39
+ title: file.title,
40
+ mimetype: file.mimetype,
41
+ size: file.size,
42
+ url_private: file.url_private,
43
+ created: file.created,
44
+ user: file.user,
45
+ channels: file.channels,
46
+ }
47
+
48
+ console.log(formatOutput(output, options.pretty))
49
+ } catch (error) {
50
+ handleError(error as Error)
51
+ }
52
+ }
53
+
54
+ async function listAction(options: { channel?: string; pretty?: boolean }): Promise<void> {
55
+ try {
56
+ const credManager = new CredentialManager()
57
+ const workspace = await credManager.getWorkspace()
58
+
59
+ if (!workspace) {
60
+ console.log(
61
+ formatOutput(
62
+ { error: 'No current workspace set. Run "auth extract" first.' },
63
+ options.pretty
64
+ )
65
+ )
66
+ process.exit(1)
67
+ }
68
+
69
+ const client = new SlackClient(workspace.token, workspace.cookie)
70
+ const files = await client.listFiles(options.channel)
71
+
72
+ const output = files.map((file) => ({
73
+ id: file.id,
74
+ name: file.name,
75
+ title: file.title,
76
+ mimetype: file.mimetype,
77
+ size: file.size,
78
+ url_private: file.url_private,
79
+ created: file.created,
80
+ user: file.user,
81
+ channels: file.channels,
82
+ }))
83
+
84
+ console.log(formatOutput(output, options.pretty))
85
+ } catch (error) {
86
+ handleError(error as Error)
87
+ }
88
+ }
89
+
90
+ async function infoAction(fileId: string, options: { pretty?: boolean }): Promise<void> {
91
+ try {
92
+ const credManager = new CredentialManager()
93
+ const workspace = await credManager.getWorkspace()
94
+
95
+ if (!workspace) {
96
+ console.log(
97
+ formatOutput(
98
+ { error: 'No current workspace set. Run "auth extract" first.' },
99
+ options.pretty
100
+ )
101
+ )
102
+ process.exit(1)
103
+ }
104
+
105
+ const client = new SlackClient(workspace.token, workspace.cookie)
106
+ const files = await client.listFiles()
107
+ const fileData = files.find((f) => f.id === fileId)
108
+
109
+ if (!fileData) {
110
+ console.log(formatOutput({ error: `File not found: ${fileId}` }, options.pretty))
111
+ process.exit(1)
112
+ }
113
+
114
+ const output = {
115
+ id: fileData.id,
116
+ name: fileData.name,
117
+ title: fileData.title,
118
+ mimetype: fileData.mimetype,
119
+ size: fileData.size,
120
+ url_private: fileData.url_private,
121
+ created: fileData.created,
122
+ user: fileData.user,
123
+ channels: fileData.channels,
124
+ }
125
+
126
+ console.log(formatOutput(output, options.pretty))
127
+ } catch (error) {
128
+ handleError(error as Error)
129
+ }
130
+ }
131
+
132
+ export const fileCommand = new Command('file')
133
+ .description('file commands')
134
+ .addCommand(
135
+ new Command('upload')
136
+ .description('upload file to channel')
137
+ .argument('<channel>', 'channel ID or name')
138
+ .argument('<path>', 'file path')
139
+ .option('--filename <name>', 'override filename')
140
+ .action(uploadAction)
141
+ )
142
+ .addCommand(
143
+ new Command('list')
144
+ .description('list files in workspace')
145
+ .option('--channel <id>', 'filter by channel')
146
+ .action(listAction)
147
+ )
148
+ .addCommand(
149
+ new Command('info')
150
+ .description('show file details')
151
+ .argument('<file>', 'file ID')
152
+ .action(infoAction)
153
+ )
@@ -0,0 +1,8 @@
1
+ export { authCommand } from './auth'
2
+ export { channelCommand } from './channel'
3
+ export { fileCommand } from './file'
4
+ export { messageCommand } from './message'
5
+ export { reactionCommand } from './reaction'
6
+ export { snapshotCommand } from './snapshot'
7
+ export { userCommand } from './user'
8
+ export { workspaceCommand } from './workspace'
@@ -0,0 +1,369 @@
1
+ import { Command } from 'commander'
2
+ import { handleError } from '../../../shared/utils/error-handler'
3
+ import { formatOutput } from '../../../shared/utils/output'
4
+ import { SlackClient } from '../client'
5
+ import { CredentialManager } from '../credential-manager'
6
+ import type { SlackMessage } from '../types'
7
+
8
+ async function sendAction(
9
+ channel: string,
10
+ text: string,
11
+ options: { thread?: string; pretty?: boolean }
12
+ ): Promise<void> {
13
+ try {
14
+ const credManager = new CredentialManager()
15
+ const workspace = await credManager.getWorkspace()
16
+
17
+ if (!workspace) {
18
+ console.log(
19
+ formatOutput(
20
+ { error: 'No current workspace set. Run "auth extract" first.' },
21
+ options.pretty
22
+ )
23
+ )
24
+ process.exit(1)
25
+ }
26
+
27
+ const client = new SlackClient(workspace.token, workspace.cookie)
28
+ const message = await client.sendMessage(channel, text, options.thread)
29
+
30
+ const output = {
31
+ ts: message.ts,
32
+ text: message.text,
33
+ type: message.type,
34
+ user: message.user,
35
+ thread_ts: message.thread_ts,
36
+ }
37
+
38
+ console.log(formatOutput(output, options.pretty))
39
+ } catch (error) {
40
+ handleError(error as Error)
41
+ }
42
+ }
43
+
44
+ async function listAction(
45
+ channel: string,
46
+ options: { limit?: number; thread?: string; pretty?: boolean }
47
+ ): Promise<void> {
48
+ try {
49
+ const credManager = new CredentialManager()
50
+ const workspace = await credManager.getWorkspace()
51
+
52
+ if (!workspace) {
53
+ console.log(
54
+ formatOutput(
55
+ { error: 'No current workspace set. Run "auth extract" first.' },
56
+ options.pretty
57
+ )
58
+ )
59
+ process.exit(1)
60
+ }
61
+
62
+ const client = new SlackClient(workspace.token, workspace.cookie)
63
+ const limit = options.limit || 20
64
+ const messages = await client.getMessages(channel, limit)
65
+
66
+ const output = messages.map((msg: SlackMessage) => ({
67
+ ts: msg.ts,
68
+ text: msg.text,
69
+ type: msg.type,
70
+ user: msg.user,
71
+ username: msg.username,
72
+ thread_ts: msg.thread_ts,
73
+ reply_count: msg.reply_count,
74
+ edited: msg.edited,
75
+ }))
76
+
77
+ console.log(formatOutput(output, options.pretty))
78
+ } catch (error) {
79
+ handleError(error as Error)
80
+ }
81
+ }
82
+
83
+ async function getAction(
84
+ channel: string,
85
+ ts: string,
86
+ options: { pretty?: boolean }
87
+ ): Promise<void> {
88
+ try {
89
+ const credManager = new CredentialManager()
90
+ const workspace = await credManager.getWorkspace()
91
+
92
+ if (!workspace) {
93
+ console.log(
94
+ formatOutput(
95
+ { error: 'No current workspace set. Run "auth extract" first.' },
96
+ options.pretty
97
+ )
98
+ )
99
+ process.exit(1)
100
+ }
101
+
102
+ const client = new SlackClient(workspace.token, workspace.cookie)
103
+ const message = await client.getMessage(channel, ts)
104
+
105
+ if (!message) {
106
+ console.log(formatOutput({ error: `Message not found: ${ts}` }, options.pretty))
107
+ process.exit(1)
108
+ }
109
+
110
+ const output = {
111
+ ts: message.ts,
112
+ text: message.text,
113
+ type: message.type,
114
+ user: message.user,
115
+ username: message.username,
116
+ thread_ts: message.thread_ts,
117
+ reply_count: message.reply_count,
118
+ edited: message.edited,
119
+ }
120
+
121
+ console.log(formatOutput(output, options.pretty))
122
+ } catch (error) {
123
+ handleError(error as Error)
124
+ }
125
+ }
126
+
127
+ async function updateAction(
128
+ channel: string,
129
+ ts: string,
130
+ text: string,
131
+ options: { pretty?: boolean }
132
+ ): Promise<void> {
133
+ try {
134
+ const credManager = new CredentialManager()
135
+ const workspace = await credManager.getWorkspace()
136
+
137
+ if (!workspace) {
138
+ console.log(
139
+ formatOutput(
140
+ { error: 'No current workspace set. Run "auth extract" first.' },
141
+ options.pretty
142
+ )
143
+ )
144
+ process.exit(1)
145
+ }
146
+
147
+ const client = new SlackClient(workspace.token, workspace.cookie)
148
+ const message = await client.updateMessage(channel, ts, text)
149
+
150
+ const output = {
151
+ ts: message.ts,
152
+ text: message.text,
153
+ type: message.type,
154
+ user: message.user,
155
+ }
156
+
157
+ console.log(formatOutput(output, options.pretty))
158
+ } catch (error) {
159
+ handleError(error as Error)
160
+ }
161
+ }
162
+
163
+ async function deleteAction(
164
+ channel: string,
165
+ ts: string,
166
+ options: { force?: boolean; pretty?: boolean }
167
+ ): Promise<void> {
168
+ try {
169
+ const credManager = new CredentialManager()
170
+ const workspace = await credManager.getWorkspace()
171
+
172
+ if (!workspace) {
173
+ console.log(
174
+ formatOutput(
175
+ { error: 'No current workspace set. Run "auth extract" first.' },
176
+ options.pretty
177
+ )
178
+ )
179
+ process.exit(1)
180
+ }
181
+
182
+ if (!options.force) {
183
+ console.log(formatOutput({ warning: 'Use --force to confirm deletion', ts }, options.pretty))
184
+ process.exit(0)
185
+ }
186
+
187
+ const client = new SlackClient(workspace.token, workspace.cookie)
188
+ await client.deleteMessage(channel, ts)
189
+
190
+ console.log(formatOutput({ deleted: ts }, options.pretty))
191
+ } catch (error) {
192
+ handleError(error as Error)
193
+ }
194
+ }
195
+
196
+ async function searchAction(
197
+ query: string,
198
+ options: { sort?: string; sortDir?: string; limit?: number; pretty?: boolean }
199
+ ): Promise<void> {
200
+ try {
201
+ const credManager = new CredentialManager()
202
+ const workspace = await credManager.getWorkspace()
203
+
204
+ if (!workspace) {
205
+ console.log(
206
+ formatOutput(
207
+ { error: 'No current workspace set. Run "auth extract" first.' },
208
+ options.pretty
209
+ )
210
+ )
211
+ process.exit(1)
212
+ }
213
+
214
+ const client = new SlackClient(workspace.token, workspace.cookie)
215
+ const results = await client.searchMessages(query, {
216
+ sort: options.sort as 'score' | 'timestamp',
217
+ sortDir: options.sortDir as 'asc' | 'desc',
218
+ count: options.limit || 20,
219
+ })
220
+
221
+ const output = results.map((result) => ({
222
+ ts: result.ts,
223
+ text: result.text,
224
+ user: result.user,
225
+ username: result.username,
226
+ channel_id: result.channel.id,
227
+ channel_name: result.channel.name,
228
+ permalink: result.permalink,
229
+ }))
230
+
231
+ console.log(formatOutput(output, options.pretty))
232
+ } catch (error) {
233
+ handleError(error as Error)
234
+ }
235
+ }
236
+
237
+ async function repliesAction(
238
+ channel: string,
239
+ threadTs: string,
240
+ options: { limit?: number; oldest?: string; latest?: string; cursor?: string; pretty?: boolean }
241
+ ): Promise<void> {
242
+ try {
243
+ const credManager = new CredentialManager()
244
+ const workspace = await credManager.getWorkspace()
245
+
246
+ if (!workspace) {
247
+ console.log(
248
+ formatOutput(
249
+ { error: 'No current workspace set. Run "auth extract" first.' },
250
+ options.pretty
251
+ )
252
+ )
253
+ process.exit(1)
254
+ }
255
+
256
+ const client = new SlackClient(workspace.token, workspace.cookie)
257
+ const result = await client.getThreadReplies(channel, threadTs, {
258
+ limit: options.limit,
259
+ oldest: options.oldest,
260
+ latest: options.latest,
261
+ cursor: options.cursor,
262
+ })
263
+
264
+ const output = result.messages.map((msg: SlackMessage) => ({
265
+ ts: msg.ts,
266
+ text: msg.text,
267
+ type: msg.type,
268
+ user: msg.user,
269
+ username: msg.username,
270
+ thread_ts: msg.thread_ts,
271
+ reply_count: msg.reply_count,
272
+ edited: msg.edited,
273
+ }))
274
+
275
+ console.log(formatOutput(output, options.pretty))
276
+ } catch (error) {
277
+ handleError(error as Error)
278
+ }
279
+ }
280
+
281
+ export const messageCommand = new Command('message')
282
+ .description('Message commands')
283
+ .addCommand(
284
+ new Command('send')
285
+ .description('Send message to channel')
286
+ .argument('<channel>', 'Channel ID or name')
287
+ .argument('<text>', 'Message text')
288
+ .option('--thread <ts>', 'Thread timestamp for replies')
289
+ .option('--pretty', 'Pretty print JSON output')
290
+ .action(sendAction)
291
+ )
292
+ .addCommand(
293
+ new Command('list')
294
+ .description('List messages from channel')
295
+ .argument('<channel>', 'Channel ID or name')
296
+ .option('--limit <n>', 'Number of messages to retrieve', '20')
297
+ .option('--thread <ts>', 'Filter by thread timestamp')
298
+ .option('--pretty', 'Pretty print JSON output')
299
+ .action((channel: string, options: any) => {
300
+ listAction(channel, {
301
+ limit: parseInt(options.limit, 10),
302
+ thread: options.thread,
303
+ pretty: options.pretty,
304
+ })
305
+ })
306
+ )
307
+ .addCommand(
308
+ new Command('get')
309
+ .description('Get a single message by timestamp')
310
+ .argument('<channel>', 'Channel ID or name')
311
+ .argument('<ts>', 'Message timestamp')
312
+ .option('--pretty', 'Pretty print JSON output')
313
+ .action(getAction)
314
+ )
315
+ .addCommand(
316
+ new Command('update')
317
+ .description('Update message text')
318
+ .argument('<channel>', 'Channel ID or name')
319
+ .argument('<ts>', 'Message timestamp')
320
+ .argument('<text>', 'New message text')
321
+ .option('--pretty', 'Pretty print JSON output')
322
+ .action(updateAction)
323
+ )
324
+ .addCommand(
325
+ new Command('delete')
326
+ .description('Delete message')
327
+ .argument('<channel>', 'Channel ID or name')
328
+ .argument('<ts>', 'Message timestamp')
329
+ .option('--force', 'Skip confirmation')
330
+ .option('--pretty', 'Pretty print JSON output')
331
+ .action(deleteAction)
332
+ )
333
+ .addCommand(
334
+ new Command('search')
335
+ .description('Search messages across workspace')
336
+ .argument('<query>', 'Search query')
337
+ .option('--sort <type>', 'Sort by: score, timestamp (default: timestamp)')
338
+ .option('--sort-dir <dir>', 'Sort direction: asc, desc (default: desc)')
339
+ .option('--limit <n>', 'Number of results', '20')
340
+ .option('--pretty', 'Pretty print JSON output')
341
+ .action((query: string, options: any) => {
342
+ searchAction(query, {
343
+ sort: options.sort,
344
+ sortDir: options.sortDir,
345
+ limit: parseInt(options.limit, 10),
346
+ pretty: options.pretty,
347
+ })
348
+ })
349
+ )
350
+ .addCommand(
351
+ new Command('replies')
352
+ .description('Get thread replies')
353
+ .argument('<channel>', 'Channel ID or name')
354
+ .argument('<thread_ts>', 'Thread timestamp')
355
+ .option('--limit <n>', 'Number of replies to retrieve', '100')
356
+ .option('--oldest <ts>', 'Only messages after this timestamp')
357
+ .option('--latest <ts>', 'Only messages before this timestamp')
358
+ .option('--cursor <cursor>', 'Pagination cursor for next page')
359
+ .option('--pretty', 'Pretty print JSON output')
360
+ .action((channel: string, threadTs: string, options: any) => {
361
+ repliesAction(channel, threadTs, {
362
+ limit: options.limit ? parseInt(options.limit, 10) : undefined,
363
+ oldest: options.oldest,
364
+ latest: options.latest,
365
+ cursor: options.cursor,
366
+ pretty: options.pretty,
367
+ })
368
+ })
369
+ )