agent-messenger 2.10.1 → 2.10.2

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 (239) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/package.json +1 -1
  3. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
  4. package/dist/src/platforms/teams/token-extractor.js +9 -2
  5. package/dist/src/platforms/teams/token-extractor.js.map +1 -1
  6. package/dist/src/shared/chromium/decryptor.d.ts +6 -0
  7. package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
  8. package/dist/src/shared/chromium/decryptor.js +26 -6
  9. package/dist/src/shared/chromium/decryptor.js.map +1 -1
  10. package/e2e/channeltalk.e2e.test.ts +13 -13
  11. package/e2e/channeltalkbot.e2e.test.ts +13 -13
  12. package/e2e/discord.e2e.test.ts +24 -24
  13. package/e2e/discordbot.e2e.test.ts +16 -16
  14. package/e2e/instagram.e2e.test.ts +10 -10
  15. package/e2e/kakaotalk.e2e.test.ts +7 -7
  16. package/e2e/line.e2e.test.ts +8 -8
  17. package/e2e/slack.e2e.test.ts +34 -34
  18. package/e2e/slackbot.e2e.test.ts +14 -14
  19. package/e2e/teams.e2e.test.ts +23 -23
  20. package/e2e/telegram.e2e.test.ts +8 -8
  21. package/e2e/webex.e2e.test.ts +14 -14
  22. package/e2e/whatsapp.e2e.test.ts +8 -8
  23. package/e2e/whatsappbot.e2e.test.ts +6 -6
  24. package/package.json +1 -1
  25. package/skills/agent-channeltalk/SKILL.md +1 -1
  26. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  27. package/skills/agent-discord/SKILL.md +1 -1
  28. package/skills/agent-discordbot/SKILL.md +1 -1
  29. package/skills/agent-instagram/SKILL.md +1 -1
  30. package/skills/agent-kakaotalk/SKILL.md +1 -1
  31. package/skills/agent-line/SKILL.md +1 -1
  32. package/skills/agent-slack/SKILL.md +1 -1
  33. package/skills/agent-slackbot/SKILL.md +1 -1
  34. package/skills/agent-teams/SKILL.md +1 -1
  35. package/skills/agent-telegram/SKILL.md +1 -1
  36. package/skills/agent-webex/SKILL.md +1 -1
  37. package/skills/agent-wechatbot/SKILL.md +1 -1
  38. package/skills/agent-whatsapp/SKILL.md +1 -1
  39. package/skills/agent-whatsappbot/SKILL.md +1 -1
  40. package/src/platforms/channeltalk/client.test.ts +26 -26
  41. package/src/platforms/channeltalk/commands/auth.test.ts +16 -16
  42. package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
  43. package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
  44. package/src/platforms/channeltalk/commands/group.test.ts +4 -4
  45. package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
  46. package/src/platforms/channeltalk/commands/message.test.ts +17 -17
  47. package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
  48. package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
  49. package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
  50. package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
  51. package/src/platforms/channeltalk/index.test.ts +23 -23
  52. package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
  53. package/src/platforms/channeltalk/types.test.ts +12 -12
  54. package/src/platforms/channeltalkbot/client.test.ts +14 -14
  55. package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
  56. package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
  57. package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
  58. package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
  59. package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
  60. package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
  61. package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
  62. package/src/platforms/channeltalkbot/commands/whoami.test.ts +4 -4
  63. package/src/platforms/channeltalkbot/credential-manager.test.ts +27 -27
  64. package/src/platforms/channeltalkbot/index.test.ts +15 -15
  65. package/src/platforms/discord/client.test.ts +28 -28
  66. package/src/platforms/discord/commands/auth.test.ts +7 -7
  67. package/src/platforms/discord/commands/channel.test.ts +7 -7
  68. package/src/platforms/discord/commands/dm.test.ts +4 -4
  69. package/src/platforms/discord/commands/file.test.ts +4 -4
  70. package/src/platforms/discord/commands/friend.test.ts +6 -6
  71. package/src/platforms/discord/commands/member.test.ts +5 -5
  72. package/src/platforms/discord/commands/mention.test.ts +5 -5
  73. package/src/platforms/discord/commands/message.test.ts +9 -9
  74. package/src/platforms/discord/commands/note.test.ts +6 -6
  75. package/src/platforms/discord/commands/profile.test.ts +4 -4
  76. package/src/platforms/discord/commands/reaction.test.ts +5 -5
  77. package/src/platforms/discord/commands/server.test.ts +7 -7
  78. package/src/platforms/discord/commands/snapshot.test.ts +6 -6
  79. package/src/platforms/discord/commands/thread.test.ts +6 -6
  80. package/src/platforms/discord/commands/user.test.ts +5 -5
  81. package/src/platforms/discord/commands/whoami.test.ts +6 -6
  82. package/src/platforms/discord/credential-manager.test.ts +16 -16
  83. package/src/platforms/discord/ensure-auth.test.ts +8 -8
  84. package/src/platforms/discord/index.test.ts +17 -17
  85. package/src/platforms/discord/listener.test.ts +33 -33
  86. package/src/platforms/discord/token-extractor.test.ts +53 -53
  87. package/src/platforms/discord/types.test.ts +26 -26
  88. package/src/platforms/discordbot/client.test.ts +31 -31
  89. package/src/platforms/discordbot/commands/auth.test.ts +18 -18
  90. package/src/platforms/discordbot/commands/channel.test.ts +11 -11
  91. package/src/platforms/discordbot/commands/file.test.ts +7 -7
  92. package/src/platforms/discordbot/commands/message.test.ts +25 -25
  93. package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
  94. package/src/platforms/discordbot/commands/server.test.ts +12 -12
  95. package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
  96. package/src/platforms/discordbot/commands/thread.test.ts +10 -10
  97. package/src/platforms/discordbot/commands/user.test.ts +9 -9
  98. package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
  99. package/src/platforms/discordbot/credential-manager.test.ts +28 -28
  100. package/src/platforms/instagram/client.test.ts +18 -18
  101. package/src/platforms/instagram/commands/auth.test.ts +11 -11
  102. package/src/platforms/instagram/commands/chat.test.ts +6 -6
  103. package/src/platforms/instagram/commands/message.test.ts +11 -11
  104. package/src/platforms/instagram/commands/shared.test.ts +12 -12
  105. package/src/platforms/instagram/commands/whoami.test.ts +3 -3
  106. package/src/platforms/instagram/credential-manager.test.ts +21 -21
  107. package/src/platforms/instagram/ensure-auth.test.ts +4 -4
  108. package/src/platforms/instagram/index.test.ts +9 -9
  109. package/src/platforms/instagram/listener.test.ts +8 -8
  110. package/src/platforms/instagram/token-extractor.test.ts +35 -35
  111. package/src/platforms/kakaotalk/client.test.ts +33 -33
  112. package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
  113. package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
  114. package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
  115. package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
  116. package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
  117. package/src/platforms/kakaotalk/index.test.ts +15 -15
  118. package/src/platforms/kakaotalk/listener.test.ts +17 -17
  119. package/src/platforms/line/client.test.ts +17 -17
  120. package/src/platforms/line/commands/auth.test.ts +8 -8
  121. package/src/platforms/line/commands/chat.test.ts +7 -7
  122. package/src/platforms/line/commands/friend.test.ts +6 -6
  123. package/src/platforms/line/commands/message.test.ts +7 -7
  124. package/src/platforms/line/commands/whoami.test.ts +6 -6
  125. package/src/platforms/line/credential-manager.test.ts +17 -17
  126. package/src/platforms/line/index.test.ts +10 -10
  127. package/src/platforms/line/listener.test.ts +15 -15
  128. package/src/platforms/line/types.test.ts +14 -14
  129. package/src/platforms/slack/cli.test.ts +8 -8
  130. package/src/platforms/slack/client.test.ts +151 -151
  131. package/src/platforms/slack/commands/activity.test.ts +13 -13
  132. package/src/platforms/slack/commands/auth.test.ts +34 -34
  133. package/src/platforms/slack/commands/bookmark.test.ts +9 -9
  134. package/src/platforms/slack/commands/channel.test.ts +17 -17
  135. package/src/platforms/slack/commands/drafts.test.ts +7 -7
  136. package/src/platforms/slack/commands/emoji.test.ts +3 -3
  137. package/src/platforms/slack/commands/file.test.ts +12 -12
  138. package/src/platforms/slack/commands/message.test.ts +19 -19
  139. package/src/platforms/slack/commands/pin.test.ts +7 -7
  140. package/src/platforms/slack/commands/reaction.test.ts +10 -10
  141. package/src/platforms/slack/commands/reminder.test.ts +9 -9
  142. package/src/platforms/slack/commands/saved.test.ts +7 -7
  143. package/src/platforms/slack/commands/sections.test.ts +5 -5
  144. package/src/platforms/slack/commands/snapshot.test.ts +13 -13
  145. package/src/platforms/slack/commands/unread.test.ts +6 -6
  146. package/src/platforms/slack/commands/user.test.ts +10 -10
  147. package/src/platforms/slack/commands/usergroup.test.ts +15 -15
  148. package/src/platforms/slack/commands/whoami.test.ts +6 -6
  149. package/src/platforms/slack/commands/workspace.test.ts +26 -26
  150. package/src/platforms/slack/credential-manager.test.ts +14 -14
  151. package/src/platforms/slack/ensure-auth.test.ts +21 -21
  152. package/src/platforms/slack/index.test.ts +12 -12
  153. package/src/platforms/slack/listener.test.ts +17 -17
  154. package/src/platforms/slack/token-extractor-node.test.ts +2 -2
  155. package/src/platforms/slack/token-extractor.test.ts +37 -37
  156. package/src/platforms/slack/types.test.ts +21 -21
  157. package/src/platforms/slackbot/client.test.ts +22 -22
  158. package/src/platforms/slackbot/commands/auth.test.ts +14 -14
  159. package/src/platforms/slackbot/commands/channel.test.ts +7 -7
  160. package/src/platforms/slackbot/commands/message.test.ts +13 -13
  161. package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
  162. package/src/platforms/slackbot/commands/user.test.ts +7 -7
  163. package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
  164. package/src/platforms/slackbot/credential-manager.test.ts +22 -22
  165. package/src/platforms/slackbot/types.test.ts +7 -7
  166. package/src/platforms/teams/client.test.ts +30 -30
  167. package/src/platforms/teams/commands/auth.test.ts +8 -8
  168. package/src/platforms/teams/commands/channel.test.ts +7 -7
  169. package/src/platforms/teams/commands/file.test.ts +4 -4
  170. package/src/platforms/teams/commands/message.test.ts +5 -5
  171. package/src/platforms/teams/commands/reaction.test.ts +4 -4
  172. package/src/platforms/teams/commands/snapshot.test.ts +7 -7
  173. package/src/platforms/teams/commands/team.test.ts +8 -8
  174. package/src/platforms/teams/commands/user.test.ts +4 -4
  175. package/src/platforms/teams/commands/whoami.test.ts +6 -6
  176. package/src/platforms/teams/credential-manager.test.ts +17 -17
  177. package/src/platforms/teams/ensure-auth.test.ts +13 -13
  178. package/src/platforms/teams/index.test.ts +15 -15
  179. package/src/platforms/teams/token-extractor.test.ts +109 -49
  180. package/src/platforms/teams/token-extractor.ts +7 -2
  181. package/src/platforms/teams/types.test.ts +26 -26
  182. package/src/platforms/telegram/app-config.test.ts +4 -4
  183. package/src/platforms/telegram/chat-utils.test.ts +12 -12
  184. package/src/platforms/telegram/client.test.ts +4 -4
  185. package/src/platforms/telegram/commands/auth.test.ts +16 -16
  186. package/src/platforms/telegram/commands/chat.test.ts +9 -9
  187. package/src/platforms/telegram/commands/message.test.ts +6 -6
  188. package/src/platforms/telegram/commands/shared.test.ts +3 -3
  189. package/src/platforms/telegram/commands/whoami.test.ts +3 -3
  190. package/src/platforms/telegram/credential-manager.test.ts +10 -10
  191. package/src/platforms/telegram/types.test.ts +6 -6
  192. package/src/platforms/webex/app-config.test.ts +8 -8
  193. package/src/platforms/webex/cli.test.ts +5 -5
  194. package/src/platforms/webex/client.test.ts +65 -65
  195. package/src/platforms/webex/commands/auth.test.ts +18 -18
  196. package/src/platforms/webex/commands/member.test.ts +5 -5
  197. package/src/platforms/webex/commands/message.test.ts +12 -12
  198. package/src/platforms/webex/commands/snapshot.test.ts +5 -5
  199. package/src/platforms/webex/commands/space.test.ts +10 -10
  200. package/src/platforms/webex/commands/whoami.test.ts +6 -6
  201. package/src/platforms/webex/credential-manager.test.ts +22 -22
  202. package/src/platforms/webex/encryption.test.ts +4 -4
  203. package/src/platforms/webex/ensure-auth.test.ts +5 -5
  204. package/src/platforms/webex/index.test.ts +5 -5
  205. package/src/platforms/webex/markdown-to-html.test.ts +33 -33
  206. package/src/platforms/webex/token-extractor.test.ts +23 -23
  207. package/src/platforms/webex/types.test.ts +27 -27
  208. package/src/platforms/wechatbot/client.test.ts +27 -27
  209. package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
  210. package/src/platforms/wechatbot/commands/message.test.ts +8 -8
  211. package/src/platforms/wechatbot/commands/template.test.ts +9 -9
  212. package/src/platforms/wechatbot/commands/user.test.ts +7 -7
  213. package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
  214. package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
  215. package/src/platforms/wechatbot/index.test.ts +10 -10
  216. package/src/platforms/wechatbot/types.test.ts +25 -25
  217. package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
  218. package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
  219. package/src/platforms/whatsapp/commands/message.test.ts +10 -10
  220. package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
  221. package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
  222. package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
  223. package/src/platforms/whatsapp/index.test.ts +8 -8
  224. package/src/platforms/whatsapp/types.test.ts +42 -42
  225. package/src/platforms/whatsappbot/client.test.ts +27 -27
  226. package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
  227. package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
  228. package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
  229. package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
  230. package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
  231. package/src/platforms/whatsappbot/index.test.ts +7 -7
  232. package/src/platforms/whatsappbot/types.test.ts +18 -18
  233. package/src/shared/chromium/browsers.test.ts +22 -22
  234. package/src/shared/chromium/cookie-reader.test.ts +13 -13
  235. package/src/shared/chromium/decryptor.test.ts +97 -32
  236. package/src/shared/chromium/decryptor.ts +27 -6
  237. package/src/shared/utils/concurrency.test.ts +6 -6
  238. package/src/shared/utils/derived-key-cache.test.ts +11 -11
  239. package/src/tui/utils.test.ts +31 -31
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
2
  import { existsSync, rmSync } from 'node:fs'
