agent-messenger 1.0.0 → 1.1.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 (330) 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/README.md +16 -14
  6. package/biome.json +33 -1
  7. package/bun.lock +63 -0
  8. package/dist/package.json +8 -4
  9. package/dist/src/cli.d.ts.map +1 -1
  10. package/dist/src/cli.js +4 -1
  11. package/dist/src/cli.js.map +1 -1
  12. package/dist/src/platforms/discord/cli.js +1 -1
  13. package/dist/src/platforms/discord/client.d.ts.map +1 -1
  14. package/dist/src/platforms/discord/client.js +3 -3
  15. package/dist/src/platforms/discord/client.js.map +1 -1
  16. package/dist/src/platforms/discord/commands/user.d.ts.map +1 -1
  17. package/dist/src/platforms/discord/commands/user.js +10 -1
  18. package/dist/src/platforms/discord/commands/user.js.map +1 -1
  19. package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -1
  20. package/dist/src/platforms/discord/credential-manager.js +18 -12
  21. package/dist/src/platforms/discord/credential-manager.js.map +1 -1
  22. package/dist/src/platforms/slack/cli.js +1 -1
  23. package/dist/src/platforms/slack/credential-manager.d.ts.map +1 -1
  24. package/dist/src/platforms/slack/credential-manager.js +20 -6
  25. package/dist/src/platforms/slack/credential-manager.js.map +1 -1
  26. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  27. package/dist/src/platforms/slack/token-extractor.js +34 -9
  28. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  29. package/dist/src/platforms/teams/cli.d.ts.map +1 -0
  30. package/dist/{cli.js → src/platforms/teams/cli.js} +11 -10
  31. package/dist/src/platforms/teams/cli.js.map +1 -0
  32. package/dist/src/platforms/teams/client.d.ts +32 -0
  33. package/dist/src/platforms/teams/client.d.ts.map +1 -0
  34. package/dist/src/platforms/teams/client.js +202 -0
  35. package/dist/src/platforms/teams/client.js.map +1 -0
  36. package/dist/src/platforms/teams/commands/auth.d.ts +14 -0
  37. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -0
  38. package/dist/src/platforms/teams/commands/auth.js +176 -0
  39. package/dist/src/platforms/teams/commands/auth.js.map +1 -0
  40. package/dist/src/platforms/teams/commands/channel.d.ts +13 -0
  41. package/dist/src/platforms/teams/commands/channel.d.ts.map +1 -0
  42. package/dist/src/platforms/teams/commands/channel.js +97 -0
  43. package/dist/src/platforms/teams/commands/channel.js.map +1 -0
  44. package/dist/src/platforms/teams/commands/file.d.ts +12 -0
  45. package/dist/src/platforms/teams/commands/file.d.ts.map +1 -0
  46. package/dist/src/platforms/teams/commands/file.js +104 -0
  47. package/dist/src/platforms/teams/commands/file.js.map +1 -0
  48. package/dist/{commands → src/platforms/teams/commands}/index.d.ts +5 -2
  49. package/dist/src/platforms/teams/commands/index.d.ts.map +1 -0
  50. package/dist/{commands → src/platforms/teams/commands}/index.js +5 -2
  51. package/dist/src/platforms/teams/commands/index.js.map +1 -0
  52. package/dist/src/platforms/teams/commands/message.d.ts +17 -0
  53. package/dist/src/platforms/teams/commands/message.d.ts.map +1 -0
  54. package/dist/src/platforms/teams/commands/message.js +133 -0
  55. package/dist/src/platforms/teams/commands/message.js.map +1 -0
  56. package/dist/src/platforms/teams/commands/reaction.d.ts +9 -0
  57. package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -0
  58. package/dist/src/platforms/teams/commands/reaction.js +68 -0
  59. package/dist/src/platforms/teams/commands/reaction.js.map +1 -0
  60. package/dist/src/platforms/teams/commands/snapshot.d.ts +10 -0
  61. package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -0
  62. package/dist/src/platforms/teams/commands/snapshot.js +85 -0
  63. package/dist/src/platforms/teams/commands/snapshot.js.map +1 -0
  64. package/dist/src/platforms/teams/commands/team.d.ts +18 -0
  65. package/dist/src/platforms/teams/commands/team.d.ts.map +1 -0
  66. package/dist/src/platforms/teams/commands/team.js +130 -0
  67. package/dist/src/platforms/teams/commands/team.js.map +1 -0
  68. package/dist/src/platforms/teams/commands/user.d.ts.map +1 -0
  69. package/dist/src/platforms/teams/commands/user.js +88 -0
  70. package/dist/src/platforms/teams/commands/user.js.map +1 -0
  71. package/dist/src/platforms/teams/credential-manager.d.ts +18 -0
  72. package/dist/src/platforms/teams/credential-manager.d.ts.map +1 -0
  73. package/dist/src/platforms/teams/credential-manager.js +81 -0
  74. package/dist/src/platforms/teams/credential-manager.js.map +1 -0
  75. package/dist/src/platforms/teams/index.d.ts +4 -0
  76. package/dist/src/platforms/teams/index.d.ts.map +1 -0
  77. package/dist/src/platforms/teams/index.js +6 -0
  78. package/dist/src/platforms/teams/index.js.map +1 -0
  79. package/dist/src/platforms/teams/token-extractor.d.ts +36 -0
  80. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -0
  81. package/dist/src/platforms/teams/token-extractor.js +335 -0
  82. package/dist/src/platforms/teams/token-extractor.js.map +1 -0
  83. package/dist/src/platforms/teams/types.d.ts +209 -0
  84. package/dist/src/platforms/teams/types.d.ts.map +1 -0
  85. package/dist/src/platforms/teams/types.js +65 -0
  86. package/dist/src/platforms/teams/types.js.map +1 -0
  87. package/docs/teams.md +321 -0
  88. package/e2e/README.md +256 -0
  89. package/e2e/config.ts +45 -0
  90. package/e2e/discord.e2e.test.ts +252 -0
  91. package/e2e/helpers.ts +107 -0
  92. package/e2e/slack.e2e.test.ts +309 -0
  93. package/package.json +8 -4
  94. package/scripts/postbuild.ts +15 -0
  95. package/skills/agent-teams/SKILL.md +292 -0
  96. package/skills/agent-teams/references/authentication.md +375 -0
  97. package/skills/agent-teams/references/common-patterns.md +596 -0
  98. package/skills/agent-teams/templates/monitor-channel.sh +239 -0
  99. package/skills/agent-teams/templates/post-message.sh +224 -0
  100. package/skills/agent-teams/templates/team-summary.sh +210 -0
  101. package/src/cli.ts +4 -0
  102. package/src/platforms/discord/client.ts +3 -3
  103. package/src/platforms/discord/commands/auth.test.ts +48 -32
  104. package/src/platforms/discord/commands/channel.test.ts +54 -42
  105. package/src/platforms/discord/commands/file.test.ts +40 -53
  106. package/src/platforms/discord/commands/guild.test.ts +47 -27
  107. package/src/platforms/discord/commands/message.test.ts +54 -51
  108. package/src/platforms/discord/commands/reaction.test.ts +54 -42
  109. package/src/platforms/discord/commands/user.ts +12 -1
  110. package/src/platforms/discord/credential-manager.test.ts +137 -136
  111. package/src/platforms/discord/credential-manager.ts +20 -13
  112. package/src/platforms/discord/token-extractor.test.ts +133 -383
  113. package/{tests → src/platforms/slack}/cli.test.ts +3 -3
  114. package/{tests/slack-client.test.ts → src/platforms/slack/client.test.ts} +1 -1
  115. package/{tests → src/platforms/slack}/commands/auth.test.ts +25 -13
  116. package/{tests → src/platforms/slack}/commands/channel.test.ts +2 -2
  117. package/{tests → src/platforms/slack}/commands/file.test.ts +2 -2
  118. package/{tests → src/platforms/slack}/commands/message.test.ts +2 -2
  119. package/{tests → src/platforms/slack}/commands/reaction.test.ts +1 -1
  120. package/{tests → src/platforms/slack}/commands/snapshot.test.ts +117 -105
  121. package/{tests → src/platforms/slack}/commands/user.test.ts +3 -3
  122. package/{tests → src/platforms/slack}/commands/workspace.test.ts +44 -95
  123. package/{tests → src/platforms/slack}/credential-manager.test.ts +2 -2
  124. package/src/platforms/slack/credential-manager.ts +22 -7
  125. package/src/platforms/slack/token-extractor-node-test.ts +40 -0
  126. package/src/platforms/slack/token-extractor-node.test.ts +10 -0
  127. package/src/platforms/slack/token-extractor.ts +36 -10
  128. package/{tests → src/platforms/slack}/types.test.ts +1 -1
  129. package/src/platforms/teams/cli.ts +36 -0
  130. package/src/platforms/teams/client.test.ts +500 -0
  131. package/src/platforms/teams/client.ts +365 -0
  132. package/src/platforms/teams/commands/auth.test.ts +99 -0
  133. package/src/platforms/teams/commands/auth.ts +232 -0
  134. package/src/platforms/teams/commands/channel.test.ts +147 -0
  135. package/src/platforms/teams/commands/channel.ts +129 -0
  136. package/src/platforms/teams/commands/file.test.ts +88 -0
  137. package/src/platforms/teams/commands/file.ts +144 -0
  138. package/src/platforms/teams/commands/index.ts +12 -0
  139. package/src/platforms/teams/commands/message.test.ts +110 -0
  140. package/src/platforms/teams/commands/message.ts +188 -0
  141. package/src/platforms/teams/commands/reaction.test.ts +87 -0
  142. package/src/platforms/teams/commands/reaction.ts +104 -0
  143. package/src/platforms/teams/commands/snapshot.test.ts +35 -0
  144. package/src/platforms/teams/commands/snapshot.ts +115 -0
  145. package/src/platforms/teams/commands/team.test.ts +157 -0
  146. package/src/platforms/teams/commands/team.ts +164 -0
  147. package/src/platforms/teams/commands/user.test.ts +83 -0
  148. package/src/platforms/teams/commands/user.ts +112 -0
  149. package/src/platforms/teams/credential-manager.test.ts +178 -0
  150. package/src/platforms/teams/credential-manager.ts +92 -0
  151. package/src/platforms/teams/index.ts +5 -0
  152. package/src/platforms/teams/token-extractor.test.ts +429 -0
  153. package/src/platforms/teams/token-extractor.ts +462 -0
  154. package/src/platforms/teams/types.test.ts +226 -0
  155. package/src/platforms/teams/types.ts +140 -0
  156. package/tsconfig.json +1 -1
  157. package/dist/cli.d.ts.map +0 -1
  158. package/dist/cli.js.map +0 -1
  159. package/dist/commands/auth.d.ts +0 -3
  160. package/dist/commands/auth.d.ts.map +0 -1
  161. package/dist/commands/auth.js +0 -140
  162. package/dist/commands/auth.js.map +0 -1
  163. package/dist/commands/channel.d.ts +0 -3
  164. package/dist/commands/channel.d.ts.map +0 -1
  165. package/dist/commands/channel.js +0 -118
  166. package/dist/commands/channel.js.map +0 -1
  167. package/dist/commands/file.d.ts +0 -3
  168. package/dist/commands/file.d.ts.map +0 -1
  169. package/dist/commands/file.js +0 -113
  170. package/dist/commands/file.js.map +0 -1
  171. package/dist/commands/index.d.ts.map +0 -1
  172. package/dist/commands/index.js.map +0 -1
  173. package/dist/commands/message.d.ts +0 -3
  174. package/dist/commands/message.d.ts.map +0 -1
  175. package/dist/commands/message.js +0 -214
  176. package/dist/commands/message.js.map +0 -1
  177. package/dist/commands/reaction.d.ts +0 -3
  178. package/dist/commands/reaction.d.ts.map +0 -1
  179. package/dist/commands/reaction.js +0 -100
  180. package/dist/commands/reaction.js.map +0 -1
  181. package/dist/commands/snapshot.d.ts +0 -3
  182. package/dist/commands/snapshot.d.ts.map +0 -1
  183. package/dist/commands/snapshot.js +0 -88
  184. package/dist/commands/snapshot.js.map +0 -1
  185. package/dist/commands/user.d.ts.map +0 -1
  186. package/dist/commands/user.js +0 -96
  187. package/dist/commands/user.js.map +0 -1
  188. package/dist/commands/workspace.d.ts +0 -3
  189. package/dist/commands/workspace.d.ts.map +0 -1
  190. package/dist/commands/workspace.js +0 -89
  191. package/dist/commands/workspace.js.map +0 -1
  192. package/dist/lib/credential-manager.d.ts +0 -13
  193. package/dist/lib/credential-manager.d.ts.map +0 -1
  194. package/dist/lib/credential-manager.js +0 -58
  195. package/dist/lib/credential-manager.js.map +0 -1
  196. package/dist/lib/index.d.ts +0 -3
  197. package/dist/lib/index.d.ts.map +0 -1
  198. package/dist/lib/index.js +0 -3
  199. package/dist/lib/index.js.map +0 -1
  200. package/dist/lib/ref-manager.d.ts +0 -26
  201. package/dist/lib/ref-manager.d.ts.map +0 -1
  202. package/dist/lib/ref-manager.js +0 -92
  203. package/dist/lib/ref-manager.js.map +0 -1
  204. package/dist/lib/slack-client.d.ts +0 -37
  205. package/dist/lib/slack-client.d.ts.map +0 -1
  206. package/dist/lib/slack-client.js +0 -379
  207. package/dist/lib/slack-client.js.map +0 -1
  208. package/dist/lib/token-extractor.d.ts +0 -28
  209. package/dist/lib/token-extractor.d.ts.map +0 -1
  210. package/dist/lib/token-extractor.js +0 -401
  211. package/dist/lib/token-extractor.js.map +0 -1
  212. package/dist/src/platforms/discord/client.test.d.ts +0 -2
  213. package/dist/src/platforms/discord/client.test.d.ts.map +0 -1
  214. package/dist/src/platforms/discord/client.test.js +0 -367
  215. package/dist/src/platforms/discord/client.test.js.map +0 -1
  216. package/dist/src/platforms/discord/commands/auth.test.d.ts +0 -2
  217. package/dist/src/platforms/discord/commands/auth.test.d.ts.map +0 -1
  218. package/dist/src/platforms/discord/commands/auth.test.js +0 -65
  219. package/dist/src/platforms/discord/commands/auth.test.js.map +0 -1
  220. package/dist/src/platforms/discord/commands/channel.test.d.ts +0 -2
  221. package/dist/src/platforms/discord/commands/channel.test.d.ts.map +0 -1
  222. package/dist/src/platforms/discord/commands/channel.test.js +0 -136
  223. package/dist/src/platforms/discord/commands/channel.test.js.map +0 -1
  224. package/dist/src/platforms/discord/commands/file.test.d.ts +0 -2
  225. package/dist/src/platforms/discord/commands/file.test.d.ts.map +0 -1
  226. package/dist/src/platforms/discord/commands/file.test.js +0 -83
  227. package/dist/src/platforms/discord/commands/file.test.js.map +0 -1
  228. package/dist/src/platforms/discord/commands/guild.test.d.ts +0 -2
  229. package/dist/src/platforms/discord/commands/guild.test.d.ts.map +0 -1
  230. package/dist/src/platforms/discord/commands/guild.test.js +0 -100
  231. package/dist/src/platforms/discord/commands/guild.test.js.map +0 -1
  232. package/dist/src/platforms/discord/commands/message.test.d.ts +0 -2
  233. package/dist/src/platforms/discord/commands/message.test.d.ts.map +0 -1
  234. package/dist/src/platforms/discord/commands/message.test.js +0 -91
  235. package/dist/src/platforms/discord/commands/message.test.js.map +0 -1
  236. package/dist/src/platforms/discord/commands/reaction.test.d.ts +0 -2
  237. package/dist/src/platforms/discord/commands/reaction.test.d.ts.map +0 -1
  238. package/dist/src/platforms/discord/commands/reaction.test.js +0 -115
  239. package/dist/src/platforms/discord/commands/reaction.test.js.map +0 -1
  240. package/dist/src/platforms/discord/commands/snapshot.test.d.ts +0 -2
  241. package/dist/src/platforms/discord/commands/snapshot.test.d.ts.map +0 -1
  242. package/dist/src/platforms/discord/commands/snapshot.test.js +0 -25
  243. package/dist/src/platforms/discord/commands/snapshot.test.js.map +0 -1
  244. package/dist/src/platforms/discord/commands/user.test.d.ts +0 -2
  245. package/dist/src/platforms/discord/commands/user.test.d.ts.map +0 -1
  246. package/dist/src/platforms/discord/commands/user.test.js +0 -103
  247. package/dist/src/platforms/discord/commands/user.test.js.map +0 -1
  248. package/dist/src/platforms/discord/credential-manager.test.d.ts +0 -2
  249. package/dist/src/platforms/discord/credential-manager.test.d.ts.map +0 -1
  250. package/dist/src/platforms/discord/credential-manager.test.js +0 -136
  251. package/dist/src/platforms/discord/credential-manager.test.js.map +0 -1
  252. package/dist/src/platforms/discord/token-extractor.test.d.ts +0 -2
  253. package/dist/src/platforms/discord/token-extractor.test.d.ts.map +0 -1
  254. package/dist/src/platforms/discord/token-extractor.test.js +0 -789
  255. package/dist/src/platforms/discord/token-extractor.test.js.map +0 -1
  256. package/dist/src/platforms/discord/types.test.d.ts +0 -2
  257. package/dist/src/platforms/discord/types.test.d.ts.map +0 -1
  258. package/dist/src/platforms/discord/types.test.js +0 -211
  259. package/dist/src/platforms/discord/types.test.js.map +0 -1
  260. package/dist/src/shared/utils/concurrency.test.d.ts +0 -2
  261. package/dist/src/shared/utils/concurrency.test.d.ts.map +0 -1
  262. package/dist/src/shared/utils/concurrency.test.js +0 -39
  263. package/dist/src/shared/utils/concurrency.test.js.map +0 -1
  264. package/dist/tests/cli.test.d.ts +0 -2
  265. package/dist/tests/cli.test.d.ts.map +0 -1
  266. package/dist/tests/cli.test.js +0 -83
  267. package/dist/tests/cli.test.js.map +0 -1
  268. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/CURRENT +0 -1
  269. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOCK +0 -0
  270. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG +0 -3
  271. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG.old +0 -1
  272. package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/MANIFEST-000004 +0 -0
  273. package/dist/tests/commands/auth.test.d.ts +0 -2
  274. package/dist/tests/commands/auth.test.d.ts.map +0 -1
  275. package/dist/tests/commands/auth.test.js +0 -304
  276. package/dist/tests/commands/auth.test.js.map +0 -1
  277. package/dist/tests/commands/channel.test.d.ts +0 -2
  278. package/dist/tests/commands/channel.test.d.ts.map +0 -1
  279. package/dist/tests/commands/channel.test.js +0 -166
  280. package/dist/tests/commands/channel.test.js.map +0 -1
  281. package/dist/tests/commands/file.test.d.ts +0 -2
  282. package/dist/tests/commands/file.test.d.ts.map +0 -1
  283. package/dist/tests/commands/file.test.js +0 -175
  284. package/dist/tests/commands/file.test.js.map +0 -1
  285. package/dist/tests/commands/message.test.d.ts +0 -2
  286. package/dist/tests/commands/message.test.d.ts.map +0 -1
  287. package/dist/tests/commands/message.test.js +0 -293
  288. package/dist/tests/commands/message.test.js.map +0 -1
  289. package/dist/tests/commands/reaction.test.d.ts +0 -2
  290. package/dist/tests/commands/reaction.test.d.ts.map +0 -1
  291. package/dist/tests/commands/reaction.test.js +0 -84
  292. package/dist/tests/commands/reaction.test.js.map +0 -1
  293. package/dist/tests/commands/snapshot.test.d.ts +0 -2
  294. package/dist/tests/commands/snapshot.test.d.ts.map +0 -1
  295. package/dist/tests/commands/snapshot.test.js +0 -280
  296. package/dist/tests/commands/snapshot.test.js.map +0 -1
  297. package/dist/tests/commands/user.test.d.ts +0 -2
  298. package/dist/tests/commands/user.test.d.ts.map +0 -1
  299. package/dist/tests/commands/user.test.js +0 -117
  300. package/dist/tests/commands/user.test.js.map +0 -1
  301. package/dist/tests/commands/workspace.test.d.ts +0 -2
  302. package/dist/tests/commands/workspace.test.d.ts.map +0 -1
  303. package/dist/tests/commands/workspace.test.js +0 -453
  304. package/dist/tests/commands/workspace.test.js.map +0 -1
  305. package/dist/tests/credential-manager.test.d.ts +0 -2
  306. package/dist/tests/credential-manager.test.d.ts.map +0 -1
  307. package/dist/tests/credential-manager.test.js +0 -199
  308. package/dist/tests/credential-manager.test.js.map +0 -1
  309. package/dist/tests/slack-client.test.d.ts +0 -2
  310. package/dist/tests/slack-client.test.d.ts.map +0 -1
  311. package/dist/tests/slack-client.test.js +0 -741
  312. package/dist/tests/slack-client.test.js.map +0 -1
  313. package/dist/tests/types.test.d.ts +0 -2
  314. package/dist/tests/types.test.d.ts.map +0 -1
  315. package/dist/tests/types.test.js +0 -215
  316. package/dist/tests/types.test.js.map +0 -1
  317. package/dist/types/index.d.ts +0 -369
  318. package/dist/types/index.d.ts.map +0 -1
  319. package/dist/types/index.js +0 -92
  320. package/dist/types/index.js.map +0 -1
  321. package/dist/utils/error-handler.d.ts +0 -2
  322. package/dist/utils/error-handler.d.ts.map +0 -1
  323. package/dist/utils/error-handler.js +0 -5
  324. package/dist/utils/error-handler.js.map +0 -1
  325. package/dist/utils/output.d.ts +0 -2
  326. package/dist/utils/output.d.ts.map +0 -1
  327. package/dist/utils/output.js +0 -4
  328. package/dist/utils/output.js.map +0 -1
  329. /package/dist/{cli.d.ts → src/platforms/teams/cli.d.ts} +0 -0
  330. /package/dist/{commands → src/platforms/teams/commands}/user.d.ts +0 -0
