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
@@ -9,7 +9,7 @@ export async function listAction(options: { pretty?: boolean }): Promise<void> {
9
9
  const credManager = new DiscordCredentialManager()
10
10
  const config = await credManager.load()
11
11
 
12
- if (!config.token || !config.current_guild) {
12
+ if (!config.token || !config.current_server) {
13
13
  console.log(
14
14
  formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
15
15
  )
@@ -17,7 +17,7 @@ export async function listAction(options: { pretty?: boolean }): Promise<void> {
17
17
  }
18
18
 
19
19
  const client = new DiscordClient(config.token)
20
- const channels = await client.listChannels(config.current_guild)
20
+ const channels = await client.listChannels(config.current_server)
21
21
 
22
22
  const textChannels = channels.filter((ch) => ch.type === 0)
23
23
 
@@ -54,7 +54,7 @@ export async function infoAction(channelId: string, options: { pretty?: boolean
54
54
  id: channel.id,
55
55
  name: channel.name,
56
56
  type: channel.type,
57
- guild_id: channel.guild_id,
57
+ server_id: channel.guild_id,
58
58
  topic: channel.topic || null,
59
59
  parent_id: (channel as any).parent_id || null,
60
60
  }
@@ -101,7 +101,7 @@ export const channelCommand = new Command('channel')
101
101
  .description('Channel commands')
102
102
  .addCommand(
103
103
  new Command('list')
104
- .description('List channels in current guild')
104
+ .description('List channels in current server')
105
105
  .option('--pretty', 'Pretty print JSON output')
106
106
  .action(listAction)
107
107
  )
@@ -0,0 +1,146 @@
1
+ import { afterEach, beforeEach, describe, expect, it, mock, spyOn } from 'bun:test'
2
+ import { DiscordClient } from '../client'
3
+ import { DiscordCredentialManager } from '../credential-manager'
4
+ import type { DiscordDMChannel } from '../types'
5
+ import { createAction, listAction } from './dm'
6
+
7
+ let clientListDMChannelsSpy: ReturnType<typeof spyOn>
8
+ let clientCreateDMSpy: ReturnType<typeof spyOn>
9
+ let credManagerLoadSpy: ReturnType<typeof spyOn>
10
+
11
+ const mockChannels: DiscordDMChannel[] = [
12
+ {
13
+ id: '123',
14
+ type: 1,
15
+ recipients: [
16
+ {
17
+ id: '456',
18
+ username: 'testuser',
19
+ },
20
+ ],
21
+ },
22
+ {
23
+ id: '789',
24
+ type: 3,
25
+ name: 'Group Chat',
26
+ recipients: [
27
+ {
28
+ id: '111',
29
+ username: 'user1',
30
+ },
31
+ {
32
+ id: '222',
33
+ username: 'user2',
34
+ },
35
+ ],
36
+ },
37
+ ]
38
+
39
+ beforeEach(() => {
40
+ clientListDMChannelsSpy = spyOn(DiscordClient.prototype, 'listDMChannels').mockResolvedValue(
41
+ mockChannels
42
+ )
43
+
44
+ clientCreateDMSpy = spyOn(DiscordClient.prototype, 'createDM').mockResolvedValue({
45
+ id: '999',
46
+ type: 1,
47
+ recipients: [
48
+ {
49
+ id: '456',
50
+ username: 'newuser',
51
+ },
52
+ ],
53
+ })
54
+
55
+ credManagerLoadSpy = spyOn(DiscordCredentialManager.prototype, 'load').mockResolvedValue({
56
+ token: 'test-token',
57
+ current_server: null,
58
+ servers: {},
59
+ })
60
+ })
61
+
62
+ afterEach(() => {
63
+ clientListDMChannelsSpy?.mockRestore()
64
+ clientCreateDMSpy?.mockRestore()
65
+ credManagerLoadSpy?.mockRestore()
66
+ })
67
+
68
+ describe('dm commands', () => {
69
+ describe('listAction', () => {
70
+ it('should list DM channels', async () => {
71
+ const consoleSpy = mock(() => {})
72
+ const originalLog = console.log
73
+ console.log = consoleSpy
74
+
75
+ await listAction({ pretty: false })
76
+
77
+ console.log = originalLog
78
+
79
+ expect(consoleSpy).toHaveBeenCalled()
80
+ expect(clientListDMChannelsSpy).toHaveBeenCalled()
81
+ })
82
+
83
+ it('should handle authentication error', async () => {
84
+ credManagerLoadSpy.mockResolvedValue({
85
+ token: '',
86
+ current_server: null,
87
+ servers: {},
88
+ })
89
+
90
+ const exitSpy = mock(() => {})
91
+ const originalExit = process.exit
92
+ process.exit = exitSpy as any
93
+
94
+ const consoleSpy = mock(() => {})
95
+ const originalLog = console.log
96
+ console.log = consoleSpy
97
+
98
+ await listAction({ pretty: false })
99
+
100
+ console.log = originalLog
101
+ process.exit = originalExit
102
+
103
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Not authenticated'))
104
+ expect(exitSpy).toHaveBeenCalledWith(1)
105
+ })
106
+ })
107
+
108
+ describe('createAction', () => {
109
+ it('should create a DM channel', async () => {
110
+ const consoleSpy = mock(() => {})
111
+ const originalLog = console.log
112
+ console.log = consoleSpy
113
+
114
+ await createAction('456', { pretty: false })
115
+
116
+ console.log = originalLog
117
+
118
+ expect(consoleSpy).toHaveBeenCalled()
119
+ expect(clientCreateDMSpy).toHaveBeenCalledWith('456')
120
+ })
121
+
122
+ it('should handle authentication error', async () => {
123
+ credManagerLoadSpy.mockResolvedValue({
124
+ token: '',
125
+ current_server: null,
126
+ servers: {},
127
+ })
128
+
129
+ const exitSpy = mock(() => {})
130
+ const originalExit = process.exit
131
+ process.exit = exitSpy as any
132
+
133
+ const consoleSpy = mock(() => {})
134
+ const originalLog = console.log
135
+ console.log = consoleSpy
136
+
137
+ await createAction('456', { pretty: false })
138
+
139
+ console.log = originalLog
140
+ process.exit = originalExit
141
+
142
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Not authenticated'))
143
+ expect(exitSpy).toHaveBeenCalledWith(1)
144
+ })
145
+ })
146
+ })
@@ -0,0 +1,85 @@
1
+ import { Command } from 'commander'
2
+ import { handleError } from '../../../shared/utils/error-handler'
3
+ import { formatOutput } from '../../../shared/utils/output'
4
+ import { DiscordClient } from '../client'
5
+ import { DiscordCredentialManager } from '../credential-manager'
6
+ import type { DiscordDMChannel } from '../types'
7
+
8
+ export async function listAction(options: { pretty?: boolean }): Promise<void> {
9
+ try {
10
+ const credManager = new DiscordCredentialManager()
11
+ const config = await credManager.load()
12
+
13
+ if (!config.token) {
14
+ console.log(
15
+ formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
16
+ )
17
+ process.exit(1)
18
+ }
19
+
20
+ const client = new DiscordClient(config.token)
21
+ const channels = await client.listDMChannels()
22
+
23
+ const output = channels.map((channel: DiscordDMChannel) => ({
24
+ id: channel.id,
25
+ type: channel.type === 1 ? 'DM' : 'Group DM',
26
+ name: channel.name || null,
27
+ recipients: channel.recipients.map((user) => ({
28
+ id: user.id,
29
+ username: user.username,
30
+ })),
31
+ last_message_id: channel.last_message_id || null,
32
+ }))
33
+
34
+ console.log(formatOutput(output, options.pretty))
35
+ } catch (error) {
36
+ handleError(error as Error)
37
+ }
38
+ }
39
+
40
+ export async function createAction(userId: string, options: { pretty?: boolean }): Promise<void> {
41
+ try {
42
+ const credManager = new DiscordCredentialManager()
43
+ const config = await credManager.load()
44
+
45
+ if (!config.token) {
46
+ console.log(
47
+ formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
48
+ )
49
+ process.exit(1)
50
+ }
51
+
52
+ const client = new DiscordClient(config.token)
53
+ const channel = await client.createDM(userId)
54
+
55
+ const output = {
56
+ id: channel.id,
57
+ type: channel.type === 1 ? 'DM' : 'Group DM',
58
+ name: channel.name || null,
59
+ recipients: channel.recipients.map((user) => ({
60
+ id: user.id,
61
+ username: user.username,
62
+ })),
63
+ }
64
+
65
+ console.log(formatOutput(output, options.pretty))
66
+ } catch (error) {
67
+ handleError(error as Error)
68
+ }
69
+ }
70
+
71
+ export const dmCommand = new Command('dm')
72
+ .description('DM channel commands')
73
+ .addCommand(
74
+ new Command('list')
75
+ .description('List DM channels')
76
+ .option('--pretty', 'Pretty print JSON output')
77
+ .action(listAction)
78
+ )
79
+ .addCommand(
80
+ new Command('create')
81
+ .description('Create a DM channel')
82
+ .argument('<user-id>', 'User ID to create DM with')
83
+ .option('--pretty', 'Pretty print JSON output')
84
+ .action(createAction)
85
+ )
@@ -1,64 +1,51 @@
1
- import { beforeEach, expect, mock, test } from 'bun:test'
1
+ import { afterEach, beforeEach, expect, mock, spyOn, test } from 'bun:test'
2
+ import { DiscordClient } from '../client'
3
+ import { DiscordCredentialManager } from '../credential-manager'
2
4
  import { infoAction, listAction, uploadAction } from './file'
3
5
 
4
- mock.module('../client', () => ({
5
- DiscordClient: mock(() => ({
6
- uploadFile: mock(async () => ({
6
+ let clientUploadFileSpy: ReturnType<typeof spyOn>
7
+ let clientListFilesSpy: ReturnType<typeof spyOn>
8
+ let credManagerLoadSpy: ReturnType<typeof spyOn>
9
+
10
+ beforeEach(() => {
11
+ // Spy on DiscordClient.prototype methods
12
+ clientUploadFileSpy = spyOn(DiscordClient.prototype, 'uploadFile').mockResolvedValue({
13
+ id: 'file_123',
14
+ filename: 'test.pdf',
15
+ size: 1024,
16
+ url: 'https://cdn.discordapp.com/attachments/123/456/test.pdf',
17
+ content_type: 'application/pdf',
18
+ })
19
+
20
+ clientListFilesSpy = spyOn(DiscordClient.prototype, 'listFiles').mockResolvedValue([
21
+ {
7
22
  id: 'file_123',
8
23
  filename: 'test.pdf',
9
24
  size: 1024,
10
25
  url: 'https://cdn.discordapp.com/attachments/123/456/test.pdf',
11
26
  content_type: 'application/pdf',
12
- })),
13
- listFiles: mock(async () => [
14
- {
15
- id: 'file_123',
16
- filename: 'test.pdf',
17
- size: 1024,
18
- url: 'https://cdn.discordapp.com/attachments/123/456/test.pdf',
19
- content_type: 'application/pdf',
20
- },
21
- {
22
- id: 'file_124',
23
- filename: 'image.png',
24
- size: 2048,
25
- url: 'https://cdn.discordapp.com/attachments/123/457/image.png',
26
- content_type: 'image/png',
27
- },
28
- ]),
29
- })),
30
- }))
31
-
32
- mock.module('../credential-manager', () => ({
33
- DiscordCredentialManager: mock(() => ({
34
- load: mock(async () => ({
35
- token: 'test_token',
36
- current_guild: 'guild_123',
37
- guilds: {},
38
- })),
39
- })),
40
- }))
41
-
42
- mock.module('../../../shared/utils/output', () => ({
43
- formatOutput: (data: any, pretty?: boolean) => JSON.stringify(data, null, pretty ? 2 : 0),
44
- }))
45
-
46
- mock.module('../../../shared/utils/error-handler', () => ({
47
- handleError: (error: Error) => {
48
- console.error(error.message)
49
- },
50
- }))
51
-
52
- mock.module('node:fs', () => ({
53
- readFileSync: () => Buffer.from('test file content'),
54
- }))
55
-
56
- mock.module('node:path', () => ({
57
- resolve: (path: string) => path,
58
- }))
27
+ },
28
+ {
29
+ id: 'file_124',
30
+ filename: 'image.png',
31
+ size: 2048,
32
+ url: 'https://cdn.discordapp.com/attachments/123/457/image.png',
33
+ content_type: 'image/png',
34
+ },
35
+ ])
36
+
37
+ // Spy on DiscordCredentialManager.prototype methods
38
+ credManagerLoadSpy = spyOn(DiscordCredentialManager.prototype, 'load').mockResolvedValue({
39
+ token: 'test_token',
40
+ current_server: 'server_123',
41
+ servers: {},
42
+ })
43
+ })
59
44
 
60
- beforeEach(() => {
61
- mock.restore()
45
+ afterEach(() => {
46
+ clientUploadFileSpy?.mockRestore()
47
+ clientListFilesSpy?.mockRestore()
48
+ credManagerLoadSpy?.mockRestore()
62
49
  })
63
50
 
64
51
  test('upload: sends multipart request and returns file info', async () => {
@@ -0,0 +1,134 @@
1
+ import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
2
+ import { DiscordClient } from '../client'
3
+ import { DiscordCredentialManager } from '../credential-manager'
4
+
5
+ let clientGetRelationshipsSpy: ReturnType<typeof spyOn>
6
+ let credManagerLoadSpy: ReturnType<typeof spyOn>
7
+
8
+ beforeEach(() => {
9
+ clientGetRelationshipsSpy = spyOn(DiscordClient.prototype, 'getRelationships').mockResolvedValue([
10
+ {
11
+ id: 'rel-1',
12
+ type: 1,
13
+ user: {
14
+ id: 'user-1',
15
+ username: 'alice',
16
+ global_name: 'Alice Smith',
17
+ avatar: 'avatar-hash-1',
18
+ },
19
+ nickname: 'Ally',
20
+ },
21
+ {
22
+ id: 'rel-2',
23
+ type: 1,
24
+ user: {
25
+ id: 'user-2',
26
+ username: 'bob',
27
+ global_name: 'Bob Jones',
28
+ avatar: 'avatar-hash-2',
29
+ },
30
+ },
31
+ {
32
+ id: 'rel-3',
33
+ type: 3,
34
+ user: {
35
+ id: 'user-3',
36
+ username: 'charlie',
37
+ global_name: 'Charlie Brown',
38
+ avatar: 'avatar-hash-3',
39
+ },
40
+ },
41
+ {
42
+ id: 'rel-4',
43
+ type: 2,
44
+ user: {
45
+ id: 'user-4',
46
+ username: 'blocked_user',
47
+ avatar: 'avatar-hash-4',
48
+ },
49
+ },
50
+ ])
51
+
52
+ credManagerLoadSpy = spyOn(DiscordCredentialManager.prototype, 'load').mockResolvedValue({
53
+ token: 'test-token',
54
+ current_server: null,
55
+ servers: {},
56
+ })
57
+ })
58
+
59
+ afterEach(() => {
60
+ clientGetRelationshipsSpy?.mockRestore()
61
+ credManagerLoadSpy?.mockRestore()
62
+ })
63
+
64
+ test('list: returns all relationships', async () => {
65
+ // given: discord client with relationships
66
+ const client = new DiscordClient('test-token')
67
+ const relationships = await client.getRelationships()
68
+
69
+ // when: getting all relationships
70
+ expect(relationships).toBeDefined()
71
+
72
+ // then: all relationships are returned
73
+ expect(relationships).toHaveLength(4)
74
+ })
75
+
76
+ test('list: includes relationship metadata', async () => {
77
+ // given: discord client with relationships
78
+ const client = new DiscordClient('test-token')
79
+ const relationships = await client.getRelationships()
80
+
81
+ // when: checking relationship properties
82
+ const relationship = relationships[0]
83
+
84
+ // then: relationship has id, type, user
85
+ expect(relationship.id).toBeDefined()
86
+ expect(relationship.type).toBeDefined()
87
+ expect(relationship.user).toBeDefined()
88
+ expect(relationship.user.id).toBeDefined()
89
+ expect(relationship.user.username).toBeDefined()
90
+ })
91
+
92
+ test('list: filters friends (type=1)', async () => {
93
+ // given: discord client with relationships
94
+ const client = new DiscordClient('test-token')
95
+ const relationships = await client.getRelationships()
96
+
97
+ // when: filtering friends
98
+ const friends = relationships.filter((r) => r.type === 1)
99
+
100
+ // then: only friends are returned
101
+ expect(friends).toHaveLength(2)
102
+ expect(friends[0].user.username).toBe('alice')
103
+ expect(friends[1].user.username).toBe('bob')
104
+ })
105
+
106
+ test('list: includes optional nickname', async () => {
107
+ // given: discord client with relationships
108
+ const client = new DiscordClient('test-token')
109
+ const relationships = await client.getRelationships()
110
+
111
+ // when: checking for nickname
112
+ const withNickname = relationships.find((r) => r.nickname)
113
+ const withoutNickname = relationships.find((r) => !r.nickname && r.type === 1)
114
+
115
+ // then: nickname is optional
116
+ expect(withNickname?.nickname).toBe('Ally')
117
+ expect(withoutNickname?.nickname).toBeUndefined()
118
+ })
119
+
120
+ test('list: distinguishes relationship types', async () => {
121
+ // given: discord client with relationships
122
+ const client = new DiscordClient('test-token')
123
+ const relationships = await client.getRelationships()
124
+
125
+ // when: grouping by type
126
+ const friends = relationships.filter((r) => r.type === 1)
127
+ const blocked = relationships.filter((r) => r.type === 2)
128
+ const incoming = relationships.filter((r) => r.type === 3)
129
+
130
+ // then: types are correctly identified
131
+ expect(friends).toHaveLength(2)
132
+ expect(blocked).toHaveLength(1)
133
+ expect(incoming).toHaveLength(1)
134
+ })
@@ -0,0 +1,45 @@
1
+ import { Command } from 'commander'
2
+ import { DiscordClient } from '../client'
3
+ import { DiscordCredentialManager } from '../credential-manager'
4
+
5
+ export const friendCommand = new Command('friend')
6
+ .description('Manage Discord relationships (friends)')
7
+ .addCommand(
8
+ new Command('list')
9
+ .description('List all relationships')
10
+ .option('--pretty', 'Pretty print output')
11
+ .action(async (options) => {
12
+ const credManager = new DiscordCredentialManager()
13
+ const config = await credManager.load()
14
+
15
+ if (!config.token) {
16
+ throw new Error('No Discord token found. Run auth extract first.')
17
+ }
18
+
19
+ const client = new DiscordClient(config.token)
20
+
21
+ const relationships = await client.getRelationships()
22
+
23
+ if (options.pretty) {
24
+ const typeNames: Record<number, string> = {
25
+ 1: 'Friend',
26
+ 2: 'Blocked',
27
+ 3: 'Incoming Request',
28
+ 4: 'Outgoing Request',
29
+ }
30
+
31
+ console.log(`\nRelationships (${relationships.length}):\n`)
32
+ for (const rel of relationships) {
33
+ const displayName = rel.user.global_name || rel.user.username
34
+ const nickname = rel.nickname ? ` (${rel.nickname})` : ''
35
+ const type = typeNames[rel.type] || `Type ${rel.type}`
36
+ console.log(` ${displayName}${nickname} - ${type}`)
37
+ console.log(` ID: ${rel.user.id}`)
38
+ console.log(` Username: ${rel.user.username}`)
39
+ console.log()
40
+ }
41
+ } else {
42
+ console.log(JSON.stringify(relationships, null, 2))
43
+ }
44
+ })
45
+ )
@@ -1,8 +1,8 @@
1
1
  export { authCommand } from './auth'
2
2
  export { channelCommand } from './channel'
3
3
  export { fileCommand } from './file'
4
- export { guildCommand } from './guild'
5
4
  export { messageCommand } from './message'
6
5
  export { reactionCommand } from './reaction'
6
+ export { serverCommand } from './server'
7
7
  export { snapshotCommand } from './snapshot'
8
8
  export { userCommand } from './user'
@@ -0,0 +1,98 @@
1
+ import { afterEach, beforeEach, expect, spyOn, test } from 'bun:test'
2
+ import { DiscordClient } from '../client'
3
+ import { DiscordCredentialManager } from '../credential-manager'
4
+
5
+ let clientSearchMembersSpy: ReturnType<typeof spyOn>
6
+ let credManagerLoadSpy: ReturnType<typeof spyOn>
7
+
8
+ beforeEach(() => {
9
+ clientSearchMembersSpy = spyOn(DiscordClient.prototype, 'searchMembers').mockResolvedValue([
10
+ {
11
+ user: {
12
+ id: 'user-1',
13
+ username: 'alice',
14
+ global_name: 'Alice Smith',
15
+ avatar: 'avatar-hash-1',
16
+ bot: false,
17
+ },
18
+ nick: 'AliceNick',
19
+ roles: ['role-1', 'role-2'],
20
+ joined_at: '2024-01-15T10:00:00Z',
21
+ deaf: false,
22
+ mute: false,
23
+ flags: 0,
24
+ },
25
+ {
26
+ user: {
27
+ id: 'user-2',
28
+ username: 'alice_bot',
29
+ global_name: 'Alice Bot',
30
+ avatar: 'avatar-hash-2',
31
+ bot: true,
32
+ },
33
+ nick: undefined,
34
+ roles: ['role-3'],
35
+ joined_at: '2024-02-20T15:30:00Z',
36
+ deaf: false,
37
+ mute: false,
38
+ flags: 0,
39
+ },
40
+ ])
41
+
42
+ credManagerLoadSpy = spyOn(DiscordCredentialManager.prototype, 'load').mockResolvedValue({
43
+ token: 'test-token',
44
+ current_server: 'guild-1',
45
+ servers: {
46
+ 'guild-1': { server_id: 'guild-1', server_name: 'Test Guild' },
47
+ },
48
+ })
49
+ })
50
+
51
+ afterEach(() => {
52
+ clientSearchMembersSpy?.mockRestore()
53
+ credManagerLoadSpy?.mockRestore()
54
+ })
55
+
56
+ test('search: returns members matching query', async () => {
57
+ const client = new DiscordClient('test-token')
58
+ const members = await client.searchMembers('guild-1', 'alice', 10)
59
+
60
+ expect(members).toBeDefined()
61
+ expect(members).toHaveLength(2)
62
+ expect(members[0].user.username).toBe('alice')
63
+ expect(members[1].user.username).toBe('alice_bot')
64
+ })
65
+
66
+ test('search: includes member metadata', async () => {
67
+ const client = new DiscordClient('test-token')
68
+ const members = await client.searchMembers('guild-1', 'alice', 10)
69
+
70
+ const member = members[0]
71
+
72
+ expect(member.user).toBeDefined()
73
+ expect(member.user.id).toBe('user-1')
74
+ expect(member.user.username).toBe('alice')
75
+ expect(member.user.global_name).toBe('Alice Smith')
76
+ expect(member.nick).toBe('AliceNick')
77
+ expect(member.roles).toEqual(['role-1', 'role-2'])
78
+ expect(member.joined_at).toBe('2024-01-15T10:00:00Z')
79
+ expect(member.deaf).toBe(false)
80
+ expect(member.mute).toBe(false)
81
+ expect(member.flags).toBe(0)
82
+ })
83
+
84
+ test('search: respects limit parameter', async () => {
85
+ const client = new DiscordClient('test-token')
86
+
87
+ await client.searchMembers('guild-1', 'alice', 5)
88
+
89
+ expect(clientSearchMembersSpy).toHaveBeenCalledWith('guild-1', 'alice', 5)
90
+ })
91
+
92
+ test('search: uses default limit of 10', async () => {
93
+ const client = new DiscordClient('test-token')
94
+
95
+ const members = await client.searchMembers('guild-1', 'alice')
96
+
97
+ expect(members).toHaveLength(2)
98
+ })