agent-messenger 1.3.0 → 1.3.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 (236) hide show
  1. package/.claude-plugin/marketplace.json +27 -1
  2. package/.claude-plugin/plugin.json +17 -4
  3. package/.env.template +3 -0
  4. package/.github/workflows/release.yml +80 -0
  5. package/AGENTS.md +48 -0
  6. package/README.md +25 -20
  7. package/biome.json +15 -39
  8. package/bun.lock +69 -0
  9. package/dist/package.json +10 -3
  10. package/dist/src/cli.d.ts.map +1 -1
  11. package/dist/src/cli.js +1 -4
  12. package/dist/src/cli.js.map +1 -1
  13. package/dist/src/platforms/discord/client.d.ts.map +1 -1
  14. package/dist/src/platforms/discord/client.js.map +1 -1
  15. package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -1
  16. package/dist/src/platforms/discord/commands/auth.js.map +1 -1
  17. package/dist/src/platforms/discord/commands/channel.d.ts.map +1 -1
  18. package/dist/src/platforms/discord/commands/channel.js.map +1 -1
  19. package/dist/src/platforms/discord/commands/dm.d.ts.map +1 -1
  20. package/dist/src/platforms/discord/commands/dm.js.map +1 -1
  21. package/dist/src/platforms/discord/commands/file.d.ts.map +1 -1
  22. package/dist/src/platforms/discord/commands/file.js +1 -4
  23. package/dist/src/platforms/discord/commands/file.js.map +1 -1
  24. package/dist/src/platforms/discord/commands/friend.d.ts.map +1 -1
  25. package/dist/src/platforms/discord/commands/friend.js +1 -3
  26. package/dist/src/platforms/discord/commands/friend.js.map +1 -1
  27. package/dist/src/platforms/discord/commands/member.d.ts.map +1 -1
  28. package/dist/src/platforms/discord/commands/member.js.map +1 -1
  29. package/dist/src/platforms/discord/commands/mention.d.ts.map +1 -1
  30. package/dist/src/platforms/discord/commands/mention.js.map +1 -1
  31. package/dist/src/platforms/discord/commands/message.d.ts.map +1 -1
  32. package/dist/src/platforms/discord/commands/message.js.map +1 -1
  33. package/dist/src/platforms/discord/commands/note.d.ts.map +1 -1
  34. package/dist/src/platforms/discord/commands/note.js.map +1 -1
  35. package/dist/src/platforms/discord/commands/profile.d.ts.map +1 -1
  36. package/dist/src/platforms/discord/commands/profile.js.map +1 -1
  37. package/dist/src/platforms/discord/commands/reaction.d.ts.map +1 -1
  38. package/dist/src/platforms/discord/commands/reaction.js.map +1 -1
  39. package/dist/src/platforms/discord/commands/server.d.ts.map +1 -1
  40. package/dist/src/platforms/discord/commands/server.js.map +1 -1
  41. package/dist/src/platforms/discord/commands/snapshot.d.ts.map +1 -1
  42. package/dist/src/platforms/discord/commands/snapshot.js.map +1 -1
  43. package/dist/src/platforms/discord/commands/thread.d.ts.map +1 -1
  44. package/dist/src/platforms/discord/commands/thread.js.map +1 -1
  45. package/dist/src/platforms/discord/commands/user.d.ts.map +1 -1
  46. package/dist/src/platforms/discord/commands/user.js.map +1 -1
  47. package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -1
  48. package/dist/src/platforms/discord/credential-manager.js.map +1 -1
  49. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  50. package/dist/src/platforms/discord/token-extractor.js +2 -7
  51. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  52. package/dist/src/platforms/slack/client.d.ts.map +1 -1
  53. package/dist/src/platforms/slack/client.js +2 -0
  54. package/dist/src/platforms/slack/client.js.map +1 -1
  55. package/dist/src/platforms/slack/commands/activity.d.ts.map +1 -1
  56. package/dist/src/platforms/slack/commands/activity.js.map +1 -1
  57. package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
  58. package/dist/src/platforms/slack/commands/auth.js.map +1 -1
  59. package/dist/src/platforms/slack/commands/channel.d.ts.map +1 -1
  60. package/dist/src/platforms/slack/commands/channel.js.map +1 -1
  61. package/dist/src/platforms/slack/commands/drafts.d.ts.map +1 -1
  62. package/dist/src/platforms/slack/commands/drafts.js.map +1 -1
  63. package/dist/src/platforms/slack/commands/file.d.ts.map +1 -1
  64. package/dist/src/platforms/slack/commands/file.js +1 -4
  65. package/dist/src/platforms/slack/commands/file.js.map +1 -1
  66. package/dist/src/platforms/slack/commands/message.d.ts.map +1 -1
  67. package/dist/src/platforms/slack/commands/message.js.map +1 -1
  68. package/dist/src/platforms/slack/commands/reaction.d.ts.map +1 -1
  69. package/dist/src/platforms/slack/commands/reaction.js +1 -2
  70. package/dist/src/platforms/slack/commands/reaction.js.map +1 -1
  71. package/dist/src/platforms/slack/commands/saved.d.ts.map +1 -1
  72. package/dist/src/platforms/slack/commands/saved.js.map +1 -1
  73. package/dist/src/platforms/slack/commands/sections.d.ts.map +1 -1
  74. package/dist/src/platforms/slack/commands/sections.js.map +1 -1
  75. package/dist/src/platforms/slack/commands/snapshot.d.ts.map +1 -1
  76. package/dist/src/platforms/slack/commands/snapshot.js.map +1 -1
  77. package/dist/src/platforms/slack/commands/unread.d.ts.map +1 -1
  78. package/dist/src/platforms/slack/commands/unread.js.map +1 -1
  79. package/dist/src/platforms/slack/commands/user.d.ts.map +1 -1
  80. package/dist/src/platforms/slack/commands/user.js.map +1 -1
  81. package/dist/src/platforms/slack/commands/workspace.d.ts.map +1 -1
  82. package/dist/src/platforms/slack/commands/workspace.js.map +1 -1
  83. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  84. package/dist/src/platforms/slack/token-extractor.js +4 -5
  85. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  86. package/dist/src/platforms/slack/types.d.ts +24 -0
  87. package/dist/src/platforms/slack/types.d.ts.map +1 -1
  88. package/dist/src/platforms/slack/types.js +7 -0
  89. package/dist/src/platforms/slack/types.js.map +1 -1
  90. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  91. package/dist/src/platforms/slackbot/cli.js +1 -1
  92. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  93. package/dist/src/platforms/slackbot/client.d.ts.map +1 -1
  94. package/dist/src/platforms/slackbot/client.js.map +1 -1
  95. package/dist/src/platforms/slackbot/commands/auth.js.map +1 -1
  96. package/dist/src/platforms/slackbot/commands/channel.js.map +1 -1
  97. package/dist/src/platforms/slackbot/commands/message.d.ts.map +1 -1
  98. package/dist/src/platforms/slackbot/commands/message.js.map +1 -1
  99. package/dist/src/platforms/slackbot/commands/reaction.d.ts.map +1 -1
  100. package/dist/src/platforms/slackbot/commands/reaction.js.map +1 -1
  101. package/dist/src/platforms/slackbot/commands/shared.d.ts.map +1 -1
  102. package/dist/src/platforms/slackbot/commands/shared.js.map +1 -1
  103. package/dist/src/platforms/slackbot/commands/user.js.map +1 -1
  104. package/dist/src/platforms/slackbot/credential-manager.d.ts.map +1 -1
  105. package/dist/src/platforms/slackbot/credential-manager.js +2 -4
  106. package/dist/src/platforms/slackbot/credential-manager.js.map +1 -1
  107. package/dist/src/platforms/teams/client.d.ts.map +1 -1
  108. package/dist/src/platforms/teams/client.js.map +1 -1
  109. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
  110. package/dist/src/platforms/teams/commands/auth.js.map +1 -1
  111. package/dist/src/platforms/teams/commands/channel.d.ts.map +1 -1
  112. package/dist/src/platforms/teams/commands/channel.js.map +1 -1
  113. package/dist/src/platforms/teams/commands/file.d.ts.map +1 -1
  114. package/dist/src/platforms/teams/commands/file.js.map +1 -1
  115. package/dist/src/platforms/teams/commands/message.d.ts.map +1 -1
  116. package/dist/src/platforms/teams/commands/message.js.map +1 -1
  117. package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -1
  118. package/dist/src/platforms/teams/commands/reaction.js.map +1 -1
  119. package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -1
  120. package/dist/src/platforms/teams/commands/snapshot.js.map +1 -1
  121. package/dist/src/platforms/teams/commands/team.d.ts.map +1 -1
  122. package/dist/src/platforms/teams/commands/team.js +1 -4
  123. package/dist/src/platforms/teams/commands/team.js.map +1 -1
  124. package/dist/src/platforms/teams/commands/user.d.ts.map +1 -1
  125. package/dist/src/platforms/teams/commands/user.js.map +1 -1
  126. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
  127. package/dist/src/platforms/teams/token-extractor.js +3 -1
  128. package/dist/src/platforms/teams/token-extractor.js.map +1 -1
  129. package/docs/content/docs/agent-skills.mdx +4 -4
  130. package/docs/content/docs/index.mdx +11 -18
  131. package/docs/content/docs/integrations/discord.mdx +65 -1
  132. package/docs/content/docs/integrations/slack.mdx +51 -1
  133. package/docs/content/docs/integrations/slackbot.mdx +11 -1
  134. package/docs/content/docs/integrations/teams.mdx +4 -1
  135. package/docs/content/docs/quick-start.mdx +3 -2
  136. package/docs/src/app/icon.png +0 -0
  137. package/docs/src/app/layout.config.tsx +8 -1
  138. package/package.json +16 -9
  139. package/scripts/prepublish.ts +11 -0
  140. package/skills/agent-discord/SKILL.md +14 -0
  141. package/skills/agent-slack/SKILL.md +14 -0
  142. package/skills/agent-slackbot/SKILL.md +14 -0
  143. package/skills/agent-teams/SKILL.md +14 -0
  144. package/src/cli.ts +1 -4
  145. package/src/platforms/discord/client.test.ts +6 -14
  146. package/src/platforms/discord/client.ts +12 -34
  147. package/src/platforms/discord/commands/auth.test.ts +2 -7
  148. package/src/platforms/discord/commands/auth.ts +14 -19
  149. package/src/platforms/discord/commands/channel.test.ts +18 -20
  150. package/src/platforms/discord/commands/channel.ts +9 -18
  151. package/src/platforms/discord/commands/dm.test.ts +1 -3
  152. package/src/platforms/discord/commands/dm.ts +6 -10
  153. package/src/platforms/discord/commands/file.ts +10 -23
  154. package/src/platforms/discord/commands/friend.ts +33 -35
  155. package/src/platforms/discord/commands/member.ts +5 -7
  156. package/src/platforms/discord/commands/mention.ts +5 -11
  157. package/src/platforms/discord/commands/message.test.ts +1 -3
  158. package/src/platforms/discord/commands/message.ts +23 -61
  159. package/src/platforms/discord/commands/note.ts +7 -15
  160. package/src/platforms/discord/commands/profile.ts +4 -6
  161. package/src/platforms/discord/commands/reaction.test.ts +1 -3
  162. package/src/platforms/discord/commands/reaction.ts +19 -29
  163. package/src/platforms/discord/commands/server.test.ts +14 -18
  164. package/src/platforms/discord/commands/server.ts +9 -15
  165. package/src/platforms/discord/commands/snapshot.ts +5 -7
  166. package/src/platforms/discord/commands/thread.ts +8 -15
  167. package/src/platforms/discord/commands/user.ts +9 -20
  168. package/src/platforms/discord/credential-manager.test.ts +2 -2
  169. package/src/platforms/discord/credential-manager.ts +1 -3
  170. package/src/platforms/discord/token-extractor.test.ts +28 -57
  171. package/src/platforms/discord/token-extractor.ts +10 -30
  172. package/src/platforms/discord/types.ts +1 -1
  173. package/src/platforms/slack/client.test.ts +14 -20
  174. package/src/platforms/slack/client.ts +6 -11
  175. package/src/platforms/slack/commands/activity.test.ts +3 -9
  176. package/src/platforms/slack/commands/activity.ts +7 -12
  177. package/src/platforms/slack/commands/auth.test.ts +2 -2
  178. package/src/platforms/slack/commands/auth.ts +15 -31
  179. package/src/platforms/slack/commands/channel.ts +10 -32
  180. package/src/platforms/slack/commands/drafts.ts +5 -14
  181. package/src/platforms/slack/commands/file.ts +9 -29
  182. package/src/platforms/slack/commands/message.ts +23 -67
  183. package/src/platforms/slack/commands/reaction.test.ts +37 -33
  184. package/src/platforms/slack/commands/reaction.ts +21 -51
  185. package/src/platforms/slack/commands/saved.ts +5 -14
  186. package/src/platforms/slack/commands/sections.ts +4 -11
  187. package/src/platforms/slack/commands/snapshot.test.ts +1 -3
  188. package/src/platforms/slack/commands/snapshot.ts +5 -10
  189. package/src/platforms/slack/commands/unread.test.ts +6 -8
  190. package/src/platforms/slack/commands/unread.ts +10 -33
  191. package/src/platforms/slack/commands/user.test.ts +1 -4
  192. package/src/platforms/slack/commands/user.ts +6 -8
  193. package/src/platforms/slack/commands/workspace.test.ts +1 -1
  194. package/src/platforms/slack/commands/workspace.ts +7 -12
  195. package/src/platforms/slack/token-extractor-node-test.ts +1 -1
  196. package/src/platforms/slack/token-extractor.ts +8 -17
  197. package/src/platforms/slack/types.ts +11 -1
  198. package/src/platforms/slackbot/cli.ts +1 -7
  199. package/src/platforms/slackbot/client.test.ts +7 -7
  200. package/src/platforms/slackbot/client.ts +4 -11
  201. package/src/platforms/slackbot/commands/auth.test.ts +1 -1
  202. package/src/platforms/slackbot/commands/auth.ts +7 -7
  203. package/src/platforms/slackbot/commands/channel.ts +4 -4
  204. package/src/platforms/slackbot/commands/message.ts +16 -29
  205. package/src/platforms/slackbot/commands/reaction.ts +6 -16
  206. package/src/platforms/slackbot/commands/shared.ts +2 -4
  207. package/src/platforms/slackbot/commands/user.ts +4 -4
  208. package/src/platforms/slackbot/credential-manager.ts +2 -7
  209. package/src/platforms/slackbot/types.ts +1 -1
  210. package/src/platforms/teams/client.test.ts +15 -32
  211. package/src/platforms/teams/client.ts +18 -51
  212. package/src/platforms/teams/commands/auth.test.ts +6 -16
  213. package/src/platforms/teams/commands/auth.ts +16 -26
  214. package/src/platforms/teams/commands/channel.test.ts +2 -5
  215. package/src/platforms/teams/commands/channel.ts +10 -20
  216. package/src/platforms/teams/commands/file.test.ts +1 -4
  217. package/src/platforms/teams/commands/file.ts +11 -21
  218. package/src/platforms/teams/commands/message.test.ts +1 -3
  219. package/src/platforms/teams/commands/message.ts +15 -25
  220. package/src/platforms/teams/commands/reaction.test.ts +2 -7
  221. package/src/platforms/teams/commands/reaction.ts +12 -16
  222. package/src/platforms/teams/commands/snapshot.ts +6 -11
  223. package/src/platforms/teams/commands/team.test.ts +15 -26
  224. package/src/platforms/teams/commands/team.ts +10 -19
  225. package/src/platforms/teams/commands/user.ts +8 -14
  226. package/src/platforms/teams/credential-manager.test.ts +2 -5
  227. package/src/platforms/teams/token-extractor.test.ts +21 -50
  228. package/src/platforms/teams/token-extractor.ts +12 -20
  229. package/src/platforms/teams/types.ts +1 -1
  230. package/src/shared/utils/concurrency.test.ts +2 -2
  231. package/src/shared/utils/concurrency.ts +1 -1
  232. package/.claude/commands/release.md +0 -92
  233. package/dist/src/platforms/discord/commands/guild.d.ts +0 -15
  234. package/dist/src/platforms/discord/commands/guild.d.ts.map +0 -1
  235. package/dist/src/platforms/discord/commands/guild.js +0 -102
  236. package/dist/src/platforms/discord/commands/guild.js.map +0 -1