3
3
  import { mkdir, stat } from 'node:fs/promises'
4
4
  import { tmpdir } from 'node:os'
@@ -38,7 +38,7 @@ describe('DiscordBotCredentialManager', () => {
38
38
  })
39
39
 
40
40
  describe('load', () => {
41
- test('returns empty config when no file exists', async () => {
41
+ it('returns empty config when no file exists', async () => {
42
42
  const config = await manager.load()
43
43
 
44
44
  expect(config.current).toBeNull()
@@ -49,7 +49,7 @@ describe('DiscordBotCredentialManager', () => {
49
49
  })
50
50
 
51
51
  describe('save and load', () => {
52
- test('persists config to file', async () => {
52
+ it('persists config to file', async () => {
53
53
  const config = {
54
54
  current: { bot_id: 'bot-123' },
55
55
  bots: {
@@ -67,11 +67,11 @@ describe('DiscordBotCredentialManager', () => {
67
67
  })
68
68
 
69
69
  describe('getCredentials', () => {
70
- test('returns null when no credentials exist', async () => {
70
+ it('returns null when no credentials exist', async () => {
71
71
  expect(await manager.getCredentials()).toBeNull()
72
72
  })
73
73
 
74
- test('returns current bot credentials', async () => {
74
+ it('returns current bot credentials', async () => {
75
75
  await manager.setCredentials(CREDS_A)
76
76
 
77
77
  const creds = await manager.getCredentials()
@@ -79,7 +79,7 @@ describe('DiscordBotCredentialManager', () => {
79
79
  expect(creds).toEqual(CREDS_A)
80
80
  })
81
81
 
82
- test('returns specific bot by id', async () => {
82
+ it('returns specific bot by id', async () => {
83
83
  await manager.setCredentials(CREDS_A)
84
84
  await manager.setCredentials(CREDS_B)
85
85
 
@@ -88,7 +88,7 @@ describe('DiscordBotCredentialManager', () => {
88
88
  expect(creds).toEqual(CREDS_A)
89
89
  })
90
90
 
91
- test('returns null for non-existent bot id', async () => {
91
+ it('returns null for non-existent bot id', async () => {
92
92
  await manager.setCredentials(CREDS_A)
93
93
 
94
94
  const creds = await manager.getCredentials('nonexistent')
@@ -96,7 +96,7 @@ describe('DiscordBotCredentialManager', () => {
96
96
  expect(creds).toBeNull()
97
97
  })
98
98
 
99
- test('env vars take precedence when no botId specified', async () => {
99
+ it('env vars take precedence when no botId specified', async () => {
100
100
  await manager.setCredentials(CREDS_A)
101
101
 
102
102
  process.env.E2E_DISCORDBOT_TOKEN = 'env-token'
@@ -112,7 +112,7 @@ describe('DiscordBotCredentialManager', () => {
112
112
  expect(creds?.server_name).toBe('Env Server')
113
113
  })
114
114
 
115
- test('env vars ignored when botId explicitly provided', async () => {
115
+ it('env vars ignored when botId explicitly provided', async () => {
116
116
  await manager.setCredentials(CREDS_A)
117
117
 
118
118
  process.env.E2E_DISCORDBOT_TOKEN = 'env-token'
@@ -124,7 +124,7 @@ describe('DiscordBotCredentialManager', () => {
124
124
  expect(creds?.bot_id).toBe('bot-123')
125
125
  })
126
126
 
127
- test('env vars use default server name when not provided', async () => {
127
+ it('env vars use default server name when not provided', async () => {
128
128
  process.env.E2E_DISCORDBOT_TOKEN = 'env-token'
129
129
  process.env.E2E_DISCORDBOT_SERVER_ID = 'server-789'
130
130
  delete process.env.E2E_DISCORDBOT_SERVER_NAME
@@ -136,7 +136,7 @@ describe('DiscordBotCredentialManager', () => {
136
136
  })
137
137
 
138
138
  describe('setCredentials', () => {
139
- test('stores bot and sets as current', async () => {
139
+ it('stores bot and sets as current', async () => {
140
140
  await manager.setCredentials(CREDS_A)
141
141
 
142
142
  const config = await manager.load()
@@ -144,7 +144,7 @@ describe('DiscordBotCredentialManager', () => {
144
144
  expect(config.bots['bot-123'].token).toBe('bot-token-a')
145
145
  })
146
146
 
147
- test('stores multiple bots', async () => {
147
+ it('stores multiple bots', async () => {
148
148
  await manager.setCredentials(CREDS_A)
149
149
  await manager.setCredentials(CREDS_B)
150
150
 
@@ -153,7 +153,7 @@ describe('DiscordBotCredentialManager', () => {
153
153
  expect(config.current).toEqual({ bot_id: 'bot-456' })
154
154
  })
155
155
 
156
- test('overwrites existing bot with same id', async () => {
156
+ it('overwrites existing bot with same id', async () => {
157
157
  await manager.setCredentials(CREDS_A)
158
158
  const updated = { ...CREDS_A, bot_name: 'Updated Bot A' }
159
159
  await manager.setCredentials(updated)
@@ -165,7 +165,7 @@ describe('DiscordBotCredentialManager', () => {
165
165
  })
166
166
 
167
167
  describe('listAll', () => {
168
- test('returns all bots with current flag', async () => {
168
+ it('returns all bots with current flag', async () => {
169
169
  await manager.setCredentials(CREDS_A)
170
170
  await manager.setCredentials(CREDS_B)
171
171
 
@@ -176,7 +176,7 @@ describe('DiscordBotCredentialManager', () => {
176
176
  expect(all.find((b) => b.bot_id === 'bot-456')?.is_current).toBe(true)
177
177
  })
178
178
 
179
- test('returns empty array when no bots exist', async () => {
179
+ it('returns empty array when no bots exist', async () => {
180
180
  const all = await manager.listAll()
181
181
 
182
182
  expect(all).toEqual([])
@@ -184,7 +184,7 @@ describe('DiscordBotCredentialManager', () => {
184
184
  })
185
185
 
186
186
  describe('setCurrent', () => {
187
- test('switches current bot', async () => {
187
+ it('switches current bot', async () => {
188
188
  await manager.setCredentials(CREDS_A)
189
189
  await manager.setCredentials(CREDS_B)
190
190
 
@@ -195,13 +195,13 @@ describe('DiscordBotCredentialManager', () => {
195
195
  expect(creds?.bot_id).toBe('bot-123')
196
196
  })
197
197
 
198
- test('returns false for unknown bot', async () => {
198
+ it('returns false for unknown bot', async () => {
199
199
  expect(await manager.setCurrent('nonexistent')).toBe(false)
200
200
  })
201
201
  })
202
202
 
203
203
  describe('removeBot', () => {
204
- test('removes a bot by id', async () => {
204
+ it('removes a bot by id', async () => {
205
205
  await manager.setCredentials(CREDS_A)
206
206
  await manager.setCredentials(CREDS_B)
207
207
 
@@ -212,7 +212,7 @@ describe('DiscordBotCredentialManager', () => {
212
212
  expect(Object.keys(config.bots)).toEqual(['bot-456'])
213
213
  })
214
214
 
215
- test('clears current when current bot removed', async () => {
215
+ it('clears current when current bot removed', async () => {
216
216
  await manager.setCredentials(CREDS_A)
217
217
 
218
218
  await manager.removeBot('bot-123')
@@ -221,11 +221,11 @@ describe('DiscordBotCredentialManager', () => {
221
221
  expect(config.current).toBeNull()
222
222
  })
223
223
 
224
- test('returns false for unknown bot', async () => {
224
+ it('returns false for unknown bot', async () => {
225
225
  expect(await manager.removeBot('nonexistent')).toBe(false)
226
226
  })
227
227
 
228
- test('does not clear current if removing non-current bot', async () => {
228
+ it('does not clear current if removing non-current bot', async () => {
229
229
  await manager.setCredentials(CREDS_A)
230
230
  await manager.setCredentials(CREDS_B)
231
231
 
@@ -237,7 +237,7 @@ describe('DiscordBotCredentialManager', () => {
237
237
  })
238
238
 
239
239
  describe('clearCredentials', () => {
240
- test('removes all credentials', async () => {
240
+ it('removes all credentials', async () => {
241
241
  await manager.setCredentials(CREDS_A)
242
242
  await manager.setCredentials(CREDS_B)
243
243
 
@@ -252,13 +252,13 @@ describe('DiscordBotCredentialManager', () => {
252
252
  })
253
253
 
254
254
  describe('getCurrentServer', () => {
255
- test('returns null when no server set', async () => {
255
+ it('returns null when no server set', async () => {
256
256
  const serverId = await manager.getCurrentServer()
257
257
 
258
258
  expect(serverId).toBeNull()
259
259
  })
260
260
 
261
- test('returns current server id', async () => {
261
+ it('returns current server id', async () => {
262
262
  await manager.setCurrentServer('guild-123', 'My Server')
263
263
 
264
264
  const serverId = await manager.getCurrentServer()
@@ -268,7 +268,7 @@ describe('DiscordBotCredentialManager', () => {
268
268
  })
269
269
 
270
270
  describe('setCurrentServer', () => {
271
- test('sets current server and adds to servers map', async () => {
271
+ it('sets current server and adds to servers map', async () => {
272
272
  await manager.setCurrentServer('guild-123', 'My Server')
273
273
 
274
274
  const config = await manager.load()
@@ -279,7 +279,7 @@ describe('DiscordBotCredentialManager', () => {
279
279
  })
280
280
  })
281
281
 
282
- test('updates existing server entry', async () => {
282
+ it('updates existing server entry', async () => {
283
283
  await manager.setCurrentServer('guild-123', 'My Server')
284
284
  await manager.setCurrentServer('guild-123', 'Updated Server')
285
285
 
@@ -287,7 +287,7 @@ describe('DiscordBotCredentialManager', () => {
287
287
  expect(config.servers['guild-123'].server_name).toBe('Updated Server')
288
288
  })
289
289
 
290
- test('switches current server', async () => {
290
+ it('switches current server', async () => {
291
291
  await manager.setCurrentServer('guild-123', 'Server A')
292
292
  await manager.setCurrentServer('guild-456', 'Server B')
293
293
 
@@ -298,7 +298,7 @@ describe('DiscordBotCredentialManager', () => {
298
298
  })
299
299
 
300
300
  describe('file permissions', () => {
301
- test('saves file with secure permissions (600)', async () => {
301
+ it('saves file with secure permissions (600)', async () => {
302
302
  await manager.setCredentials(CREDS_A)
303
303
 
304
304
  const credPath = join(tempDir, 'discordbot-credentials.json')
@@ -1,4 +1,4 @@
1
- import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test } from 'bun:test'
1
+ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'bun:test'
2
2
  import { generateKeyPairSync } from 'node:crypto'
3
3
  import { mkdirSync, rmSync, writeFileSync } from 'node:fs'
4
4
  import { join } from 'node:path'
@@ -82,14 +82,14 @@ async function loadedClient(): Promise<InstagramClient> {
82
82
 
83
83
  describe('InstagramClient', () => {
84
84
  describe('constructor', () => {
85
- test('creates instance with default credential manager', () => {
85
+ it('creates instance with default credential manager', () => {
86
86
  const client = new InstagramClient()
87
87
  expect(client).toBeInstanceOf(InstagramClient)
88
88
  })
89
89
  })
90
90
 
91
91
  describe('login', () => {
92
- test('throws when no account configured', async () => {
92
+ it('throws when no account configured', async () => {
93
93
  const mockManager = {
94
94
  getAccount: () => Promise.resolve(null),
95
95
  } as any
@@ -100,7 +100,7 @@ describe('InstagramClient', () => {
100
100
  await expect(client.login()).rejects.toThrow('No Instagram credentials found')
101
101
  })
102
102
 
103
- test('loads session from disk when file exists', async () => {
103
+ it('loads session from disk when file exists', async () => {
104
104
  const mockManager = {
105
105
  getAccount: () =>
106
106
  Promise.resolve({ account_id: 'testuser', username: 'testuser', created_at: '', updated_at: '' }),
@@ -116,7 +116,7 @@ describe('InstagramClient', () => {
116
116
  })
117
117
 
118
118
  describe('plaintextPassword format', () => {
119
- test('produces #PWD_INSTAGRAM:0:timestamp:rawpassword format', async () => {
119
+ it('produces #PWD_INSTAGRAM:0:timestamp:rawpassword format', async () => {
120
120
  fetchResponses.push(
121
121
  new Response(null, {
122
122
  status: 200,
@@ -142,7 +142,7 @@ describe('InstagramClient', () => {
142
142
  })
143
143
 
144
144
  describe('encryptPassword format', () => {
145
- test('produces #PWD_INSTAGRAM:4:timestamp:base64 format when encryption key provided', async () => {
145
+ it('produces #PWD_INSTAGRAM:4:timestamp:base64 format when encryption key provided', async () => {
146
146
  fetchResponses.push(
147
147
  new Response(null, {
148
148
  status: 200,
@@ -173,7 +173,7 @@ describe('InstagramClient', () => {
173
173
  })
174
174
 
175
175
  describe('buildHeaders', () => {
176
- test('includes required Instagram headers', async () => {
176
+ it('includes required Instagram headers', async () => {
177
177
  fetchResponses.push(new Response(null, { status: 200, headers: {} }))
178
178
  fetchResponses.push(jsonResponse({ status: 'ok', logged_in_user: { pk: '99' } }))
179
179
 
@@ -189,7 +189,7 @@ describe('InstagramClient', () => {
189
189
  expect(headers['Content-Type']).toContain('application/x-www-form-urlencoded')
190
190
  })
191
191
 
192
- test('includes device headers when session is set', async () => {
192
+ it('includes device headers when session is set', async () => {
193
193
  fetchResponses.push(jsonResponse({ status: 'ok', inbox: { threads: [] } }))
194
194
 
195
195
  const client = await loadedClient()
@@ -204,7 +204,7 @@ describe('InstagramClient', () => {
204
204
  })
205
205
 
206
206
  describe('mapThread', () => {
207
- test('maps API thread to InstagramChatSummary', async () => {
207
+ it('maps API thread to InstagramChatSummary', async () => {
208
208
  const thread = {
209
209
  thread_id: 'thread-42',
210
210
  thread_title: 'Team Chat',
@@ -231,7 +231,7 @@ describe('InstagramClient', () => {
231
231
  expect(chat.participant_count).toBe(3)
232
232
  })
233
233
 
234
- test('falls back to user names when no thread_title', async () => {
234
+ it('falls back to user names when no thread_title', async () => {
235
235
  const thread = {
236
236
  thread_id: 't-1',
237
237
  thread_type: 'private',
@@ -250,7 +250,7 @@ describe('InstagramClient', () => {
250
250
  })
251
251
 
252
252
  describe('mapMessage', () => {
253
- test('maps API item to InstagramMessageSummary with media_url', async () => {
253
+ it('maps API item to InstagramMessageSummary with media_url', async () => {
254
254
  const item = {
255
255
  item_id: 'msg-7',
256
256
  user_id: '10',
@@ -282,7 +282,7 @@ describe('InstagramClient', () => {
282
282
  expect(msg.media_url).toBe('https://cdn.example.com/photo.jpg')
283
283
  })
284
284
 
285
- test('sets is_outgoing true when from matches userId', async () => {
285
+ it('sets is_outgoing true when from matches userId', async () => {
286
286
  const item = {
287
287
  item_id: 'msg-8',
288
288
  user_id: '42',
@@ -300,7 +300,7 @@ describe('InstagramClient', () => {
300
300
  })
301
301
 
302
302
  describe('request', () => {
303
- test('throws rate_limited on 429', async () => {
303
+ it('throws rate_limited on 429', async () => {
304
304
  fetchResponses.push(new Response('Rate limited', { status: 429 }))
305
305
 
306
306
  const client = await loadedClient()
@@ -310,7 +310,7 @@ describe('InstagramClient', () => {
310
310
  expect((err as InstagramError).code).toBe('rate_limited')
311
311
  })
312
312
 
313
- test('throws on JSON parse error', async () => {
313
+ it('throws on JSON parse error', async () => {
314
314
  fetchResponses.push(new Response('not json', { status: 200 }))
315
315
 
316
316
  const client = await loadedClient()
@@ -318,7 +318,7 @@ describe('InstagramClient', () => {
318
318
  await expect(client.listChats()).rejects.toThrow(InstagramError)
319
319
  })
320
320
 
321
- test('returns parsed response on success', async () => {
321
+ it('returns parsed response on success', async () => {
322
322
  fetchResponses.push(jsonResponse({ status: 'ok', inbox: { threads: [] } }))
323
323
 
324
324
  const client = await loadedClient()
@@ -329,7 +329,7 @@ describe('InstagramClient', () => {
329
329
  })
330
330
 
331
331
  describe('searchUsers', () => {
332
- test('maps response to user list', async () => {
332
+ it('maps response to user list', async () => {
333
333
  fetchResponses.push(
334
334
  jsonResponse({
335
335
  status: 'ok',
@@ -350,7 +350,7 @@ describe('InstagramClient', () => {
350
350
  })
351
351
 
352
352
  describe('sendMessage', () => {
353
- test('sends correct body params', async () => {
353
+ it('sends correct body params', async () => {
354
354
  fetchResponses.push(
355
355
  jsonResponse({
356
356
  status: 'ok',
@@ -370,7 +370,7 @@ describe('InstagramClient', () => {
370
370
  })
371
371
 
372
372
  describe('sendMessageToUser', () => {
373
- test('sends correct body params', async () => {
373
+ it('sends correct body params', async () => {
374
374
  fetchResponses.push(
375
375
  jsonResponse({
376
376
  status: 'ok',
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, mock, spyOn, it } from 'bun:test'
2
2
 
3
3
  const originalConsoleLog = console.log
4
4
  import type { Command } from 'commander'
@@ -55,7 +55,7 @@ describe('auth commands', () => {
55
55
  })
56
56
 
57
57
  describe('status', () => {
58
- test('outputs error and exits when no account found', async () => {
58
+ it('outputs error and exits when no account found', async () => {
59
59
  mockGetAccount.mockImplementation(() => Promise.resolve(null))
60
60
 
61
61
  await expect(authCommand.parseAsync(['status'], { from: 'user' })).rejects.toThrow('process.exit called')
@@ -65,7 +65,7 @@ describe('auth commands', () => {
65
65
  expect(output.error).toContain('No Instagram account configured')
66
66
  })
67
67
 
68
- test('outputs account info when account exists', async () => {
68
+ it('outputs account info when account exists', async () => {
69
69
  mockGetAccount.mockImplementation(() =>
70
70
  Promise.resolve({
71
71
  account_id: 'user_testuser',
@@ -84,7 +84,7 @@ describe('auth commands', () => {
84
84
  expect(output.pk).toBe('12345')
85
85
  })
86
86
 
87
- test('outputs error for specific account not found', async () => {
87
+ it('outputs error for specific account not found', async () => {
88
88
  mockGetAccount.mockImplementation(() => Promise.resolve(null))
89
89
 
90
90
  await expect(
@@ -97,7 +97,7 @@ describe('auth commands', () => {
97
97
  })
98
98
 
99
99
  describe('list', () => {
100
- test('outputs empty array when no accounts', async () => {
100
+ it('outputs empty array when no accounts', async () => {
101
101
  mockListAccounts.mockImplementation(() => Promise.resolve([]))
102
102
 
103
103
  await authCommand.parseAsync(['list'], { from: 'user' })
@@ -106,7 +106,7 @@ describe('auth commands', () => {
106
106
  expect(output).toEqual([])
107
107
  })
108
108
 
109
- test('outputs accounts list', async () => {
109
+ it('outputs accounts list', async () => {
110
110
  mockListAccounts.mockImplementation(() =>
111
111
  Promise.resolve([
112
112
  {
@@ -140,7 +140,7 @@ describe('auth commands', () => {
140
140
  })
141
141
 
142
142
  describe('use', () => {
143
- test('switches to specified account', async () => {
143
+ it('switches to specified account', async () => {
144
144
  mockSetCurrent.mockImplementation(() => Promise.resolve(true))
145
145
  mockGetAccount.mockImplementation(() =>
146
146
  Promise.resolve({
@@ -160,7 +160,7 @@ describe('auth commands', () => {
160
160
  expect(output.account_id).toBe('user_alice')
161
161
  })
162
162
 
163
- test('outputs error when account not found', async () => {
163
+ it('outputs error when account not found', async () => {
164
164
  mockSetCurrent.mockImplementation(() => Promise.resolve(false))
165
165
 
166
166
  await expect(authCommand.parseAsync(['use', 'missing_account'], { from: 'user' })).rejects.toThrow(
@@ -173,7 +173,7 @@ describe('auth commands', () => {
173
173
  })
174
174
 
175
175
  describe('logout', () => {
176
- test('removes account and outputs success', async () => {
176
+ it('removes account and outputs success', async () => {
177
177
  mockGetAccount.mockImplementation(() =>
178
178
  Promise.resolve({
179
179
  account_id: 'user_alice',
@@ -194,7 +194,7 @@ describe('auth commands', () => {
194
194
  expect(output.account_id).toBe('user_alice')
195
195
  })
196
196
 
197
- test('outputs error when no account configured', async () => {
197
+ it('outputs error when no account configured', async () => {
198
198
  mockGetAccount.mockImplementation(() => Promise.resolve(null))
199
199
 
200
200
  await expect(authCommand.parseAsync(['logout'], { from: 'user' })).rejects.toThrow('process.exit called')
@@ -203,7 +203,7 @@ describe('auth commands', () => {
203
203
  expect(output.error).toContain('No Instagram account configured')
204
204
  })
205
205
 
206
- test('outputs error for specific account not found', async () => {
206
+ it('outputs error for specific account not found', async () => {
207
207
  mockGetAccount.mockImplementation(() => Promise.resolve(null))
208
208
 
209
209
  await expect(
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, mock, spyOn, it } from 'bun:test'
2
2
 
3
3
  const originalConsoleLog = console.log
4
4
  import type { Command } from 'commander'
@@ -67,7 +67,7 @@ describe('chat commands', () => {
67
67
  })
68
68
 
69
69
  describe('list', () => {
70
- test('lists DM conversations', async () => {
70
+ it('lists DM conversations', async () => {
71
71
  await expect(chatCommand.parseAsync(['list'], { from: 'user' })).rejects.toThrow('process.exit called')
72
72
 
73
73
  expect(processExitSpy).toHaveBeenCalledWith(0)
@@ -78,7 +78,7 @@ describe('chat commands', () => {
78
78
  expect(output[1].id).toBe('thread-2')
79
79
  })
80
80
 
81
- test('passes custom limit', async () => {
81
+ it('passes custom limit', async () => {
82
82
  await expect(chatCommand.parseAsync(['list', '--limit', '5'], { from: 'user' })).rejects.toThrow(
83
83
  'process.exit called',
84
84
  )
@@ -88,7 +88,7 @@ describe('chat commands', () => {
88
88
  })
89
89
 
90
90
  describe('search', () => {
91
- test('searches DM conversations by query', async () => {
91
+ it('searches DM conversations by query', async () => {
92
92
  await expect(chatCommand.parseAsync(['search', 'Alice'], { from: 'user' })).rejects.toThrow('process.exit called')
93
93
 
94
94
  expect(processExitSpy).toHaveBeenCalledWith(0)
@@ -98,7 +98,7 @@ describe('chat commands', () => {
98
98
  expect(output[0].id).toBe('thread-1')
99
99
  })
100
100
 
101
- test('passes custom limit to search', async () => {
101
+ it('passes custom limit to search', async () => {
102
102
  await expect(chatCommand.parseAsync(['search', 'Alice', '--limit', '10'], { from: 'user' })).rejects.toThrow(
103
103
  'process.exit called',
104
104
  )
@@ -106,7 +106,7 @@ describe('chat commands', () => {
106
106
  expect(mockSearchChats).toHaveBeenCalledWith('Alice', 10)
107
107
  })
108
108
 
109
- test('returns empty array when no results', async () => {
109
+ it('returns empty array when no results', async () => {
110
110
  mockSearchChats.mockImplementation(() => Promise.resolve([]))
111
111
 
112
112
  await expect(chatCommand.parseAsync(['search', 'nobody'], { from: 'user' })).rejects.toThrow(
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, mock, spyOn, it } from 'bun:test'
2
2
 
3
3
  const originalConsoleLog = console.log
4
4
  import type { Command } from 'commander'
@@ -68,7 +68,7 @@ describe('message commands', () => {
68
68
  })
69
69
 
70
70
  describe('list', () => {
71
- test('lists messages from a thread', async () => {
71
+ it('lists messages from a thread', async () => {
72
72
  await expect(messageCommand.parseAsync(['list', 'thread-123'], { from: 'user' })).rejects.toThrow(
73
73
  'process.exit called',
74
74
  )
@@ -79,7 +79,7 @@ describe('message commands', () => {
79
79
  expect(output).toEqual([{ id: 'msg-1', text: 'Hello' }])
80
80
  })
81
81
 
82
- test('passes custom limit', async () => {
82
+ it('passes custom limit', async () => {
83
83
  await expect(
84
84
  messageCommand.parseAsync(['list', 'thread-123', '--limit', '10'], { from: 'user' }),
85
85
  ).rejects.toThrow('process.exit called')
@@ -89,7 +89,7 @@ describe('message commands', () => {
89
89
  })
90
90
 
91
91
  describe('send', () => {
92
- test('sends a message to a thread', async () => {
92
+ it('sends a message to a thread', async () => {
93
93
  await expect(messageCommand.parseAsync(['send', 'thread-123', 'Hello world'], { from: 'user' })).rejects.toThrow(
94
94
  'process.exit called',
95
95
  )
@@ -102,7 +102,7 @@ describe('message commands', () => {
102
102
  })
103
103
 
104
104
  describe('send-to', () => {
105
- test('sends a message to a user by username', async () => {
105
+ it('sends a message to a user by username', async () => {
106
106
  await expect(messageCommand.parseAsync(['send-to', 'targetuser', 'Hi there'], { from: 'user' })).rejects.toThrow(
107
107
  'process.exit called',
108
108
  )
@@ -114,7 +114,7 @@ describe('message commands', () => {
114
114
  expect(output).toEqual({ id: 'msg-3', text: 'Sent to user' })
115
115
  })
116
116
 
117
- test('strips @ prefix from username', async () => {
117
+ it('strips @ prefix from username', async () => {
118
118
  await expect(messageCommand.parseAsync(['send-to', '@targetuser', 'Hi there'], { from: 'user' })).rejects.toThrow(
119
119
  'process.exit called',
120
120
  )
@@ -122,7 +122,7 @@ describe('message commands', () => {
122
122
  expect(mockSearchUsers).toHaveBeenCalledWith('targetuser')
123
123
  })
124
124
 
125
- test('handles user not found error', async () => {
125
+ it('handles user not found error', async () => {
126
126
  mockSearchUsers.mockImplementation(() => Promise.resolve([]))
127
127
 
128
128
  try {
@@ -136,7 +136,7 @@ describe('message commands', () => {
136
136
  })
137
137
 
138
138
  describe('search', () => {
139
- test('searches messages by query', async () => {
139
+ it('searches messages by query', async () => {
140
140
  await expect(messageCommand.parseAsync(['search', 'hello'], { from: 'user' })).rejects.toThrow(
141
141
  'process.exit called',
142
142
  )
@@ -147,7 +147,7 @@ describe('message commands', () => {
147
147
  expect(output).toEqual([{ id: 'msg-4', text: 'Found' }])
148
148
  })
149
149
 
150
- test('passes thread option to search', async () => {
150
+ it('passes thread option to search', async () => {
151
151
  await expect(
152
152
  messageCommand.parseAsync(['search', 'hello', '--thread', 'thread-456'], { from: 'user' }),
153
153
  ).rejects.toThrow('process.exit called')
@@ -155,7 +155,7 @@ describe('message commands', () => {
155
155
  expect(mockSearchMessages).toHaveBeenCalledWith('hello', { threadId: 'thread-456', limit: 20 })
156
156
  })
157
157
 
158
- test('passes limit option to search', async () => {
158
+ it('passes limit option to search', async () => {
159
159
  await expect(messageCommand.parseAsync(['search', 'hello2', '--limit', '5'], { from: 'user' })).rejects.toThrow(
160
160
  'process.exit called',
161
161
  )
@@ -165,7 +165,7 @@ describe('message commands', () => {
165
165
  })
166
166
 
167
167
  describe('search-users', () => {
168
- test('searches users by query', async () => {
168
+ it('searches users by query', async () => {
169
169
  await expect(messageCommand.parseAsync(['search-users', 'target'], { from: 'user' })).rejects.toThrow(
170
170
  'process.exit called',
171
171
  )