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
@@ -3,6 +3,7 @@ import { createDecipheriv, pbkdf2Sync } from 'node:crypto'
3
3
  import { existsSync, readdirSync, readFileSync } from 'node:fs'
4
4
  import { homedir } from 'node:os'
5
5
  import { join } from 'node:path'
6
+ import { DerivedKeyCache } from '../../shared/utils/derived-key-cache'
6
7
 
7
8
  export interface ExtractedDiscordToken {
8
9
  token: string
@@ -59,11 +60,19 @@ export class DiscordTokenExtractor {
59
60
  private platform: NodeJS.Platform
60
61
  private startupWait: number
61
62
  private killWait: number
62
-
63
- constructor(platform?: NodeJS.Platform, startupWait?: number, killWait?: number) {
63
+ private keyCache: DerivedKeyCache
64
+ private cachedKey: Buffer | null = null
65
+
66
+ constructor(
67
+ platform?: NodeJS.Platform,
68
+ startupWait?: number,
69
+ killWait?: number,
70
+ keyCache?: DerivedKeyCache
71
+ ) {
64
72
  this.platform = platform ?? process.platform
65
73
  this.startupWait = startupWait ?? DISCORD_STARTUP_WAIT
66
74
  this.killWait = killWait ?? 1000
75
+ this.keyCache = keyCache ?? new DerivedKeyCache()
67
76
  }
68
77
 
69
78
  getDiscordDirs(): string[] {
@@ -123,6 +132,8 @@ export class DiscordTokenExtractor {
123
132
  }
124
133
 
125
134
  async extract(): Promise<ExtractedDiscordToken | null> {
135
+ await this.loadCachedKey()
136
+
126
137
  const levelDbToken = await this.extractFromLevelDB()
127
138
  if (levelDbToken) {
128
139
  return levelDbToken
@@ -138,6 +149,20 @@ export class DiscordTokenExtractor {
138
149
  return null
139
150
  }
140
151
 
152
+ private async loadCachedKey(): Promise<void> {
153
+ if (this.platform !== 'darwin') return
154
+
155
+ const cached = await this.keyCache.get('discord')
156
+ if (cached) {
157
+ this.cachedKey = cached
158
+ }
159
+ }
160
+
161
+ async clearKeyCache(): Promise<void> {
162
+ await this.keyCache.clear('discord')
163
+ this.cachedKey = null
164
+ }
165
+
141
166
  private async tryExtractViaCDP(): Promise<string | null> {
142
167
  const token = await this.extractViaCDP()
143
168
  if (token) {
@@ -288,6 +313,11 @@ export class DiscordTokenExtractor {
288
313
  }
289
314
 
290
315
  private decryptMacToken(encryptedData: Buffer, discordDir: string): string | null {
316
+ if (this.cachedKey) {
317
+ const decrypted = this.decryptAESCBC(encryptedData, this.cachedKey)
318
+ if (decrypted) return decrypted
319
+ }
320
+
291
321
  const variant = this.getVariantFromPath(discordDir)
292
322
  const keychainVariants = this.getKeychainVariants().filter((v) => {
293
323
  const lowerAccount = v.account.toLowerCase()
@@ -308,7 +338,11 @@ export class DiscordTokenExtractor {
308
338
 
309
339
  const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
310
340
  const decrypted = this.decryptAESCBC(encryptedData, key)
311
- if (decrypted) return decrypted
341
+ if (decrypted) {
342
+ this.cachedKey = key
343
+ this.keyCache.set('discord', key).catch(() => {})
344
+ return decrypted
345
+ }
312
346
  } catch {}
313
347
  }
314
348
 
@@ -203,21 +203,21 @@ test('DiscordCredentialsSchema rejects missing token', () => {
203
203
 
204
204
  test('DiscordConfigSchema validates correct config', () => {
205
205
  const result = DiscordConfigSchema.safeParse({
206
- current_guild: null,
206
+ current_server: null,
207
207
  token: 'token_value',
208
- guilds: {},
208
+ servers: {},
209
209
  })
210
210
  expect(result.success).toBe(true)
211
211
  })
212
212
 
213
- test('DiscordConfigSchema validates config with guilds', () => {
213
+ test('DiscordConfigSchema validates config with servers', () => {
214
214
  const result = DiscordConfigSchema.safeParse({
215
- current_guild: '123456789012345678',
215
+ current_server: '123456789012345678',
216
216
  token: 'token_value',
217
- guilds: {
217
+ servers: {
218
218
  '123456789012345678': {
219
- guild_id: '123456789012345678',
220
- guild_name: 'Test Guild',
219
+ server_id: '123456789012345678',
220
+ server_name: 'Test Server',
221
221
  },
222
222
  },
223
223
  })
@@ -226,7 +226,7 @@ test('DiscordConfigSchema validates config with guilds', () => {
226
226
 
227
227
  test('DiscordConfigSchema rejects missing required fields', () => {
228
228
  const result = DiscordConfigSchema.safeParse({
229
- current_guild: null,
229
+ current_server: null,
230
230
  token: 'token_value',
231
231
  })
232
232
  expect(result.success).toBe(false)
@@ -18,6 +18,13 @@ export interface DiscordChannel {
18
18
  type: number
19
19
  topic?: string
20
20
  position?: number
21
+ parent_id?: string
22
+ thread_metadata?: {
23
+ archived?: boolean
24
+ auto_archive_duration?: number
25
+ archive_timestamp?: string
26
+ locked?: boolean
27
+ }
21
28
  }
22
29
 
23
30
  export interface DiscordMessage {
@@ -41,6 +48,14 @@ export interface DiscordUser {
41
48
  bot?: boolean
42
49
  }
43
50
 
51
+ export interface DiscordDMChannel {
52
+ id: string
53
+ type: number // 1=DM, 3=Group DM
54
+ last_message_id?: string
55
+ recipients: DiscordUser[]
56
+ name?: string // Only for group DMs
57
+ }
58
+
44
59
  export interface DiscordReaction {
45
60
  emoji: {
46
61
  id?: string
@@ -59,18 +74,92 @@ export interface DiscordFile {
59
74
  width?: number
60
75
  }
61
76
 
77
+ export interface DiscordMention {
78
+ id: string
79
+ channel_id: string
80
+ author: { id: string; username: string }
81
+ content: string
82
+ timestamp: string
83
+ mention_everyone: boolean
84
+ mentions: DiscordUser[]
85
+ guild_id?: string
86
+ }
87
+
88
+ export interface DiscordUserNote {
89
+ user_id: string
90
+ note_user_id: string
91
+ note: string
92
+ }
93
+
94
+ export interface DiscordSearchResult {
95
+ id: string
96
+ channel_id: string
97
+ guild_id?: string
98
+ content: string
99
+ author: {
100
+ id: string
101
+ username: string
102
+ }
103
+ timestamp: string
104
+ hit: boolean
105
+ }
106
+
107
+ export interface DiscordSearchResponse {
108
+ total_results: number
109
+ messages: DiscordSearchResult[][]
110
+ }
111
+
112
+ export interface DiscordSearchOptions {
113
+ channelId?: string
114
+ authorId?: string
115
+ has?: 'file' | 'image' | 'video' | 'embed' | 'link' | 'sticker'
116
+ sortBy?: 'timestamp' | 'relevance'
117
+ sortOrder?: 'asc' | 'desc'
118
+ limit?: number
119
+ offset?: number
120
+ }
121
+
122
+ export interface DiscordRelationship {
123
+ id: string
124
+ type: number
125
+ user: DiscordUser
126
+ nickname?: string
127
+ }
128
+
129
+ export interface DiscordGuildMember {
130
+ user: DiscordUser
131
+ nick?: string
132
+ roles: string[]
133
+ joined_at: string
134
+ deaf: boolean
135
+ mute: boolean
136
+ flags: number
137
+ }
138
+
139
+ export interface DiscordUserProfile {
140
+ user: DiscordUser & { bio?: string }
141
+ connected_accounts: Array<{
142
+ type: string
143
+ id: string
144
+ name: string
145
+ verified: boolean
146
+ }>
147
+ premium_since?: string
148
+ mutual_guilds?: Array<{ id: string; nick?: string }>
149
+ }
150
+
62
151
  export interface DiscordCredentials {
63
152
  token: string
64
153
  }
65
154
 
66
155
  export interface DiscordConfig {
67
- current_guild: string | null
156
+ current_server: string | null
68
157
  token: string
69
- guilds: Record<
158
+ servers: Record<
70
159
  string,
71
160
  {
72
- guild_id: string
73
- guild_name: string
161
+ server_id: string
162
+ server_name: string
74
163
  }
75
164
  >
76
165
  }
@@ -113,6 +202,14 @@ export const DiscordUserSchema = z.object({
113
202
  bot: z.boolean().optional(),
114
203
  })
115
204
 
205
+ export const DiscordDMChannelSchema = z.object({
206
+ id: z.string(),
207
+ type: z.number(),
208
+ last_message_id: z.string().optional(),
209
+ recipients: z.array(DiscordUserSchema),
210
+ name: z.string().optional(),
211
+ })
212
+
116
213
  export const DiscordReactionSchema = z.object({
117
214
  emoji: z.object({
118
215
  id: z.string().optional(),
@@ -131,18 +228,57 @@ export const DiscordFileSchema = z.object({
131
228
  width: z.number().optional(),
132
229
  })
133
230
 
231
+ export const DiscordMentionSchema = z.object({
232
+ id: z.string(),
233
+ channel_id: z.string(),
234
+ author: z.object({
235
+ id: z.string(),
236
+ username: z.string(),
237
+ }),
238
+ content: z.string(),
239
+ timestamp: z.string(),
240
+ mention_everyone: z.boolean(),
241
+ mentions: z.array(DiscordUserSchema),
242
+ guild_id: z.string().optional(),
243
+ })
244
+
245
+ export const DiscordRelationshipSchema = z.object({
246
+ id: z.string(),
247
+ type: z.number(),
248
+ user: DiscordUserSchema,
249
+ nickname: z.string().optional(),
250
+ })
251
+
252
+ export const DiscordSearchResultSchema = z.object({
253
+ id: z.string(),
254
+ channel_id: z.string(),
255
+ guild_id: z.string().optional(),
256
+ content: z.string(),
257
+ author: z.object({
258
+ id: z.string(),
259
+ username: z.string(),
260
+ }),
261
+ timestamp: z.string(),
262
+ hit: z.boolean(),
263
+ })
264
+
265
+ export const DiscordSearchResponseSchema = z.object({
266
+ total_results: z.number(),
267
+ messages: z.array(z.array(DiscordSearchResultSchema)),
268
+ })
269
+
134
270
  export const DiscordCredentialsSchema = z.object({
135
271
  token: z.string(),
136
272
  })
137
273
 
138
274
  export const DiscordConfigSchema = z.object({
139
- current_guild: z.string().nullable(),
275
+ current_server: z.string().nullable(),
140
276
  token: z.string(),
141
- guilds: z.record(
277
+ servers: z.record(
142
278
  z.string(),
143
279
  z.object({
144
- guild_id: z.string(),
145
- guild_name: z.string(),
280
+ server_id: z.string(),
281
+ server_name: z.string(),
146
282
  })
147
283
  ),
148
284
  })
@@ -1,8 +1,8 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
  import { spawn } from 'bun'
3
- import pkg from '../package.json'
4
- import { handleError } from '../src/shared/utils/error-handler'
5
- import { formatOutput } from '../src/shared/utils/output'
3
+ import { handleError } from '@/shared/utils/error-handler'
4
+ import { formatOutput } from '@/shared/utils/output'
5
+ import pkg from '../../../package.json'
6
6
 
7
7
  describe('CLI Framework', () => {
8
8
  describe('formatOutput utility', () => {
@@ -3,12 +3,17 @@
3
3
  import { Command } from 'commander'
4
4
  import pkg from '../../../package.json'
5
5
  import {
6
+ activityCommand,
6
7
  authCommand,
7
8
  channelCommand,
9
+ draftsCommand,
8
10
  fileCommand,
9
11
  messageCommand,
10
12
  reactionCommand,
13
+ savedCommand,
14
+ sectionsCommand,
11
15
  snapshotCommand,
16
+ unreadCommand,
12
17
  userCommand,
13
18
  workspaceCommand,
14
19
  } from './commands/index'
@@ -30,6 +35,11 @@ program.addCommand(userCommand)
30
35
  program.addCommand(reactionCommand)
31
36
  program.addCommand(fileCommand)
32
37
  program.addCommand(snapshotCommand)
38
+ program.addCommand(activityCommand)
39
+ program.addCommand(draftsCommand)
40
+ program.addCommand(savedCommand)
41
+ program.addCommand(sectionsCommand)
42
+ program.addCommand(unreadCommand)
33
43
 
34
44
  program.parse(process.argv)
35
45
 
@@ -1,6 +1,6 @@
1
1
  import { beforeEach, describe, expect, mock, test } from 'bun:test'
2
2
  import type { WebClient } from '@slack/web-api'
3
- import { SlackClient, SlackError } from '../src/platforms/slack/client'
3
+ import { SlackClient, SlackError } from '@/platforms/slack/client'
4
4
 
5
5
  const mockWebClient: any = {
6
6
  conversations: {
@@ -1,5 +1,17 @@
1
1
  import { WebClient } from '@slack/web-api'
2
- import type { SlackChannel, SlackFile, SlackMessage, SlackSearchResult, SlackUser } from './types'
2
+ import type {
3
+ SlackActivityItem,
4
+ SlackChannel,
5
+ SlackChannelSection,
6
+ SlackDraft,
7
+ SlackFile,
8
+ SlackMessage,
9
+ SlackSavedItem,
10
+ SlackSearchResult,
11
+ SlackThreadView,
12
+ SlackUnreadCounts,
13
+ SlackUser,
14
+ } from './types'
3
15
 
4
16
  export class SlackError extends Error {
5
17
  code: string
@@ -463,4 +475,163 @@ export class SlackClient {
463
475
  }
464
476
  })
465
477
  }
478
+
479
+ async getUnreadCounts(): Promise<SlackUnreadCounts> {
480
+ return this.withRetry(async () => {
481
+ const response = await (this.client as any).client.counts()
482
+ this.checkResponse(response)
483
+
484
+ const channels = (response.channels || []).map((ch: any) => ({
485
+ id: ch.id || '',
486
+ name: ch.name || '',
487
+ unread_count: ch.unread_count || 0,
488
+ mention_count: ch.mention_count || 0,
489
+ }))
490
+
491
+ return {
492
+ channels,
493
+ total_unread: channels.reduce((sum: number, ch: any) => sum + ch.unread_count, 0),
494
+ total_mentions: channels.reduce((sum: number, ch: any) => sum + ch.mention_count, 0),
495
+ }
496
+ })
497
+ }
498
+
499
+ async getThreadView(channelId: string, ts: string): Promise<SlackThreadView> {
500
+ return this.withRetry(async () => {
501
+ const response = await (this.client as any).subscriptions.thread.getView({
502
+ channel: channelId,
503
+ thread_ts: ts,
504
+ })
505
+ this.checkResponse(response)
506
+
507
+ const view = response.view as any
508
+ return {
509
+ channel_id: view.channel_id || channelId,
510
+ thread_ts: view.thread_ts || ts,
511
+ unread_count: view.unread_count || 0,
512
+ last_read: view.last_read || '',
513
+ subscribed: view.subscribed || false,
514
+ }
515
+ })
516
+ }
517
+
518
+ async markRead(channelId: string, ts: string): Promise<void> {
519
+ return this.withRetry(async () => {
520
+ const response = await this.client.conversations.mark({
521
+ channel: channelId,
522
+ ts,
523
+ })
524
+ this.checkResponse(response)
525
+ })
526
+ }
527
+
528
+ async getActivityFeed(options?: {
529
+ types?: string
530
+ mode?: string
531
+ limit?: number
532
+ }): Promise<SlackActivityItem[]> {
533
+ return this.withRetry(async () => {
534
+ const response = await (this.client as any).activity.feed({
535
+ types: options?.types,
536
+ mode: options?.mode || 'chrono_reads_and_unreads',
537
+ limit: options?.limit || 20,
538
+ })
539
+ this.checkResponse(response)
540
+
541
+ const items = (response.items || []).map((item: any) => ({
542
+ id: item.id || '',
543
+ type: item.type || '',
544
+ channel: item.channel || '',
545
+ ts: item.ts || '',
546
+ text: item.text || '',
547
+ user: item.user || '',
548
+ created: item.created || 0,
549
+ }))
550
+
551
+ return items
552
+ })
553
+ }
554
+
555
+ async getSavedItems(cursor?: string): Promise<{
556
+ items: SlackSavedItem[]
557
+ has_more: boolean
558
+ next_cursor?: string
559
+ }> {
560
+ return this.withRetry(async () => {
561
+ const response = await (this.client as any).apiCall('saved.list', {
562
+ cursor,
563
+ limit: 100,
564
+ })
565
+ this.checkResponse(response)
566
+
567
+ const items = (response.items || []).map((item: any) => ({
568
+ type: item.type || 'message',
569
+ message: {
570
+ ts: item.message?.ts || '',
571
+ text: item.message?.text || '',
572
+ user: item.message?.user,
573
+ username: item.message?.username,
574
+ type: item.message?.type || 'message',
575
+ thread_ts: item.message?.thread_ts,
576
+ reply_count: item.message?.reply_count,
577
+ replies: item.message?.replies,
578
+ edited: item.message?.edited
579
+ ? {
580
+ user: item.message.edited.user || '',
581
+ ts: item.message.edited.ts || '',
582
+ }
583
+ : undefined,
584
+ },
585
+ channel: {
586
+ id: item.channel?.id || '',
587
+ name: item.channel?.name || '',
588
+ },
589
+ date_created: item.date_created || 0,
590
+ }))
591
+
592
+ return {
593
+ items,
594
+ has_more: response.has_more || false,
595
+ next_cursor: response.response_metadata?.next_cursor,
596
+ }
597
+ })
598
+ }
599
+
600
+ async getChannelSections(): Promise<SlackChannelSection[]> {
601
+ return this.withRetry(async () => {
602
+ const response = await (this.client as any).apiCall('users.channelSections.list')
603
+ this.checkResponse(response)
604
+
605
+ const sections = (response as any).channel_sections || []
606
+ return sections.map((section: any) => ({
607
+ id: section.id!,
608
+ name: section.name || '',
609
+ channel_ids: section.channel_ids || [],
610
+ date_created: section.date_created || 0,
611
+ date_updated: section.date_updated || 0,
612
+ }))
613
+ })
614
+ }
615
+
616
+ async getDrafts(cursor?: string): Promise<{ drafts: SlackDraft[]; next_cursor?: string }> {
617
+ return this.withRetry(async () => {
618
+ const response = await this.client.apiCall('drafts.list', {
619
+ cursor,
620
+ })
621
+ this.checkResponse(response)
622
+
623
+ const drafts = ((response as any).drafts || []).map((draft: any) => ({
624
+ id: draft.id || '',
625
+ channel_id: draft.channel_id || '',
626
+ message: draft.message || null,
627
+ date_created: draft.date_created || 0,
628
+ date_updated: draft.date_updated || 0,
629
+ }))
630
+
631
+ return {
632
+ drafts,
633
+ next_cursor: (response as any).response_metadata?.next_cursor,
634
+ }
635
+ })
636
+ }
466
637
  }
@@ -0,0 +1,147 @@
1
+ import { describe, expect, mock, test } from 'bun:test'
2
+ import { Command } from 'commander'
3
+ import { activityCommand } from '@/platforms/slack/commands/activity'
4
+
5
+ describe('activity command', () => {
6
+ describe('list subcommand', () => {
7
+ test('returns activity items', async () => {
8
+ const mockActivityItems = [
9
+ {
10
+ id: 'act_1',
11
+ type: 'thread_reply',
12
+ channel: 'C123',
13
+ ts: '1234567890.123456',
14
+ text: 'New reply in thread',
15
+ user: 'U456',
16
+ created: 1234567890,
17
+ },
18
+ {
19
+ id: 'act_2',
20
+ type: 'message_reaction',
21
+ channel: 'C456',
22
+ ts: '1234567891.123456',
23
+ text: 'Someone reacted to your message',
24
+ user: 'U789',
25
+ created: 1234567891,
26
+ },
27
+ ]
28
+
29
+ const mockGetActivityFeed = mock(() => Promise.resolve(mockActivityItems))
30
+ const result = await mockGetActivityFeed()
31
+
32
+ expect(result).toHaveLength(2)
33
+ expect(result[0].type).toBe('thread_reply')
34
+ expect(result[1].type).toBe('message_reaction')
35
+ })
36
+
37
+ test('respects limit option', async () => {
38
+ const mockActivityItems = [
39
+ {
40
+ id: 'act_1',
41
+ type: 'thread_reply',
42
+ channel: 'C123',
43
+ ts: '1234567890.123456',
44
+ text: 'New reply',
45
+ user: 'U456',
46
+ created: 1234567890,
47
+ },
48
+ ]
49
+
50
+ const mockGetActivityFeed = mock((_options?: { limit?: number }) =>
51
+ Promise.resolve(mockActivityItems)
52
+ )
53
+ const result = await mockGetActivityFeed({ limit: 10 })
54
+
55
+ expect(mockGetActivityFeed).toHaveBeenCalledWith({ limit: 10 })
56
+ expect(result).toHaveLength(1)
57
+ })
58
+
59
+ test('respects unread-only mode', async () => {
60
+ const mockActivityItems = [
61
+ {
62
+ id: 'act_1',
63
+ type: 'at_user',
64
+ channel: 'C123',
65
+ ts: '1234567890.123456',
66
+ text: 'You were mentioned',
67
+ user: 'U456',
68
+ created: 1234567890,
69
+ },
70
+ ]
71
+
72
+ const mockGetActivityFeed = mock((_options?: { mode?: string }) =>
73
+ Promise.resolve(mockActivityItems)
74
+ )
75
+ const result = await mockGetActivityFeed({ mode: 'priority_unreads_v1' })
76
+
77
+ expect(mockGetActivityFeed).toHaveBeenCalledWith({ mode: 'priority_unreads_v1' })
78
+ expect(result).toHaveLength(1)
79
+ })
80
+
81
+ test('respects types filter', async () => {
82
+ const mockActivityItems = [
83
+ {
84
+ id: 'act_1',
85
+ type: 'thread_reply',
86
+ channel: 'C123',
87
+ ts: '1234567890.123456',
88
+ text: 'New reply',
89
+ user: 'U456',
90
+ created: 1234567890,
91
+ },
92
+ ]
93
+
94
+ const mockGetActivityFeed = mock((_options?: { types?: string }) =>
95
+ Promise.resolve(mockActivityItems)
96
+ )
97
+ const result = await mockGetActivityFeed({ types: 'thread_reply,at_user' })
98
+
99
+ expect(mockGetActivityFeed).toHaveBeenCalledWith({ types: 'thread_reply,at_user' })
100
+ expect(result).toHaveLength(1)
101
+ })
102
+
103
+ test('handles empty activity feed', async () => {
104
+ const mockGetActivityFeed = mock(() => Promise.resolve([]))
105
+ const result = await mockGetActivityFeed()
106
+
107
+ expect(result).toHaveLength(0)
108
+ })
109
+ })
110
+
111
+ describe('command structure', () => {
112
+ test('activity command exists', () => {
113
+ expect(activityCommand).toBeInstanceOf(Command)
114
+ })
115
+
116
+ test('activity command has correct name', () => {
117
+ expect(activityCommand.name()).toBe('activity')
118
+ })
119
+
120
+ test('activity command has description', () => {
121
+ expect(activityCommand.description()).toBe('Activity feed commands')
122
+ })
123
+
124
+ test('list subcommand exists', () => {
125
+ const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
126
+ expect(listCmd).toBeDefined()
127
+ })
128
+
129
+ test('list subcommand has --unread option', () => {
130
+ const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
131
+ const unreadOption = listCmd?.options.find((opt) => opt.long === '--unread')
132
+ expect(unreadOption).toBeDefined()
133
+ })
134
+
135
+ test('list subcommand has --limit option', () => {
136
+ const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
137
+ const limitOption = listCmd?.options.find((opt) => opt.long === '--limit')
138
+ expect(limitOption).toBeDefined()
139
+ })
140
+
141
+ test('list subcommand has --types option', () => {
142
+ const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
143
+ const typesOption = listCmd?.options.find((opt) => opt.long === '--types')
144
+ expect(typesOption).toBeDefined()
145
+ })
146
+ })
147
+ })