@@ -1,14 +1,9 @@
1
1
  import { Command } from 'commander'
2
- import { handleError } from '../../../shared/utils/error-handler'
3
- import { formatOutput } from '../../../shared/utils/output'
2
+ import { handleError } from '@/shared/utils/error-handler'
3
+ import { formatOutput } from '@/shared/utils/output'
4
4
  import { type BotOption, getClient } from './shared'
5
5
 
6
- async function addAction(
7
- channel: string,
8
- timestamp: string,
9
- emoji: string,
10
- options: BotOption
11
- ): Promise<void> {
6
+ async function addAction(channel: string, timestamp: string, emoji: string, options: BotOption): Promise<void> {
12
7
  try {
13
8
  const client = await getClient(options)
14
9
  await client.addReaction(channel, timestamp, emoji)
@@ -19,12 +14,7 @@ async function addAction(
19
14
  }
20
15
  }
21
16
 
22
- async function removeAction(
23
- channel: string,
24
- timestamp: string,
25
- emoji: string,
26
- options: BotOption
27
- ): Promise<void> {
17
+ async function removeAction(channel: string, timestamp: string, emoji: string, options: BotOption): Promise<void> {
28
18
  try {
29
19
  const client = await getClient(options)
30
20
  await client.removeReaction(channel, timestamp, emoji)
@@ -45,7 +35,7 @@ export const reactionCommand = new Command('reaction')
45
35
  .argument('<emoji>', 'Emoji name (with or without colons)')
46
36
  .option('--bot <id>', 'Use specific bot')
47
37
  .option('--pretty', 'Pretty print JSON output')
48
- .action(addAction)
38
+ .action(addAction),
49
39
  )
50
40
  .addCommand(
51
41
  new Command('remove')
@@ -55,5 +45,5 @@ export const reactionCommand = new Command('reaction')
55
45
  .argument('<emoji>', 'Emoji name (with or without colons)')
56
46
  .option('--bot <id>', 'Use specific bot')
57
47
  .option('--pretty', 'Pretty print JSON output')
58
- .action(removeAction)
48
+ .action(removeAction),
59
49
  )
@@ -1,4 +1,4 @@
1
- import { formatOutput } from '../../../shared/utils/output'
1
+ import { formatOutput } from '@/shared/utils/output'
2
2
  import { SlackBotClient } from '../client'
3
3
  import { SlackBotCredentialManager } from '../credential-manager'
4
4
 
@@ -13,9 +13,7 @@ export async function getClient(options: BotOption): Promise<SlackBotClient> {
13
13
  const creds = await credManager.getCredentials(options.bot)
14
14
 
15
15
  if (!creds) {
16
- console.log(
17
- formatOutput({ error: 'No credentials. Run "auth set <token>" first.' }, options.pretty)
18
- )
16
+ console.log(formatOutput({ error: 'No credentials. Run "auth set <token>" first.' }, options.pretty))
19
17
  process.exit(1)
20
18
  }
21
19
 
@@ -1,6 +1,6 @@
1
1
  import { Command } from 'commander'
2
- import { handleError } from '../../../shared/utils/error-handler'
3
- import { formatOutput } from '../../../shared/utils/output'
2
+ import { handleError } from '@/shared/utils/error-handler'
3
+ import { formatOutput } from '@/shared/utils/output'
4
4
  import { type BotOption, getClient } from './shared'
5
5
 
6
6
  async function listAction(options: BotOption & { limit?: string }): Promise<void> {
@@ -34,7 +34,7 @@ export const userCommand = new Command('user')
34
34
  .option('--limit <n>', 'Number of users to fetch')
35
35
  .option('--bot <id>', 'Use specific bot')
36
36
  .option('--pretty', 'Pretty print JSON output')
37
- .action(listAction)
37
+ .action(listAction),
38
38
  )
39
39
  .addCommand(
40
40
  new Command('info')
@@ -42,5 +42,5 @@ export const userCommand = new Command('user')
42
42
  .argument('<user>', 'User ID')
43
43
  .option('--bot <id>', 'Use specific bot')
44
44
  .option('--pretty', 'Pretty print JSON output')
45
- .action(infoAction)
45
+ .action(infoAction),
46
46
  )
@@ -166,10 +166,7 @@ export class SlackBotCredentialManager {
166
166
  if (Object.keys(workspace.bots).length === 0) {
167
167
  delete config.workspaces[workspace.workspace_id]
168
168
  }
169
- if (
170
- config.current?.workspace_id === workspace.workspace_id &&
171
- config.current?.bot_id === botId
172
- ) {
169
+ if (config.current?.workspace_id === workspace.workspace_id && config.current?.bot_id === botId) {
173
170
  config.current = null
174
171
  }
175
172
  await this.save(config)
@@ -202,9 +199,7 @@ export class SlackBotCredentialManager {
202
199
  workspace_name: workspace.workspace_name,
203
200
  bot_id: bot.bot_id,
204
201
  bot_name: bot.bot_name,
205
- is_current:
206
- config.current?.workspace_id === workspace.workspace_id &&
207
- config.current?.bot_id === bot.bot_id,
202
+ is_current: config.current?.workspace_id === workspace.workspace_id && config.current?.bot_id === bot.bot_id,
208
203
  })
209
204
  }
210
205
  }
@@ -174,7 +174,7 @@ export const SlackMessageSchema = z.object({
174
174
  z.object({
175
175
  user: z.string(),
176
176
  ts: z.string(),
177
- })
177
+ }),
178
178
  )
179
179
  .optional(),
180
180
  edited: z
@@ -15,10 +15,7 @@ describe('TeamsClient', () => {
15
15
  fetchCalls = []
16
16
  fetchResponses = []
17
17
  fetchIndex = 0
18
- ;(globalThis as any).fetch = async (
19
- url: string | URL | Request,
20
- options?: RequestInit
21
- ): Promise<Response> => {
18
+ ;(globalThis as any).fetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {
22
19
  fetchCalls.push({ url: url.toString(), options })
23
20
  const response = fetchResponses[fetchIndex]
24
21
  fetchIndex++
@@ -51,7 +48,7 @@ describe('TeamsClient', () => {
51
48
  new Response(body === null ? null : JSON.stringify(body), {
52
49
  status,
53
50
  headers: defaultHeaders,
54
- })
51
+ }),
55
52
  )
56
53
  }
57
54
 
@@ -110,9 +107,7 @@ describe('TeamsClient', () => {
110
107
  expect(user.id).toBe('ME')
111
108
  expect(user.displayName).toBe('Test User')
112
109
  expect(fetchCalls.length).toBe(1)
113
- expect(fetchCalls[0].url).toBe(
114
- 'https://emea.ng.msg.teams.microsoft.com/v1/users/ME/properties'
115
- )
110
+ expect(fetchCalls[0].url).toBe('https://emea.ng.msg.teams.microsoft.com/v1/users/ME/properties')
116
111
  expect(fetchCalls[0].options?.headers).toMatchObject({
117
112
  'X-Skypetoken': 'test-token',
118
113
  })
@@ -165,9 +160,7 @@ describe('TeamsClient', () => {
165
160
  expect(teams[0].name).toBe('Team One')
166
161
  expect(teams[1].id).toBe('222')
167
162
  expect(teams[1].name).toBe('Team Two')
168
- expect(fetchCalls[0].url).toBe(
169
- 'https://emea.ng.msg.teams.microsoft.com/v1/users/ME/conversations'
170
- )
163
+ expect(fetchCalls[0].url).toBe('https://emea.ng.msg.teams.microsoft.com/v1/users/ME/conversations')
171
164
  })
172
165
  })
173
166
 
@@ -196,9 +189,7 @@ describe('TeamsClient', () => {
196
189
 
197
190
  expect(channels).toHaveLength(2)
198
191
  expect(channels[0].name).toBe('General')
199
- expect(fetchCalls[0].url).toBe(
200
- 'https://teams.microsoft.com/api/csa/api/v1/teams/111/channels'
201
- )
192
+ expect(fetchCalls[0].url).toBe('https://teams.microsoft.com/api/csa/api/v1/teams/111/channels')
202
193
  })
203
194
  })
204
195
 
@@ -211,9 +202,7 @@ describe('TeamsClient', () => {
211
202
 
212
203
  expect(channel.id).toBe('ch1')
213
204
  expect(channel.name).toBe('General')
214
- expect(fetchCalls[0].url).toBe(
215
- 'https://teams.microsoft.com/api/csa/api/v1/teams/111/channels/ch1'
216
- )
205
+ expect(fetchCalls[0].url).toBe('https://teams.microsoft.com/api/csa/api/v1/teams/111/channels/ch1')
217
206
  })
218
207
  })
219
208
 
@@ -231,9 +220,7 @@ describe('TeamsClient', () => {
231
220
  const message = await client.sendMessage('111', 'ch1', 'Hello world')
232
221
 
233
222
  expect(message.content).toBe('Hello world')
234
- expect(fetchCalls[0].url).toBe(
235
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages'
236
- )
223
+ expect(fetchCalls[0].url).toBe('https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages')
237
224
  expect(fetchCalls[0].options?.method).toBe('POST')
238
225
  expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ content: 'Hello world' }))