@@ -1,173 +1,174 @@
1
- import { afterEach, beforeEach, expect, test } from 'bun:test'
2
- import { existsSync } from 'node:fs'
3
- import { rm } from 'node:fs/promises'
1
+ import { afterAll, describe, expect, test } from 'bun:test'
2
+ import { existsSync, rmSync } from 'node:fs'
4
3
  import { join } from 'node:path'
5
4
  import { DiscordCredentialManager } from './credential-manager'
6
5
 
7
- const TEST_CONFIG_DIR = '/tmp/discord-test-config'
6
+ const testDirs: string[] = []
8
7
 
9
- beforeEach(async () => {
10
- if (existsSync(TEST_CONFIG_DIR)) {
11
- await rm(TEST_CONFIG_DIR, { recursive: true })
12
- }
13
- })
8
+ function setup(): DiscordCredentialManager {
9
+ const testConfigDir = join(
10
+ import.meta.dir,
11
+ `.test-discord-config-${Date.now()}-${Math.random().toString(36).slice(2)}`
12
+ )
13
+ testDirs.push(testConfigDir)
14
+ return new DiscordCredentialManager(testConfigDir)
15
+ }
14
16
 
15
- afterEach(async () => {
16
- if (existsSync(TEST_CONFIG_DIR)) {
17
- await rm(TEST_CONFIG_DIR, { recursive: true })
17
+ afterAll(() => {
18
+ for (const dir of testDirs) {
19
+ rmSync(dir, { recursive: true, force: true })
18
20
  }
19
21
  })
20
22
 
21
- test('load returns default config when file does not exist', async () => {
22
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
23
- const config = await manager.load()
23
+ describe('DiscordCredentialManager', () => {
24
+ test('load returns default config when file does not exist', async () => {
25
+ const manager = setup()
26
+ const config = await manager.load()
24
27
 
25
- expect(config).toEqual({
26
- token: null,
27
- current_guild: null,
28
- guilds: {},
28
+ expect(config).toEqual({
29
+ token: null,
30
+ current_guild: null,
31
+ guilds: {},
32
+ })
29
33
  })
30
- })
31
-
32
- test('save creates config file with correct permissions', async () => {
33
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
34
- const config = {
35
- token: 'test-token',
36
- current_guild: 'guild-123',
37
- guilds: {
38
- 'guild-123': { guild_id: 'guild-123', guild_name: 'Test Guild' },
39
- },
40
- }
41
-
42
- await manager.save(config)
43
-
44
- const credentialsPath = join(TEST_CONFIG_DIR, 'discord-credentials.json')
45
- expect(existsSync(credentialsPath)).toBe(true)
46
-
47
- const file = Bun.file(credentialsPath)
48
- const content = await file.text()
49
- const loaded = JSON.parse(content)
50
- expect(loaded).toEqual(config)
51
- })
52
-
53
- test('getToken returns null when not authenticated', async () => {
54
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
55
- const token = await manager.getToken()
56
34
 
57
- expect(token).toBeNull()
58
- })
59
-
60
- test('setToken saves token to config', async () => {
61
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
62
- await manager.setToken('test-token-123')
63
-
64
- const token = await manager.getToken()
65
- expect(token).toBe('test-token-123')
66
- })
35
+ test('save creates config file with correct permissions', async () => {
36
+ const testConfigDir = join(
37
+ import.meta.dir,
38
+ `.test-discord-config-${Date.now()}-${Math.random().toString(36).slice(2)}`
39
+ )
40
+ testDirs.push(testConfigDir)
41
+ const manager = new DiscordCredentialManager(testConfigDir)
42
+ const config = {
43
+ token: 'test-token',
44
+ current_guild: 'guild-123',
45
+ guilds: {
46
+ 'guild-123': { guild_id: 'guild-123', guild_name: 'Test Guild' },
47
+ },
48
+ }
49
+
50
+ await manager.save(config)
51
+
52
+ const credentialsPath = join(testConfigDir, 'discord-credentials.json')
53
+ expect(existsSync(credentialsPath)).toBe(true)
54
+
55
+ const file = Bun.file(credentialsPath)
56
+ const content = await file.text()
57
+ const loaded = JSON.parse(content)
58
+ expect(loaded).toEqual(config)
59
+ })
67
60
 
68
- test('getToken returns previously set token', async () => {
69
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
70
- await manager.setToken('my-token')
61
+ test('getToken returns null when not authenticated', async () => {
62
+ const manager = setup()
63
+ const token = await manager.getToken()
64
+ expect(token).toBeNull()
65
+ })
71
66
 
72
- const token = await manager.getToken()
73
- expect(token).toBe('my-token')
74
- })
67
+ test('setToken saves token to config', async () => {
68
+ const manager = setup()
69
+ await manager.setToken('test-token-123')
75
70
 
76
- test('clearToken removes token from config', async () => {
77
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
78
- await manager.setToken('test-token')
79
- await manager.clearToken()
71
+ const token = await manager.getToken()
72
+ expect(token).toBe('test-token-123')
73
+ })
80
74
 
81
- const token = await manager.getToken()
82
- expect(token).toBeNull()
83
- })
75
+ test('getToken returns previously set token', async () => {
76
+ const manager = setup()
77
+ await manager.setToken('my-token')
84
78
 
85
- test('getCurrentGuild returns null when not set', async () => {
86
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
87
- const guild = await manager.getCurrentGuild()
79
+ const token = await manager.getToken()
80
+ expect(token).toBe('my-token')
81
+ })
88
82
 
89
- expect(guild).toBeNull()
90
- })
83
+ test('clearToken removes token from config', async () => {
84
+ const manager = setup()
85
+ await manager.setToken('test-token')
86
+ await manager.clearToken()
91
87
 
92
- test('setCurrentGuild saves guild id', async () => {
93
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
94
- await manager.setCurrentGuild('guild-456')
88
+ const token = await manager.getToken()
89
+ expect(token).toBeNull()
90
+ })
95
91
 
96
- const guild = await manager.getCurrentGuild()
97
- expect(guild).toBe('guild-456')
98
- })
92
+ test('getCurrentGuild returns null when not set', async () => {
93
+ const manager = setup()
94
+ const guild = await manager.getCurrentGuild()
95
+ expect(guild).toBeNull()
96
+ })
99
97
 
100
- test('getGuilds returns empty object when no guilds set', async () => {
101
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
102
- const guilds = await manager.getGuilds()
98
+ test('setCurrentGuild saves guild id', async () => {
99
+ const manager = setup()
100
+ await manager.setCurrentGuild('guild-456')
103
101
 
104
- expect(guilds).toEqual({})
105
- })
102
+ const guild = await manager.getCurrentGuild()
103
+ expect(guild).toBe('guild-456')
104
+ })
106
105
 
107
- test('setGuilds saves guilds to config', async () => {
108
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
109
- const guilds = {
110
- 'guild-1': { guild_id: 'guild-1', guild_name: 'Guild One' },
111
- 'guild-2': { guild_id: 'guild-2', guild_name: 'Guild Two' },
112
- }
106
+ test('getGuilds returns empty object when no guilds set', async () => {
107
+ const manager = setup()
108
+ const guilds = await manager.getGuilds()
109
+ expect(guilds).toEqual({})
110
+ })
113
111
 
114
- await manager.setGuilds(guilds)
112
+ test('setGuilds saves guilds to config', async () => {
113
+ const manager = setup()
114
+ const guilds = {
115
+ 'guild-1': { guild_id: 'guild-1', guild_name: 'Guild One' },
116
+ 'guild-2': { guild_id: 'guild-2', guild_name: 'Guild Two' },
117
+ }
115
118
 
116
- const loaded = await manager.getGuilds()
117
- expect(loaded).toEqual(guilds)
118
- })
119
+ await manager.setGuilds(guilds)
119
120
 
120
- test('getCredentials returns null when not authenticated', async () => {
121
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
122
- const creds = await manager.getCredentials()
121
+ const loaded = await manager.getGuilds()
122
+ expect(loaded).toEqual(guilds)
123
+ })
123
124
 
124
- expect(creds).toBeNull()
125
- })
125
+ test('getCredentials returns null when not authenticated', async () => {
126
+ const manager = setup()
127
+ const creds = await manager.getCredentials()
128
+ expect(creds).toBeNull()
129
+ })
126
130
 
127
- test('getCredentials returns null when token exists but no guild selected', async () => {
128
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
129
- await manager.setToken('test-token')
131
+ test('getCredentials returns null when token exists but no guild selected', async () => {
132
+ const manager = setup()
133
+ await manager.setToken('test-token')
130
134
 
131
- const creds = await manager.getCredentials()
132
- expect(creds).toBeNull()
133
- })
135
+ const creds = await manager.getCredentials()
136
+ expect(creds).toBeNull()
137
+ })
134
138
 
135
- test('getCredentials returns null when guild selected but no token', async () => {
136
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
137
- await manager.setCurrentGuild('guild-123')
139
+ test('getCredentials returns null when guild selected but no token', async () => {
140
+ const manager = setup()
141
+ await manager.setCurrentGuild('guild-123')
138
142
 
139
- const creds = await manager.getCredentials()
140
- expect(creds).toBeNull()
141
- })
143
+ const creds = await manager.getCredentials()
144
+ expect(creds).toBeNull()
145
+ })
142
146
 
143
- test('getCredentials returns token and guildId when both are set', async () => {
144
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
145
- await manager.setToken('test-token-xyz')
146
- await manager.setCurrentGuild('guild-789')
147
+ test('getCredentials returns token and guildId when both are set', async () => {
148
+ const manager = setup()
149
+ await manager.setToken('test-token-xyz')
150
+ await manager.setCurrentGuild('guild-789')
147
151
 
148
- const creds = await manager.getCredentials()
149
- expect(creds).toEqual({
150
- token: 'test-token-xyz',
151
- guildId: 'guild-789',
152
+ const creds = await manager.getCredentials()
153
+ expect(creds).toEqual({
154
+ token: 'test-token-xyz',
155
+ guildId: 'guild-789',
156
+ })
152
157
  })
153
- })
154
158
 
155
- test('multiple operations preserve existing data', async () => {
156
- const manager = new DiscordCredentialManager(TEST_CONFIG_DIR)
159
+ test('multiple operations preserve existing data', async () => {
160
+ const manager = setup()
161
+ await manager.setToken('token-1')
162
+ await manager.setCurrentGuild('guild-1')
163
+ const guilds = {
164
+ 'guild-1': { guild_id: 'guild-1', guild_name: 'Guild One' },
165
+ }
166
+ await manager.setGuilds(guilds)
157
167
 
158
- // Set initial data
159
- await manager.setToken('token-1')
160
- await manager.setCurrentGuild('guild-1')
161
- const guilds = {
162
- 'guild-1': { guild_id: 'guild-1', guild_name: 'Guild One' },
163
- }
164
- await manager.setGuilds(guilds)
168
+ await manager.setToken('token-2')
165
169
 
166
- // Update token
167
- await manager.setToken('token-2')
168
-
169
- // Verify all data is preserved
170
- expect(await manager.getToken()).toBe('token-2')
171
- expect(await manager.getCurrentGuild()).toBe('guild-1')
172
- expect(await manager.getGuilds()).toEqual(guilds)
170
+ expect(await manager.getToken()).toBe('token-2')
171
+ expect(await manager.getCurrentGuild()).toBe('guild-1')
172
+ expect(await manager.getGuilds()).toEqual(guilds)
173
+ })
173
174
  })
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from 'node:fs'
2
- import { mkdir } from 'node:fs/promises'
2
+ import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises'
3
3
  import { homedir } from 'node:os'
4
4
  import { join } from 'node:path'
5
5
 
@@ -27,21 +27,24 @@ export class DiscordCredentialManager {
27
27
  }
28
28
  }
29
29
 
30
- const file = Bun.file(this.credentialsPath)
31
- const content = await file.text()
30
+ const content = await readFile(this.credentialsPath, 'utf-8')
32
31
  return JSON.parse(content) as DiscordConfig
33
32
  }
34
33
 
35
34
  async save(config: DiscordConfig): Promise<void> {
36
35
  await mkdir(this.configDir, { recursive: true })
37
36
 
38
- const file = Bun.file(this.credentialsPath)
39
- await Bun.write(file, JSON.stringify(config, null, 2))
40
-
41
- await Bun.spawn(['chmod', '0600', this.credentialsPath]).exited
37
+ await writeFile(this.credentialsPath, JSON.stringify(config, null, 2))
38
+ await chmod(this.credentialsPath, 0o600)
42
39
  }
43
40
 
44
41
  async getToken(): Promise<string | null> {
42
+ // Check env var first (takes precedence over file-based credentials)
43
+ const envToken = process.env.E2E_DISCORD_TOKEN
44
+ if (envToken) {
45
+ return envToken
46
+ }
47
+
45
48
  const config = await this.load()
46
49
  return config.token
47
50
  }
@@ -59,6 +62,12 @@ export class DiscordCredentialManager {
59
62
  }
60
63
 
61
64
  async getCurrentGuild(): Promise<string | null> {
65
+ // Check env var first (takes precedence over file-based credentials)
66
+ const envGuildId = process.env.E2E_DISCORD_GUILD_ID
67
+ if (envGuildId) {
68
+ return envGuildId
69
+ }
70
+
62
71
  const config = await this.load()
63
72
  return config.current_guild
64
73
  }
@@ -81,15 +90,13 @@ export class DiscordCredentialManager {
81
90
  }
82
91
 
83
92
  async getCredentials(): Promise<{ token: string; guildId: string } | null> {
84
- const config = await this.load()
93
+ const token = await this.getToken()
94
+ const guildId = await this.getCurrentGuild()
85
95
 
86
- if (!config.token || !config.current_guild) {
96
+ if (!token || !guildId) {
87
97
  return null
88
98
  }
89
99
 
90
- return {
91
- token: config.token,
92
- guildId: config.current_guild,
93
- }
100
+ return { token, guildId }
94
101
  }
95
102
  }