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
 
3
3
  import * as jose from 'node-jose'
4
4
 
@@ -50,17 +50,17 @@ describe('WebexClient', () => {
50
50
  }
51
51
 
52
52
  describe('login', () => {
53
- test('accepts valid token', async () => {
53
+ it('accepts valid token', async () => {
54
54
  const client = await new WebexClient().login({ token: 'test-token' })
55
55
  expect(client).toBeInstanceOf(WebexClient)
56
56
  })
57
57
 
58
- test('throws on empty token', async () => {
58
+ it('throws on empty token', async () => {
59
59
  await expect(new WebexClient().login({ token: '' })).rejects.toThrow(WebexError)
60
60
  await expect(new WebexClient().login({ token: '' })).rejects.toThrow('Token is required')
61
61
  })
62
62
 
63
- test('accepts deviceUrl and tokenType', async () => {
63
+ it('accepts deviceUrl and tokenType', async () => {
64
64
  const client = await new WebexClient().login({
65
65
  token: 'test-token',
66
66
  deviceUrl: 'https://wdm-r.wbx2.com/wdm/api/v1/devices/dev-1',
@@ -73,7 +73,7 @@ describe('WebexClient', () => {
73
73
  })
74
74
 
75
75
  describe('testAuth', () => {
76
- test('calls GET /people/me and returns person', async () => {
76
+ it('calls GET /people/me and returns person', async () => {
77
77
  mockResponse({
78
78
  id: 'user-123',
79
79
  displayName: 'Test User',
@@ -92,14 +92,14 @@ describe('WebexClient', () => {
92
92
  })
93
93
  })
94
94
 
95
- test('throws WebexError on API error', async () => {
95
+ it('throws WebexError on API error', async () => {
96
96
  mockResponse({ message: 'Unauthorized' }, 401)
97
97
 
98
98
  const client = await new WebexClient().login({ token: 'bad-token' })
99
99
  await expect(client.testAuth()).rejects.toThrow(WebexError)
100
100
  })
101
101
 
102
- test('falls back to internal API when public API fails for extracted tokens', async () => {
102
+ it('falls back to internal API when public API fails for extracted tokens', async () => {
103
103
  // given - public API rejects, internal API succeeds
104
104
  mockResponse({ message: 'Unauthorized' }, 401)
105
105
  fetchResponses.push(
@@ -125,7 +125,7 @@ describe('WebexClient', () => {
125
125
  expect(person).toBeTruthy()
126
126
  })
127
127
 
128
- test('throws when both public and internal APIs fail for extracted tokens', async () => {
128
+ it('throws when both public and internal APIs fail for extracted tokens', async () => {
129
129
  // given - both APIs reject
130
130
  mockResponse({ message: 'Unauthorized' }, 401)
131
131
  fetchResponses.push(
@@ -144,7 +144,7 @@ describe('WebexClient', () => {
144
144
  await expect(client.testAuth()).rejects.toThrow(WebexError)
145
145
  })
146
146
 
147
- test('does not use internal API fallback for non-extracted tokens', async () => {
147
+ it('does not use internal API fallback for non-extracted tokens', async () => {
148
148
  mockResponse({ message: 'Unauthorized' }, 401)
149
149
 
150
150
  const client = await new WebexClient().login({ token: 'bad-token' })
@@ -154,7 +154,7 @@ describe('WebexClient', () => {
154
154
  })
155
155
 
156
156
  describe('listSpaces', () => {
157
- test('returns unwrapped items array', async () => {
157
+ it('returns unwrapped items array', async () => {
158
158
  mockResponse({
159
159
  items: [
160
160
  { id: 'room1', title: 'Room One', type: 'group' },
@@ -170,7 +170,7 @@ describe('WebexClient', () => {
170
170
  expect(spaces[1].title).toBe('Room Two')
171
171
  })
172
172
 
173
- test('includes default max=50 query param', async () => {
173
+ it('includes default max=50 query param', async () => {
174
174
  mockResponse({ items: [] })
175
175
 
176
176
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -179,7 +179,7 @@ describe('WebexClient', () => {
179
179
  expect(fetchCalls[0].url).toContain('max=50')
180
180
  })
181
181
 
182
- test('passes type and max query params', async () => {
182
+ it('passes type and max query params', async () => {
183
183
  mockResponse({ items: [] })
184
184
 
185
185
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -192,7 +192,7 @@ describe('WebexClient', () => {
192
192
  })
193
193
 
194
194
  describe('getSpace', () => {
195
- test('calls GET /rooms/{spaceId}', async () => {
195
+ it('calls GET /rooms/{spaceId}', async () => {
196
196
  mockResponse({ id: 'room1', title: 'Test Room', type: 'group' })
197
197
 
198
198
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -204,7 +204,7 @@ describe('WebexClient', () => {
204
204
  })
205
205
 
206
206
  describe('sendMessage', () => {
207
- test('posts text message to room', async () => {
207
+ it('posts text message to room', async () => {
208
208
  mockResponse({ id: 'msg1', roomId: 'room1', text: 'Hello world' })
209
209
 
210
210
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -216,7 +216,7 @@ describe('WebexClient', () => {
216
216
  expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ roomId: 'room1', text: 'Hello world' }))
217
217
  })
218
218
 
219
- test('sends markdown message when option set', async () => {
219
+ it('sends markdown message when option set', async () => {
220
220
  mockResponse({ id: 'msg1', roomId: 'room1', markdown: '**bold**' })
221
221
 
222
222
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -227,7 +227,7 @@ describe('WebexClient', () => {
227
227
  })
228
228
 
229
229
  describe('sendDirectMessage', () => {
230
- test('posts message with toPersonEmail', async () => {
230
+ it('posts message with toPersonEmail', async () => {
231
231
  mockResponse({ id: 'msg1', toPersonEmail: 'user@example.com', text: 'Hello' })
232
232
 
233
233
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -236,7 +236,7 @@ describe('WebexClient', () => {
236
236
  expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ toPersonEmail: 'user@example.com', text: 'Hello' }))
237
237
  })
238
238
 
239
- test('sends markdown direct message when option set', async () => {
239
+ it('sends markdown direct message when option set', async () => {
240
240
  mockResponse({ id: 'msg1', toPersonEmail: 'user@example.com' })
241
241
 
242
242
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -249,7 +249,7 @@ describe('WebexClient', () => {
249
249
  })
250
250
 
251
251
  describe('listMessages', () => {
252
- test('includes roomId query param and unwraps items', async () => {
252
+ it('includes roomId query param and unwraps items', async () => {
253
253
  mockResponse({
254
254
  items: [
255
255
  { id: 'msg1', roomId: 'room1', text: 'Message 1' },
@@ -266,7 +266,7 @@ describe('WebexClient', () => {
266
266
  expect(fetchCalls[0].url).toContain('max=50')
267
267
  })
268
268
 
269
- test('passes custom max', async () => {
269
+ it('passes custom max', async () => {
270
270
  mockResponse({ items: [] })
271
271
 
272
272
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -277,7 +277,7 @@ describe('WebexClient', () => {
277
277
  })
278
278
 
279
279
  describe('getMessage', () => {
280
- test('calls GET /messages/{messageId}', async () => {
280
+ it('calls GET /messages/{messageId}', async () => {
281
281
  mockResponse({ id: 'msg1', roomId: 'room1', text: 'Hello' })
282
282
 
283
283
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -289,7 +289,7 @@ describe('WebexClient', () => {
289
289
  })
290
290
 
291
291
  describe('deleteMessage', () => {
292
- test('calls DELETE /messages/{messageId} and handles 204', async () => {
292
+ it('calls DELETE /messages/{messageId} and handles 204', async () => {
293
293
  mockResponse(null, 204)
294
294
 
295
295
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -301,7 +301,7 @@ describe('WebexClient', () => {
301
301
  })
302
302
 
303
303
  describe('editMessage', () => {
304
- test('calls PUT /messages/{messageId} with roomId and text', async () => {
304
+ it('calls PUT /messages/{messageId} with roomId and text', async () => {
305
305
  mockResponse({ id: 'msg1', roomId: 'room1', text: 'Edited text' })
306
306
 
307
307
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -312,7 +312,7 @@ describe('WebexClient', () => {
312
312
  expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ roomId: 'room1', text: 'Edited text' }))
313
313
  })
314
314
 
315
- test('sends markdown when option set', async () => {
315
+ it('sends markdown when option set', async () => {
316
316
  mockResponse({ id: 'msg1', roomId: 'room1', markdown: '**edited**' })
317
317
 
318
318
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -323,7 +323,7 @@ describe('WebexClient', () => {
323
323
  })
324
324
 
325
325
  describe('listPeople', () => {
326
- test('returns unwrapped items', async () => {
326
+ it('returns unwrapped items', async () => {
327
327
  mockResponse({
328
328
  items: [
329
329
  { id: 'u1', displayName: 'User One', emails: ['user1@example.com'] },
@@ -338,7 +338,7 @@ describe('WebexClient', () => {
338
338
  expect(people[0].displayName).toBe('User One')
339
339
  })
340
340
 
341
- test('passes email, displayName, max query params', async () => {
341
+ it('passes email, displayName, max query params', async () => {
342
342
  mockResponse({ items: [] })
343
343
 
344
344
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -351,7 +351,7 @@ describe('WebexClient', () => {
351
351
  })
352
352
 
353
353
  describe('listMemberships', () => {
354
- test('includes roomId and returns unwrapped items', async () => {
354
+ it('includes roomId and returns unwrapped items', async () => {
355
355
  mockResponse({
356
356
  items: [
357
357
  { id: 'm1', roomId: 'room1', personEmail: 'user1@example.com', isModerator: false },
@@ -367,7 +367,7 @@ describe('WebexClient', () => {
367
367
  expect(fetchCalls[0].url).toContain('roomId=room1')
368
368
  })
369
369
 
370
- test('passes max query param', async () => {
370
+ it('passes max query param', async () => {
371
371
  mockResponse({ items: [] })
372
372
 
373
373
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -378,7 +378,7 @@ describe('WebexClient', () => {
378
378
  })
379
379
 
380
380
  describe('rate limiting', () => {
381
- test('retries on 429 with Retry-After header', async () => {
381
+ it('retries on 429 with Retry-After header', async () => {
382
382
  mockResponse({ message: 'Rate limited' }, 429, { 'Retry-After': '0.1' })
383
383
  mockResponse({
384
384
  id: 'user-123',
@@ -393,7 +393,7 @@ describe('WebexClient', () => {
393
393
  expect(fetchCalls.length).toBe(2)
394
394
  })
395
395
 
396
- test('throws after max retries exceeded on 429', async () => {
396
+ it('throws after max retries exceeded on 429', async () => {
397
397
  for (let i = 0; i <= MAX_RETRIES; i++) {
398
398
  mockResponse({ message: 'Rate limited' }, 429, { 'Retry-After': '0.01' })
399
399
  }
@@ -405,7 +405,7 @@ describe('WebexClient', () => {
405
405
  })
406
406
 
407
407
  describe('server errors', () => {
408
- test('retries on 500 with exponential backoff', async () => {
408
+ it('retries on 500 with exponential backoff', async () => {
409
409
  mockResponse({ message: 'Internal Server Error' }, 500)
410
410
  mockResponse({
411
411
  id: 'user-123',
@@ -420,7 +420,7 @@ describe('WebexClient', () => {
420
420
  expect(fetchCalls.length).toBe(2)
421
421
  })
422
422
 
423
- test('does not retry on 4xx errors except 429', async () => {
423
+ it('does not retry on 4xx errors except 429', async () => {
424
424
  mockResponse({ message: 'Not Found' }, 404)
425
425
 
426
426
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -428,7 +428,7 @@ describe('WebexClient', () => {
428
428
  expect(fetchCalls.length).toBe(1)
429
429
  })
430
430
 
431
- test('backoff increases with multiple retries', async () => {
431
+ it('backoff increases with multiple retries', async () => {
432
432
  mockResponse({ message: 'Error' }, 500)
433
433
  mockResponse({ message: 'Error' }, 500)
434
434
  mockResponse({
@@ -477,7 +477,7 @@ describe('WebexClient', () => {
477
477
  }
478
478
 
479
479
  describe('sendMessage', () => {
480
- test('posts activity to /activities with POST method', async () => {
480
+ it('posts activity to /activities with POST method', async () => {
481
481
  mockResponse(mockActivity('Hello world'))
482
482
 
483
483
  const client = await createExtractedClient()
@@ -487,7 +487,7 @@ describe('WebexClient', () => {
487
487
  expect(fetchCalls[0].options?.method).toBe('POST')
488
488
  })
489
489
 
490
- test('body has verb, object type, and displayName (no content for plain text)', async () => {
490
+ it('body has verb, object type, and displayName (no content for plain text)', async () => {
491
491
  mockResponse(mockActivity('Hello world'))
492
492
 
493
493
  const client = await createExtractedClient()
@@ -500,7 +500,7 @@ describe('WebexClient', () => {
500
500
  expect(body.object.content).toBeUndefined()
501
501
  })
502
502
 
503
- test('body has target with decoded conv UUID and conversation type', async () => {
503
+ it('body has target with decoded conv UUID and conversation type', async () => {
504
504
  mockResponse(mockActivity('Hello world'))
505
505
 
506
506
  const client = await createExtractedClient()
@@ -511,7 +511,7 @@ describe('WebexClient', () => {
511
511
  expect(body.target.objectType).toBe('conversation')
512
512
  })
513
513
 
514
- test('body has clientTempId starting with tmp-', async () => {
514
+ it('body has clientTempId starting with tmp-', async () => {
515
515
  mockResponse(mockActivity('Hello world'))
516
516
 
517
517
  const client = await createExtractedClient()
@@ -521,7 +521,7 @@ describe('WebexClient', () => {
521
521
  expect(body.clientTempId).toStartWith('tmp-')
522
522
  })
523
523
 
524
- test('includes cisco-device-url header', async () => {
524
+ it('includes cisco-device-url header', async () => {
525
525
  mockResponse(mockActivity('Hello world'))
526
526
 
527
527
  const client = await createExtractedClient()
@@ -532,7 +532,7 @@ describe('WebexClient', () => {
532
532
  })
533
533
  })
534
534
 
535
- test('returns WebexMessage mapped from activity response', async () => {
535
+ it('returns WebexMessage mapped from activity response', async () => {
536
536
  mockResponse(mockActivity('Hello world'))
537
537
 
538
538
  const client = await createExtractedClient()
@@ -544,7 +544,7 @@ describe('WebexClient', () => {
544
544
  expect(message.created).toBe('2026-01-01T00:00:00.000Z')
545
545
  })
546
546
 
547
- test('markdown option converts content to HTML and strips displayName', async () => {
547
+ it('markdown option converts content to HTML and strips displayName', async () => {
548
548
  mockResponse(mockActivity('bold text'))
549
549
 
550
550
  const client = await createExtractedClient()
@@ -556,7 +556,7 @@ describe('WebexClient', () => {
556
556
  expect(body.object.markdown).toBeUndefined()
557
557
  })
558
558
 
559
- test('plain text messages omit content field', async () => {
559
+ it('plain text messages omit content field', async () => {
560
560
  mockResponse(mockActivity('Hello world'))
561
561
 
562
562
  const client = await createExtractedClient()
@@ -569,7 +569,7 @@ describe('WebexClient', () => {
569
569
  })
570
570
 
571
571
  describe('listMessages', () => {
572
- test('calls GET on conversations endpoint with activitiesLimit and participantsLimit', async () => {
572
+ it('calls GET on conversations endpoint with activitiesLimit and participantsLimit', async () => {
573
573
  mockResponse(mockConversation([mockActivity('Hello')]))
574
574
 
575
575
  const client = await createExtractedClient()
@@ -580,7 +580,7 @@ describe('WebexClient', () => {
580
580
  )
581
581
  })
582
582
 
583
- test('filters activities to only those with verb post', async () => {
583
+ it('filters activities to only those with verb post', async () => {
584
584
  mockResponse(
585
585
  mockConversation([
586
586
  mockActivity('Hello'),
@@ -597,7 +597,7 @@ describe('WebexClient', () => {
597
597
  expect(messages[1].text).toBe('World')
598
598
  })
599
599
 
600
- test('maps each activity to WebexMessage format', async () => {
600
+ it('maps each activity to WebexMessage format', async () => {
601
601
  mockResponse(mockConversation([mockActivity('Hello')]))
602
602
 
603
603
  const client = await createExtractedClient()
@@ -609,7 +609,7 @@ describe('WebexClient', () => {
609
609
  expect(messages[0].created).toBe('2026-01-01T00:00:00.000Z')
610
610
  })
611
611
 
612
- test('passes custom max to activitiesLimit', async () => {
612
+ it('passes custom max to activitiesLimit', async () => {
613
613
  mockResponse(mockConversation([]))
614
614
 
615
615
  const client = await createExtractedClient()
@@ -618,7 +618,7 @@ describe('WebexClient', () => {
618
618
  expect(fetchCalls[0].url).toContain('activitiesLimit=25')
619
619
  })
620
620
 
621
- test('includes cisco-device-url header', async () => {
621
+ it('includes cisco-device-url header', async () => {
622
622
  mockResponse(mockConversation([]))
623
623
 
624
624
  const client = await createExtractedClient()
@@ -631,7 +631,7 @@ describe('WebexClient', () => {
631
631
  })
632
632
 
633
633
  describe('getMessage', () => {
634
- test('calls GET on activities endpoint', async () => {
634
+ it('calls GET on activities endpoint', async () => {
635
635
  mockResponse(mockActivity('Hello'))
636
636
 
637
637
  const client = await createExtractedClient()
@@ -640,7 +640,7 @@ describe('WebexClient', () => {
640
640
  expect(fetchCalls[0].url).toBe(`${CONV_BASE}/activities/activity-123`)
641
641
  })
642
642
 
643
- test('maps activity to WebexMessage format', async () => {
643
+ it('maps activity to WebexMessage format', async () => {
644
644
  mockResponse(mockActivity('Hello'))
645
645
 
646
646
  const client = await createExtractedClient()
@@ -653,7 +653,7 @@ describe('WebexClient', () => {
653
653
  })
654
654
 
655
655
  describe('deleteMessage', () => {
656
- test('first GETs the activity then POSTs a delete activity', async () => {
656
+ it('first GETs the activity then POSTs a delete activity', async () => {
657
657
  mockResponse(mockActivity('Hello'))
658
658
  mockResponse({})
659
659
 
@@ -665,7 +665,7 @@ describe('WebexClient', () => {
665
665
  expect(fetchCalls[1].options?.method).toBe('POST')
666
666
  })
667
667
 
668
- test('delete activity body has correct verb, object, and target', async () => {
668
+ it('delete activity body has correct verb, object, and target', async () => {
669
669
  mockResponse(mockActivity('Hello'))
670
670
  mockResponse({})
671
671
 
@@ -679,7 +679,7 @@ describe('WebexClient', () => {
679
679
  expect(body.target.id).toBe(TEST_CONV_UUID)
680
680
  })
681
681
 
682
- test('throws WebexError when activity has no target', async () => {
682
+ it('throws WebexError when activity has no target', async () => {
683
683
  mockResponse({ ...mockActivity('Hello'), target: undefined })
684
684
 
685
685
  const client = await createExtractedClient()
@@ -691,7 +691,7 @@ describe('WebexClient', () => {
691
691
  const mockEditActivity = (text: string, parentId = 'activity-123') =>
692
692
  mockActivity(text, { parent: { id: parentId, type: 'edit' } })
693
693
 
694
- test('posts activity with verb post and parent edit reference', async () => {
694
+ it('posts activity with verb post and parent edit reference', async () => {
695
695
  mockResponse(mockEditActivity('Edited text'))
696
696
 
697
697
  const client = await createExtractedClient()
@@ -702,7 +702,7 @@ describe('WebexClient', () => {
702
702
  expect(body.parent).toEqual({ id: 'activity-123', type: 'edit' })
703
703
  })
704
704
 
705
- test('plain text edit populates both displayName and content to avoid auto-tombstone', async () => {
705
+ it('plain text edit populates both displayName and content to avoid auto-tombstone', async () => {
706
706
  mockResponse(mockEditActivity('Edited text'))
707
707
 
708
708
  const client = await createExtractedClient()
@@ -714,7 +714,7 @@ describe('WebexClient', () => {
714
714
  expect(body.object.content).toBe('Edited text')
715
715
  })
716
716
 
717
- test('clientTempId uses -edit suffix to match Webex web client format', async () => {
717
+ it('clientTempId uses -edit suffix to match Webex web client format', async () => {
718
718
  mockResponse(mockEditActivity('Edited text'))
719
719
 
720
720
  const client = await createExtractedClient()
@@ -724,7 +724,7 @@ describe('WebexClient', () => {
724
724
  expect(body.clientTempId).toMatch(/^tmp-\d+-edit$/)
725
725
  })
726
726
 
727
- test('target has decoded conv UUID', async () => {
727
+ it('target has decoded conv UUID', async () => {
728
728
  mockResponse(mockEditActivity('Edited text'))
729
729
 
730
730
  const client = await createExtractedClient()
@@ -734,7 +734,7 @@ describe('WebexClient', () => {
734
734
  expect(body.target.id).toBe(TEST_CONV_UUID)
735
735
  })
736
736
 
737
- test('markdown option converts content to HTML and strips displayName', async () => {
737
+ it('markdown option converts content to HTML and strips displayName', async () => {
738
738
  mockResponse(mockEditActivity('italic text'))
739
739
 
740
740
  const client = await createExtractedClient()
@@ -746,7 +746,7 @@ describe('WebexClient', () => {
746
746
  expect(body.object.markdown).toBeUndefined()
747
747
  })
748
748
 
749
- test('tolerates responses that omit parent (minimal success shape)', async () => {
749
+ it('tolerates responses that omit parent (minimal success shape)', async () => {
750
750
  mockResponse(mockActivity('Edited text'))
751
751
 
752
752
  const client = await createExtractedClient()
@@ -754,7 +754,7 @@ describe('WebexClient', () => {
754
754
  expect(message.id).toBe('activity-123')
755
755
  })
756
756
 
757
- test('throws when server returns activity linked to a different parent', async () => {
757
+ it('throws when server returns activity linked to a different parent', async () => {
758
758
  mockResponse(mockEditActivity('Edited text', 'activity-999'))
759
759
 
760
760
  const client = await createExtractedClient()
@@ -781,7 +781,7 @@ describe('WebexClient', () => {
781
781
  return client
782
782
  }
783
783
 
784
- test('plain text send omits content field on encrypted path (preserves prior fix)', async () => {
784
+ it('plain text send omits content field on encrypted path (preserves prior fix)', async () => {
785
785
  mockResponse({ id: TEST_CONV_UUID, defaultActivityEncryptionKeyUrl: TEST_KEY_URI })
786
786
  mockResponse(mockActivity('Hello world'))
787
787
 
@@ -794,7 +794,7 @@ describe('WebexClient', () => {
794
794
  expect(body.encryptionKeyUrl).toBe(TEST_KEY_URI)
795
795
  })
796
796
 
797
- test('plain text edit encrypts both displayName and content with kid in JWE header', async () => {
797
+ it('plain text edit encrypts both displayName and content with kid in JWE header', async () => {
798
798
  mockResponse({ id: TEST_CONV_UUID, defaultActivityEncryptionKeyUrl: TEST_KEY_URI })
799
799
  mockResponse(mockActivity('Edited text', { parent: { id: 'activity-123', type: 'edit' } }))
800
800
 
@@ -811,7 +811,7 @@ describe('WebexClient', () => {
811
811
  })
812
812
 
813
813
  describe('sendDirectMessage', () => {
814
- test('calls public rooms and memberships API to find room, then sends via internal API', async () => {
814
+ it('calls public rooms and memberships API to find room, then sends via internal API', async () => {
815
815
  mockResponse({ items: [{ id: TEST_ROOM_ID, title: 'DM', type: 'direct' }] })
816
816
  mockResponse({
817
817
  items: [{ id: 'm1', roomId: TEST_ROOM_ID, personEmail: 'target@example.com', isModerator: false }],
@@ -827,7 +827,7 @@ describe('WebexClient', () => {
827
827
  expect(message.id).toBe('activity-123')
828
828
  })
829
829
 
830
- test('throws WebexError when no existing direct conversation found', async () => {
830
+ it('throws WebexError when no existing direct conversation found', async () => {
831
831
  mockResponse({ items: [{ id: 'room-x', title: 'DM', type: 'direct' }] })
832
832
  mockResponse({
833
833
  items: [{ id: 'm1', roomId: 'room-x', personEmail: 'other@example.com', isModerator: false }],
@@ -839,7 +839,7 @@ describe('WebexClient', () => {
839
839
  })
840
840
 
841
841
  describe('error handling', () => {
842
- test('throws WebexError when internal API returns non-OK response', async () => {
842
+ it('throws WebexError when internal API returns non-OK response', async () => {
843
843
  fetchResponses.push(
844
844
  new Response(JSON.stringify({ message: 'Activity not found' }), {
845
845
  status: 404,
@@ -851,7 +851,7 @@ describe('WebexClient', () => {
851
851
  await expect(client.getMessage('bad-activity')).rejects.toThrow(WebexError)
852
852
  })
853
853
 
854
- test('error message extracted from internal API response body', async () => {
854
+ it('error message extracted from internal API response body', async () => {
855
855
  fetchResponses.push(
856
856
  new Response(JSON.stringify({ message: 'Activity not found' }), {
857
857
  status: 404,
@@ -874,7 +874,7 @@ describe('WebexClient', () => {
874
874
  })
875
875
 
876
876
  describe('error handling', () => {
877
- test('throws WebexError with parsed message from response body', async () => {
877
+ it('throws WebexError with parsed message from response body', async () => {
878
878
  mockResponse({ message: 'The requested resource could not be found.', trackingId: 'abc' }, 404)
879
879
 
880
880
  const client = await new WebexClient().login({ token: 'test-token' })
@@ -889,7 +889,7 @@ describe('WebexClient', () => {
889
889
  expect(error?.message).toBe('The requested resource could not be found.')
890
890
  })
891
891
 
892
- test('falls back to HTTP status message when no body', async () => {
892
+ it('falls back to HTTP status message when no body', async () => {
893
893
  fetchResponses.push(
894
894
  new Response(null, {
895
895
  status: 403,