239
226
  })
@@ -257,7 +244,7 @@ describe('TeamsClient', () => {
257
244
  expect(messages).toHaveLength(1)
258
245
  expect(messages[0].content).toBe('Message 1')
259
246
  expect(fetchCalls[0].url).toBe(
260
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages?limit=50'
247
+ 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages?limit=50',
261
248
  )
262
249
  })
263
250
 
@@ -268,7 +255,7 @@ describe('TeamsClient', () => {
268
255
  await client.getMessages('111', 'ch1')
269
256
 
270
257
  expect(fetchCalls[0].url).toBe(
271
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages?limit=50'
258
+ 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages?limit=50',
272
259
  )
273
260
  })
274
261
  })
@@ -288,7 +275,7 @@ describe('TeamsClient', () => {
288
275
 
289
276
  expect(message.id).toBe('msg1')
290
277
  expect(fetchCalls[0].url).toBe(
291
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1'
278
+ 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1',
292
279
  )
293
280
  })
294
281
  })
@@ -301,7 +288,7 @@ describe('TeamsClient', () => {
301
288
  await client.deleteMessage('111', 'ch1', 'msg1')
302
289
 
303
290
  expect(fetchCalls[0].url).toBe(
304
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1'
291
+ 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1',
305
292
  )
306
293
  expect(fetchCalls[0].options?.method).toBe('DELETE')
307
294
  })
@@ -315,7 +302,7 @@ describe('TeamsClient', () => {
315
302
  await client.addReaction('111', 'ch1', 'msg1', 'like')
316
303
 
317
304
  expect(fetchCalls[0].url).toBe(
318
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1/reactions'
305
+ 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1/reactions',
319
306
  )
320
307
  expect(fetchCalls[0].options?.method).toBe('POST')
321
308
  expect(fetchCalls[0].options?.body).toBe(JSON.stringify({ emoji: 'like' }))
@@ -330,7 +317,7 @@ describe('TeamsClient', () => {
330
317
  await client.removeReaction('111', 'ch1', 'msg1', 'like')
331
318
 
332
319
  expect(fetchCalls[0].url).toBe(
333
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1/reactions/like'
320
+ 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/messages/msg1/reactions/like',
334
321
  )
335
322
  expect(fetchCalls[0].options?.method).toBe('DELETE')
336
323
  })
@@ -381,9 +368,7 @@ describe('TeamsClient', () => {
381
368
  const file = await client.uploadFile('111', 'ch1', tempFile)
382
369
 
383
370
  expect(file.name).toBe('test-teams-upload.txt')
384
- expect(fetchCalls[0].url).toBe(
385
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/files'
386
- )
371
+ expect(fetchCalls[0].url).toBe('https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/files')
387
372
  expect(fetchCalls[0].options?.method).toBe('POST')
388
373
  })
389
374
  })
@@ -400,9 +385,7 @@ describe('TeamsClient', () => {
400
385
 
401
386
  expect(files).toHaveLength(2)
402
387
  expect(files[0].name).toBe('doc.pdf')
403
- expect(fetchCalls[0].url).toBe(
404
- 'https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/files'
405
- )
388
+ expect(fetchCalls[0].url).toBe('https://teams.microsoft.com/api/csa/emea/api/v2/teams/111/channels/ch1/files')
406
389
  })
407
390
  })
408
391
 
@@ -84,12 +84,7 @@ export class TeamsClient {
84
84
  return new Promise((resolve) => setTimeout(resolve, ms))
85
85
  }
86
86
 
87
- private async request<T>(
88
- method: string,
89
- path: string,
90
- body?: unknown,
91
- baseUrl: string = MSG_API_BASE
92
- ): Promise<T> {
87
+ private async request<T>(method: string, path: string, body?: unknown, baseUrl: string = MSG_API_BASE): Promise<T> {
93
88
  if (this.isTokenExpired()) {
94
89
  throw new TeamsError('Token has expired', 'token_expired')
95
90
  }
@@ -140,7 +135,7 @@ export class TeamsClient {
140
135
  } | null
141
136
  throw new TeamsError(
142
137
  errorBody?.message ?? `HTTP ${response.status}`,
143
- errorBody?.code?.toString() ?? `http_${response.status}`
138
+ errorBody?.code?.toString() ?? `http_${response.status}`,
144
139
  )
145
140
  }
146
141
 
@@ -154,11 +149,7 @@ export class TeamsClient {
154
149
  throw new TeamsError('Request failed after retries', 'max_retries')
155
150
  }
156
151
 
157
- private async requestFormData<T>(
158
- path: string,
159
- formData: FormData,
160
- baseUrl: string = MSG_API_BASE
161
- ): Promise<T> {
152
+ private async requestFormData<T>(path: string, formData: FormData, baseUrl: string = MSG_API_BASE): Promise<T> {
162
153
  if (this.isTokenExpired()) {
163
154
  throw new TeamsError('Token has expired', 'token_expired')
164
155
  }
@@ -185,7 +176,7 @@ export class TeamsClient {
185
176
  } | null
186
177
  throw new TeamsError(
187
178
  errorBody?.message ?? `HTTP ${response.status}`,
188
- errorBody?.code?.toString() ?? `http_${response.status}`
179
+ errorBody?.code?.toString() ?? `http_${response.status}`,
189
180
  )
190
181
  }
191
182
 
@@ -242,12 +233,7 @@ export class TeamsClient {
242
233
  }
243
234
 
244
235
  async listChannels(teamId: string): Promise<TeamsChannel[]> {
245
- return this.request<TeamsChannel[]>(
246
- 'GET',
247
- `/csa/api/v1/teams/${teamId}/channels`,
248
- undefined,
249
- CSA_API_BASE
250
- )
236
+ return this.request<TeamsChannel[]>('GET', `/csa/api/v1/teams/${teamId}/channels`, undefined, CSA_API_BASE)
251
237
  }
252
238
 
253
239
  async getChannel(teamId: string, channelId: string): Promise<TeamsChannel> {
@@ -255,7 +241,7 @@ export class TeamsClient {
255
241
  'GET',
256
242
  `/csa/api/v1/teams/${teamId}/channels/${channelId}`,
257
243
  undefined,
258
- CSA_API_BASE
244
+ CSA_API_BASE,
259
245
  )
260
246
  }
261
247
 
@@ -264,20 +250,16 @@ export class TeamsClient {
264
250
  'POST',
265
251
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/messages`,
266
252
  { content },
267
- CSA_API_BASE
253
+ CSA_API_BASE,
268
254
  )
269
255
  }
270
256
 
271
- async getMessages(
272
- teamId: string,
273
- channelId: string,
274
- limit: number = 50
275
- ): Promise<TeamsMessage[]> {
257
+ async getMessages(teamId: string, channelId: string, limit: number = 50): Promise<TeamsMessage[]> {
276
258
  return this.request<TeamsMessage[]>(
277
259
  'GET',
278
260
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/messages?limit=${limit}`,
279
261
  undefined,
280
- CSA_API_BASE
262
+ CSA_API_BASE,
281
263
  )
282
264
  }
283
265
 
@@ -286,7 +268,7 @@ export class TeamsClient {
286
268
  'GET',
287
269
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/messages/${messageId}`,
288
270
  undefined,
289
- CSA_API_BASE
271
+ CSA_API_BASE,
290
272
  )
291
273
  }
292
274
 
@@ -295,45 +277,30 @@ export class TeamsClient {
295
277
  'DELETE',
296
278
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/messages/${messageId}`,
297
279
  undefined,
298
- CSA_API_BASE
280
+ CSA_API_BASE,
299
281
  )
300
282
  }
301
283
 
302
- async addReaction(
303
- teamId: string,
304
- channelId: string,
305
- messageId: string,
306
- emoji: string
307
- ): Promise<void> {
284
+ async addReaction(teamId: string, channelId: string, messageId: string, emoji: string): Promise<void> {
308
285
  return this.request<void>(
309
286
  'POST',
310
287
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/messages/${messageId}/reactions`,
311
288
  { emoji },
312
- CSA_API_BASE
289
+ CSA_API_BASE,
313
290
  )
314
291
  }
315
292
 
316
- async removeReaction(
317
- teamId: string,
318
- channelId: string,
319
- messageId: string,
320
- emoji: string
321
- ): Promise<void> {
293
+ async removeReaction(teamId: string, channelId: string, messageId: string, emoji: string): Promise<void> {
322
294
  return this.request<void>(
323
295
  'DELETE',
324
296
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/messages/${messageId}/reactions/${emoji}`,
325
297
  undefined,
326
- CSA_API_BASE
298
+ CSA_API_BASE,
327
299
  )
328
300
  }
329
301
 
330
302
  async listUsers(teamId: string): Promise<TeamsUser[]> {
331
- return this.request<TeamsUser[]>(
332
- 'GET',
333
- `/csa/api/v1/teams/${teamId}/members`,
334
- undefined,
335
- CSA_API_BASE
336
- )
303
+ return this.request<TeamsUser[]>('GET', `/csa/api/v1/teams/${teamId}/members`, undefined, CSA_API_BASE)
337
304
  }
338
305
 
339
306
  async getUser(userId: string): Promise<TeamsUser> {
@@ -350,7 +317,7 @@ export class TeamsClient {
350
317
  return this.requestFormData<TeamsFile>(
351
318
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/files`,
352
319
  formData,
353
- CSA_API_BASE
320
+ CSA_API_BASE,
354
321
  )
355
322
  }
356
323
 
@@ -359,7 +326,7 @@ export class TeamsClient {
359
326
  'GET',
360
327
  `/csa/emea/api/v2/teams/${teamId}/channels/${channelId}/files`,
361
328
  undefined,
362
- CSA_API_BASE
329
+ CSA_API_BASE,
363
330
  )
364
331
  }
365
332
  }
@@ -27,25 +27,15 @@ beforeEach(() => {
27
27
  { id: 'team-2', name: 'Team Two' },
28
28
  ])
29
29
 
30
- credManagerLoadConfigSpy = spyOn(
31
- TeamsCredentialManager.prototype,
32
- 'loadConfig'
33
- ).mockResolvedValue(null)
30
+ credManagerLoadConfigSpy = spyOn(TeamsCredentialManager.prototype, 'loadConfig').mockResolvedValue(null)
34
31
 
35
- credManagerSaveConfigSpy = spyOn(
36
- TeamsCredentialManager.prototype,
37
- 'saveConfig'
38
- ).mockResolvedValue(undefined)
32
+ credManagerSaveConfigSpy = spyOn(TeamsCredentialManager.prototype, 'saveConfig').mockResolvedValue(undefined)
39
33
 
40
- credManagerClearCredentialsSpy = spyOn(
41
- TeamsCredentialManager.prototype,
42
- 'clearCredentials'
43
- ).mockResolvedValue(undefined)
34
+ credManagerClearCredentialsSpy = spyOn(TeamsCredentialManager.prototype, 'clearCredentials').mockResolvedValue(
35
+ undefined,
36
+ )
44
37
 
45
- credManagerIsTokenExpiredSpy = spyOn(
46
- TeamsCredentialManager.prototype,
47
- 'isTokenExpired'
48
- ).mockResolvedValue(false)
38
+ credManagerIsTokenExpiredSpy = spyOn(TeamsCredentialManager.prototype, 'isTokenExpired').mockResolvedValue(false)
49
39
  })
50
40
 
51
41
  afterEach(() => {
@@ -1,15 +1,11 @@
1
1
  import { Command } from 'commander'
2
- import { handleError } from '../../../shared/utils/error-handler'
3
- import { formatOutput } from '../../../shared/utils/output'
2
+ import { handleError } from '@/shared/utils/error-handler'
3
+ import { formatOutput } from '@/shared/utils/output'
4
4
  import { TeamsClient } from '../client'
5
5
  import { TeamsCredentialManager } from '../credential-manager'
6
6
  import { TeamsTokenExtractor } from '../token-extractor'
7
7
 
8
- export async function extractAction(options: {
9
- pretty?: boolean
10
- debug?: boolean
11
- token?: string
12
- }): Promise<void> {
8
+ export async function extractAction(options: { pretty?: boolean; debug?: boolean; token?: string }): Promise<void> {
13
9
  try {
14
10
  let token: string
15
11
 
@@ -48,12 +44,11 @@ export async function extractAction(options: {
48
44
  console.log(
49
45
  formatOutput(
50
46
  {
51
- error:
52
- 'No Teams token found. Make sure Microsoft Teams desktop app is installed and logged in.',
47
+ error: 'No Teams token found. Make sure Microsoft Teams desktop app is installed and logged in.',
53
48
  hint: 'Run with --token <token> to manually provide a token, or --debug for more info.',
54
49
  },
55
- options.pretty
56
- )
50
+ options.pretty,
51
+ ),
57
52
  )
58
53
  process.exit(1)
59
54
  }
@@ -88,11 +83,10 @@ export async function extractAction(options: {
88
83
  console.log(
89
84
  formatOutput(
90
85
  {
91
- error:
92
- 'No teams found. Make sure you are a member of at least one Microsoft Teams team.',
86
+ error: 'No teams found. Make sure you are a member of at least one Microsoft Teams team.',
93
87
  },
94
- options.pretty
95
- )
88
+ options.pretty,
89
+ ),
96
90
  )
97
91
  process.exit(1)
98
92
  }
@@ -137,8 +131,8 @@ export async function extractAction(options: {
137
131
  ? 'Token expired. Open Microsoft Teams, send a message to refresh your session, then run "auth extract" again.'
138
132
  : 'Make sure Microsoft Teams desktop app is running and you are logged in.',
139
133
  },
140
- options.pretty
141
- )
134
+ options.pretty,
135
+ ),
142
136
  )
143
137
  process.exit(1)
144
138
  }
@@ -153,9 +147,7 @@ export async function logoutAction(options: { pretty?: boolean }): Promise<void>
153
147
  const config = await credManager.loadConfig()
154
148
 
155
149
  if (!config?.token) {
156
- console.log(
157
- formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
158
- )
150
+ console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
159
151
  process.exit(1)
160
152
  }
161
153
 
@@ -173,9 +165,7 @@ export async function statusAction(options: { pretty?: boolean }): Promise<void>
173
165
  const config = await credManager.loadConfig()
174
166
 
175
167
  if (!config?.token) {
176
- console.log(
177
- formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
178
- )
168
+ console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
179
169
  process.exit(1)
180
170
  }
181
171
 
@@ -216,17 +206,17 @@ export const authCommand = new Command('auth')
216
206
  .option('--pretty', 'Pretty print JSON output')
217
207
  .option('--debug', 'Show debug output for troubleshooting')
218
208
  .option('--token <token>', 'Manually provide a token (bypasses auto-extraction)')
219
- .action(extractAction)
209
+ .action(extractAction),
220
210
  )
221
211
  .addCommand(
222
212
  new Command('logout')
223
213
  .description('Logout from Microsoft Teams')
224
214
  .option('--pretty', 'Pretty print JSON output')
225
- .action(logoutAction)
215
+ .action(logoutAction),
226
216
  )
227
217
  .addCommand(
228
218
  new Command('status')
229
219
  .description('Show authentication status')
230
220
  .option('--pretty', 'Pretty print JSON output')
231
- .action(statusAction)
221
+ .action(statusAction),
232
222
  )
@@ -22,7 +22,7 @@ beforeEach(() => {
22
22
  return { id: 'ch-2', team_id: teamId, name: 'Announcements', type: 'standard' }
23
23
  }
24
24
  throw new Error('Channel not found')
25
- }
25
+ },
26
26
  )
27
27
 
28
28
  clientGetMessagesSpy = spyOn(TeamsClient.prototype, 'getMessages').mockResolvedValue([
@@ -42,10 +42,7 @@ beforeEach(() => {
42
42
  },
43
43
  ])
44
44
 
45
- credManagerLoadConfigSpy = spyOn(
46
- TeamsCredentialManager.prototype,
47
- 'loadConfig'
48
- ).mockResolvedValue({
45
+ credManagerLoadConfigSpy = spyOn(TeamsCredentialManager.prototype, 'loadConfig').mockResolvedValue({
49
46
  token: 'test-token',
50
47
  current_team: 'team-1',
51
48
  teams: {