agent-messenger 1.9.2 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/package.json +1 -1
  3. package/dist/src/platforms/discord/commands/server.d.ts.map +1 -1
  4. package/dist/src/platforms/discord/commands/server.js +5 -2
  5. package/dist/src/platforms/discord/commands/server.js.map +1 -1
  6. package/dist/src/platforms/discord/token-extractor.d.ts +1 -0
  7. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  8. package/dist/src/platforms/discord/token-extractor.js +7 -0
  9. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  10. package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
  11. package/dist/src/platforms/discordbot/client.js +1 -1
  12. package/dist/src/platforms/discordbot/client.js.map +1 -1
  13. package/dist/src/platforms/slack/commands/auth.d.ts +1 -0
  14. package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
  15. package/dist/src/platforms/slack/commands/auth.js +28 -6
  16. package/dist/src/platforms/slack/commands/auth.js.map +1 -1
  17. package/dist/src/platforms/slack/commands/file.d.ts.map +1 -1
  18. package/dist/src/platforms/slack/commands/file.js +1 -1
  19. package/dist/src/platforms/slack/commands/file.js.map +1 -1
  20. package/dist/src/platforms/slack/commands/reaction.js +4 -4
  21. package/dist/src/platforms/slack/commands/reaction.js.map +1 -1
  22. package/dist/src/platforms/slack/commands/workspace.d.ts.map +1 -1
  23. package/dist/src/platforms/slack/commands/workspace.js +2 -2
  24. package/dist/src/platforms/slack/commands/workspace.js.map +1 -1
  25. package/dist/src/platforms/slack/ensure-auth.d.ts +7 -0
  26. package/dist/src/platforms/slack/ensure-auth.d.ts.map +1 -1
  27. package/dist/src/platforms/slack/ensure-auth.js +29 -3
  28. package/dist/src/platforms/slack/ensure-auth.js.map +1 -1
  29. package/dist/src/platforms/slack/token-extractor.d.ts +10 -2
  30. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  31. package/dist/src/platforms/slack/token-extractor.js +147 -23
  32. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  33. package/dist/src/platforms/teams/client.js +2 -2
  34. package/dist/src/platforms/teams/client.js.map +1 -1
  35. package/dist/src/platforms/teams/commands/team.d.ts.map +1 -1
  36. package/dist/src/platforms/teams/commands/team.js +4 -4
  37. package/dist/src/platforms/teams/commands/team.js.map +1 -1
  38. package/package.json +1 -1
  39. package/skills/agent-discord/SKILL.md +1 -1
  40. package/skills/agent-discordbot/SKILL.md +1 -1
  41. package/skills/agent-slack/SKILL.md +1 -1
  42. package/skills/agent-slackbot/SKILL.md +1 -1
  43. package/skills/agent-teams/SKILL.md +1 -1
  44. package/src/platforms/discord/commands/server.ts +15 -2
  45. package/src/platforms/discord/token-extractor.test.ts +25 -0
  46. package/src/platforms/discord/token-extractor.ts +7 -0
  47. package/src/platforms/discordbot/client.ts +4 -1
  48. package/src/platforms/slack/commands/auth.test.ts +23 -0
  49. package/src/platforms/slack/commands/auth.ts +34 -6
  50. package/src/platforms/slack/commands/file.ts +6 -1
  51. package/src/platforms/slack/commands/reaction.ts +4 -4
  52. package/src/platforms/slack/commands/workspace.ts +12 -2
  53. package/src/platforms/slack/ensure-auth.test.ts +54 -1
  54. package/src/platforms/slack/ensure-auth.ts +32 -2
  55. package/src/platforms/slack/token-extractor.test.ts +207 -0
  56. package/src/platforms/slack/token-extractor.ts +161 -28
  57. package/src/platforms/teams/client.ts +2 -2
  58. package/src/platforms/teams/commands/team.ts +14 -4
@@ -1 +1 @@
1
- {"version":3,"file":"team.js","sourceRoot":"","sources":["../../../../../src/platforms/teams/commands/team.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../../../../../src/platforms/teams/commands/team.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA6B;IAC5D,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAChD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,iBAAiB,EAAE,CAAA;QACrD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAEhE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,IAAI,CAAC,OAAO;YAChB,IAAI,EAAE,IAAI,CAAC,SAAS;YACpB,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,YAAY;SAChD,CAAC,CAAC,CAAA;QAEH,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAc,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,EAAE,OAA6B;IAC5E,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAChD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,kBAAkB,EAAE,CAAA;QAEnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;YACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QAC/D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAEzC,MAAM,MAAM,GAAG;YACb,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAA;QAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAc,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,OAA6B;IAC9E,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAChD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,iBAAiB,EAAE,CAAA;QAErD,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CACT,YAAY,CACV,EAAE,KAAK,EAAE,mBAAmB,MAAM,EAAE,EAAE,IAAI,EAAE,yCAAyC,EAAE,EACvF,OAAO,CAAC,MAAM,CACf,CACF,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAClC,MAAM,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAc,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAChD,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,cAAc,EAAE,CAAA;QAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,gDAAgD,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;YACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/G,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAc,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,OAA6B;IAC9E,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAChD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,CAAA;QAE7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,mDAAmD,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;YACzG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,iBAAiB,EAAE,CAAA;QACrD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;YACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACT,YAAY,CACV,EAAE,KAAK,EAAE,mBAAmB,MAAM,EAAE,EAAE,IAAI,EAAE,yCAAyC,EAAE,EACvF,OAAO,CAAC,MAAM,CACf,CACF,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAE5B,IAAI,OAAO,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC;YACpC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAA;QAC7B,CAAC;QAED,MAAM,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QACpC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAc,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,0BAA0B,CAAC;KACvC,UAAU,CACT,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CACpH;KACA,UAAU,CACT,IAAI,OAAO,CAAC,MAAM,CAAC;KAChB,WAAW,CAAC,eAAe,CAAC;KAC5B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;KAChC,MAAM,CAAC,UAAU,EAAE,0BAA0B,CAAC;KAC9C,MAAM,CAAC,UAAU,CAAC,CACtB;KACA,UAAU,CACT,IAAI,OAAO,CAAC,QAAQ,CAAC;KAClB,WAAW,CAAC,gBAAgB,CAAC;KAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;KAChC,MAAM,CAAC,UAAU,EAAE,0BAA0B,CAAC;KAC9C,MAAM,CAAC,YAAY,CAAC,CACxB;KACA,UAAU,CACT,IAAI,OAAO,CAAC,SAAS,CAAC;KACnB,WAAW,CAAC,mBAAmB,CAAC;KAChC,MAAM,CAAC,UAAU,EAAE,0BAA0B,CAAC;KAC9C,MAAM,CAAC,aAAa,CAAC,CACzB;KACA,UAAU,CACT,IAAI,OAAO,CAAC,QAAQ,CAAC;KAClB,WAAW,CAAC,yBAAyB,CAAC;KACtC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;KAChC,MAAM,CAAC,UAAU,EAAE,0BAA0B,CAAC;KAC9C,MAAM,CAAC,YAAY,CAAC,CACxB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-messenger",
3
- "version": "1.9.2",
3
+ "version": "1.10.0",
4
4
  "description": "Multi-platform messaging CLI for AI agents (Slack, Discord, Teams)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-discord
3
3
  description: Interact with Discord servers - send messages, read channels, manage reactions
4
- version: 1.9.2
4
+ version: 1.10.0
5
5
  allowed-tools: Bash(agent-discord:*)
6
6
  metadata:
7
7
  openclaw:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-discordbot
3
3
  description: Interact with Discord servers using bot tokens - send messages, read channels, manage reactions
4
- version: 1.9.2
4
+ version: 1.10.0
5
5
  allowed-tools: Bash(agent-discordbot:*)
6
6
  metadata:
7
7
  openclaw:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-slack
3
3
  description: Interact with Slack workspaces - send messages, read channels, manage reactions
4
- version: 1.9.2
4
+ version: 1.10.0
5
5
  allowed-tools: Bash(agent-slack:*)
6
6
  metadata:
7
7
  openclaw:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-slackbot
3
3
  description: Interact with Slack workspaces using bot tokens - send messages, read channels, manage reactions
4
- version: 1.9.2
4
+ version: 1.10.0
5
5
  allowed-tools: Bash(agent-slackbot:*)
6
6
  metadata:
7
7
  openclaw:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-teams
3
3
  description: Interact with Microsoft Teams - send messages, read channels, manage reactions
4
- version: 1.9.2
4
+ version: 1.10.0
5
5
  allowed-tools: Bash(agent-teams:*)
6
6
  metadata:
7
7
  openclaw:
@@ -54,7 +54,12 @@ export async function switchAction(serverId: string, options: { pretty?: boolean
54
54
  const config = await credManager.load()
55
55
 
56
56
  if (!config.servers[serverId]) {
57
- console.log(formatOutput({ error: `Server not found: ${serverId}` }, options.pretty))
57
+ console.log(
58
+ formatOutput(
59
+ { error: `Server not found: ${serverId}`, hint: 'Run "server list" to see available servers.' },
60
+ options.pretty,
61
+ ),
62
+ )
58
63
  process.exit(1)
59
64
  }
60
65
 
@@ -78,7 +83,15 @@ export async function currentAction(options: { pretty?: boolean }): Promise<void
78
83
  const server = config.servers[config.current_server]
79
84
 
80
85
  if (!server) {
81
- console.log(formatOutput({ error: 'Current server not found in configuration.' }, options.pretty))
86
+ console.log(
87
+ formatOutput(
88
+ {
89
+ error: 'Current server not found in configuration.',
90
+ hint: 'Run "auth extract" to refresh, or "server switch <server-id>".',
91
+ },
92
+ options.pretty,
93
+ ),
94
+ )
82
95
  process.exit(1)
83
96
  }
84
97
 
@@ -79,6 +79,31 @@ describe('DiscordTokenExtractor', () => {
79
79
  })
80
80
  })
81
81
 
82
+ describe('Linux token decryption', () => {
83
+ test('decrypts encrypted token using peanuts password on Linux', () => {
84
+ // given — AES-128-CBC encrypted token with Linux Chromium key
85
+ const { createCipheriv, pbkdf2Sync } = require('node:crypto')
86
+ const plainToken = 'XXXXXXXXXXXXXXXXXXXXXXXX.YYYYYY.ZZZZZZZZZZZZZZZZZZZZZZZZZ'
87
+ const key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1')
88
+ const iv = Buffer.alloc(16, 0x20)
89
+ const cipher = createCipheriv('aes-128-cbc', key, iv)
90
+ const ciphertext = Buffer.concat([cipher.update(plainToken, 'utf8'), cipher.final()])
91
+ // v10 prefix (3 bytes) + ciphertext
92
+ const encrypted = Buffer.concat([Buffer.from('v10'), ciphertext])
93
+ const encryptedToken = `dQw4w9WgXcQ:${encrypted.toString('base64')}`
94
+
95
+ const linuxExtractor = new DiscordTokenExtractor('linux')
96
+ const decryptTokenSpy = spyOn(linuxExtractor as any, 'decryptToken')
97
+ decryptTokenSpy.mockRestore()
98
+
99
+ // when
100
+ const result = (linuxExtractor as any).decryptToken(encryptedToken, '/home/user/.config/discord')
101
+
102
+ // then
103
+ expect(result).toBe(plainToken)
104
+ })
105
+ })
106
+
82
107
  describe('extract', () => {
83
108
  test('returns null when no Discord directories exist on linux', async () => {
84
109
  const linuxExtractor = new DiscordTokenExtractor('linux')
@@ -260,6 +260,8 @@ export class DiscordTokenExtractor {
260
260
  return this.decryptWindowsToken(encryptedData, discordDir)
261
261
  } else if (this.platform === 'darwin') {
262
262
  return this.decryptMacToken(encryptedData, discordDir)
263
+ } else if (this.platform === 'linux') {
264
+ return this.decryptLinuxToken(encryptedData)
263
265
  }
264
266
 
265
267
  return null
@@ -335,6 +337,11 @@ export class DiscordTokenExtractor {
335
337
  return null
336
338
  }
337
339
 
340
+ private decryptLinuxToken(encryptedData: Buffer): string | null {
341
+ const key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1')
342
+ return this.decryptAESCBC(encryptedData, key)
343
+ }
344
+
338
345
  private decryptAESCBC(encryptedData: Buffer, key: Buffer): string | null {
339
346
  try {
340
347
  const ciphertext = encryptedData.subarray(3)
@@ -334,7 +334,10 @@ export class DiscordBotClient {
334
334
  const channels = await this.listChannels(guildId)
335
335
  const found = channels.find((c) => c.name === channel || c.name === channel.replace(/^#/, ''))
336
336
  if (!found) {
337
- throw new DiscordBotError(`Channel not found: "${channel}"`, 'channel_not_found')
337
+ throw new DiscordBotError(
338
+ `Channel not found: "${channel}". Use channel ID or exact channel name.`,
339
+ 'channel_not_found',
340
+ )
338
341
  }
339
342
  return found.id
340
343
  }
@@ -2,6 +2,7 @@ import { afterAll, beforeEach, describe, expect, mock, test } from 'bun:test'
2
2
  import { mkdirSync, rmSync } from 'node:fs'
3
3
  import { homedir } from 'node:os'
4
4
  import { join } from 'node:path'
5
+ import { getExtractionErrorMessage } from '@/platforms/slack/commands/auth'
5
6
  import { CredentialManager } from '@/platforms/slack/credential-manager'
6
7
  import { type ExtractedWorkspace, TokenExtractor } from '@/platforms/slack/token-extractor'
7
8
 
@@ -351,6 +352,28 @@ describe('Output Formatting', () => {
351
352
  })
352
353
  })
353
354
 
355
+ describe('getExtractionErrorMessage', () => {
356
+ test('returns cookie failure message for missing_cookie', () => {
357
+ expect(getExtractionErrorMessage(['missing_cookie'])).toContain('Cookie extraction failed')
358
+ })
359
+
360
+ test('returns session expired message for invalid_auth', () => {
361
+ expect(getExtractionErrorMessage(['invalid_auth'])).toContain('session has expired')
362
+ })
363
+
364
+ test('prioritizes missing_cookie over invalid_auth', () => {
365
+ expect(getExtractionErrorMessage(['invalid_auth', 'missing_cookie'])).toContain('Cookie extraction failed')
366
+ })
367
+
368
+ test('returns generic message for unknown error codes', () => {
369
+ expect(getExtractionErrorMessage(['unknown_error'])).toContain('Extracted tokens are invalid')
370
+ })
371
+
372
+ test('returns generic message for empty failure list', () => {
373
+ expect(getExtractionErrorMessage([])).toContain('Extracted tokens are invalid')
374
+ })
375
+ })
376
+
354
377
  describe('Error Handling', () => {
355
378
  beforeEach(() => {
356
379
  rmSync(testSlackDir, { recursive: true, force: true })
@@ -1,13 +1,15 @@
1
1
  import { Command } from 'commander'
2
2
  import { handleError } from '@/shared/utils/error-handler'
3
3
  import { formatOutput } from '@/shared/utils/output'
4
- import { SlackClient } from '../client'
4
+ import { SlackClient, SlackError } from '../client'
5
5
  import { CredentialManager } from '../credential-manager'
6
+ import { refreshCookie } from '../ensure-auth'
6
7
  import { TokenExtractor } from '../token-extractor'
7
8
 
8
9
  async function extractAction(options: { pretty?: boolean; debug?: boolean }): Promise<void> {
9
10
  try {
10
- const extractor = new TokenExtractor()
11
+ const debugLog = options.debug ? (msg: string) => console.error(`[debug] ${msg}`) : undefined
12
+ const extractor = new TokenExtractor(undefined, undefined, undefined, debugLog)
11
13
 
12
14
  if (process.platform === 'darwin') {
13
15
  console.log('')
@@ -58,6 +60,7 @@ async function extractAction(options: { pretty?: boolean; debug?: boolean }): Pr
58
60
  const config = await credManager.load()
59
61
 
60
62
  const validWorkspaces = []
63
+ const failureReasons: string[] = []
61
64
  for (const ws of workspaces) {
62
65
  if (options.debug) {
63
66
  console.error(`[debug] Testing credentials for ${ws.workspace_id}...`)
@@ -74,6 +77,10 @@ async function extractAction(options: { pretty?: boolean; debug?: boolean }): Pr
74
77
  console.error(`[debug] ✓ Valid: ${authInfo.team} (${authInfo.user})`)
75
78
  }
76
79
  } catch (error) {
80
+ const code = error instanceof SlackError ? error.code : undefined
81
+ if (code && !failureReasons.includes(code)) {
82
+ failureReasons.push(code)
83
+ }
77
84
  if (options.debug) {
78
85
  console.error(`[debug] ✗ Invalid: ${(error as Error).message}`)
79
86
  }
@@ -81,11 +88,13 @@ async function extractAction(options: { pretty?: boolean; debug?: boolean }): Pr
81
88
  }
82
89
 
83
90
  if (validWorkspaces.length === 0) {
91
+ const errorMessage = getExtractionErrorMessage(failureReasons)
84
92
  console.log(
85
93
  formatOutput(
86
94
  {
87
- error: 'Extracted tokens are invalid. Make sure you are logged into the Slack desktop app.',
95
+ error: errorMessage,
88
96
  extracted_count: workspaces.length,
97
+ hint: options.debug ? undefined : 'Run with --debug for more details.',
89
98
  },
90
99
  options.pretty,
91
100
  ),
@@ -124,7 +133,15 @@ async function logoutAction(workspace: string | undefined, options: { pretty?: b
124
133
  }
125
134
 
126
135
  if (!config.workspaces[targetWorkspace]) {
127
- console.log(formatOutput({ error: `Workspace not found: ${targetWorkspace}` }, options.pretty))
136
+ console.log(
137
+ formatOutput(
138
+ {
139
+ error: `Workspace not found: ${targetWorkspace}`,
140
+ hint: 'Run "workspace list" to see available workspaces.',
141
+ },
142
+ options.pretty,
143
+ ),
144
+ )
128
145
  process.exit(1)
129
146
  }
130
147
 
@@ -142,7 +159,7 @@ async function statusAction(options: { pretty?: boolean }): Promise<void> {
142
159
  const ws = await credManager.getWorkspace()
143
160
 
144
161
  if (!ws) {
145
- console.log(formatOutput({ error: 'No workspace configured. Run "auth extract" first.' }, options.pretty))
162
+ console.log(formatOutput({ error: 'No current workspace set. Run "auth extract" first.' }, options.pretty))
146
163
  process.exit(1)
147
164
  }
148
165
 
@@ -154,7 +171,8 @@ async function statusAction(options: { pretty?: boolean }): Promise<void> {
154
171
  authInfo = await client.testAuth()
155
172
  valid = true
156
173
  } catch {
157
- valid = false
174
+ authInfo = await refreshCookie(ws.token, credManager)
175
+ valid = authInfo !== null
158
176
  }
159
177
 
160
178
  const output = {
@@ -171,6 +189,16 @@ async function statusAction(options: { pretty?: boolean }): Promise<void> {
171
189
  }
172
190
  }
173
191
 
192
+ export function getExtractionErrorMessage(failureReasons: string[]): string {
193
+ if (failureReasons.includes('missing_cookie')) {
194
+ return 'Cookie extraction failed. Make sure the Slack desktop app is installed and grant Keychain access when prompted.'
195
+ }
196
+ if (failureReasons.includes('invalid_auth')) {
197
+ return 'Slack session has expired. Sign into the Slack desktop app, wait a few seconds, then re-run this command.'
198
+ }
199
+ return 'Extracted tokens are invalid. Make sure you are logged into the Slack desktop app.'
200
+ }
201
+
174
202
  export const authCommand = new Command('auth')
175
203
  .description('Authentication commands')
176
204
  .addCommand(
@@ -94,7 +94,12 @@ async function infoAction(fileId: string, options: { pretty?: boolean }): Promis
94
94
  const fileData = files.find((f) => f.id === fileId)
95
95
 
96
96
  if (!fileData) {
97
- console.log(formatOutput({ error: `File not found: ${fileId}` }, options.pretty))
97
+ console.log(
98
+ formatOutput(
99
+ { error: `File not found: ${fileId}`, hint: 'Run "file list" to see available files.' },
100
+ options.pretty,
101
+ ),
102
+ )
98
103
  process.exit(1)
99
104
  }
100
105
 
@@ -10,7 +10,7 @@ async function addAction(channel: string, ts: string, emoji: string, options: {
10
10
  const ws = await credManager.getWorkspace()
11
11
 
12
12
  if (!ws) {
13
- console.log(formatOutput({ error: 'No workspace configured. Run "auth extract" first.' }, options.pretty))
13
+ console.log(formatOutput({ error: 'No current workspace set. Run "auth extract" first.' }, options.pretty))
14
14
  process.exit(1)
15
15
  }
16
16
 
@@ -40,7 +40,7 @@ async function removeAction(channel: string, ts: string, emoji: string, options:
40
40
  const ws = await credManager.getWorkspace()
41
41
 
42
42
  if (!ws) {
43
- console.log(formatOutput({ error: 'No workspace configured. Run "auth extract" first.' }, options.pretty))
43
+ console.log(formatOutput({ error: 'No current workspace set. Run "auth extract" first.' }, options.pretty))
44
44
  process.exit(1)
45
45
  }
46
46
 
@@ -70,7 +70,7 @@ async function listAction(channel: string, ts: string, options: { pretty?: boole
70
70
  const ws = await credManager.getWorkspace()
71
71
 
72
72
  if (!ws) {
73
- console.log(formatOutput({ error: 'No workspace configured. Run "auth extract" first.' }, options.pretty))
73
+ console.log(formatOutput({ error: 'No current workspace set. Run "auth extract" first.' }, options.pretty))
74
74
  process.exit(1)
75
75
  }
76
76
 
@@ -82,7 +82,7 @@ async function listAction(channel: string, ts: string, options: { pretty?: boole
82
82
  console.log(
83
83
  formatOutput(
84
84
  {
85
- error: 'Message not found',
85
+ error: `Message not found: ${ts}`,
86
86
  channel,
87
87
  ts,
88
88
  },
@@ -27,7 +27,12 @@ async function switchAction(id: string, options: { pretty?: boolean }): Promise<
27
27
  const config = await credManager.load()
28
28
 
29
29
  if (!config.workspaces[id]) {
30
- console.log(formatOutput({ error: `Workspace not found: ${id}` }, options.pretty))
30
+ console.log(
31
+ formatOutput(
32
+ { error: `Workspace not found: ${id}`, hint: 'Run "workspace list" to see available workspaces.' },
33
+ options.pretty,
34
+ ),
35
+ )
31
36
  process.exit(1)
32
37
  }
33
38
 
@@ -65,7 +70,12 @@ async function removeAction(id: string, options: { pretty?: boolean }): Promise<
65
70
  const config = await credManager.load()
66
71
 
67
72
  if (!config.workspaces[id]) {
68
- console.log(formatOutput({ error: `Workspace not found: ${id}` }, options.pretty))
73
+ console.log(
74
+ formatOutput(
75
+ { error: `Workspace not found: ${id}`, hint: 'Run "workspace list" to see available workspaces.' },
76
+ options.pretty,
77
+ ),
78
+ )
69
79
  process.exit(1)
70
80
  }
71
81
 
@@ -6,6 +6,7 @@ import { TokenExtractor } from './token-extractor'
6
6
 
7
7
  let getWorkspaceSpy: ReturnType<typeof spyOn>
8
8
  let extractSpy: ReturnType<typeof spyOn>
9
+ let extractCookieSpy: ReturnType<typeof spyOn>
9
10
  let testAuthSpy: ReturnType<typeof spyOn>
10
11
  let setWorkspaceSpy: ReturnType<typeof spyOn>
11
12
  let loadSpy: ReturnType<typeof spyOn>
@@ -23,6 +24,8 @@ beforeEach(() => {
23
24
  },
24
25
  ])
25
26
 
27
+ extractCookieSpy = spyOn(TokenExtractor.prototype, 'extractCookie').mockResolvedValue('xoxd-fresh-cookie')
28
+
26
29
  testAuthSpy = spyOn(SlackClient.prototype, 'testAuth').mockResolvedValue({
27
30
  user_id: 'U123',
28
31
  team_id: 'T123',
@@ -43,6 +46,7 @@ beforeEach(() => {
43
46
  afterEach(() => {
44
47
  getWorkspaceSpy?.mockRestore()
45
48
  extractSpy?.mockRestore()
49
+ extractCookieSpy?.mockRestore()
46
50
  testAuthSpy?.mockRestore()
47
51
  setWorkspaceSpy?.mockRestore()
48
52
  loadSpy?.mockRestore()
@@ -50,7 +54,7 @@ afterEach(() => {
50
54
  })
51
55
 
52
56
  describe('ensureSlackAuth', () => {
53
- test('skips extraction when credentials already exist', async () => {
57
+ test('skips extraction when stored credentials are valid', async () => {
54
58
  // given
55
59
  getWorkspaceSpy.mockResolvedValue({
56
60
  workspace_id: 'T123',
@@ -63,9 +67,58 @@ describe('ensureSlackAuth', () => {
63
67
  await ensureSlackAuth()
64
68
 
65
69
  // then
70
+ expect(testAuthSpy).toHaveBeenCalled()
66
71
  expect(extractSpy).not.toHaveBeenCalled()
67
72
  })
68
73
 
74
+ test('refreshes cookie when stored credentials are stale', async () => {
75
+ // given
76
+ getWorkspaceSpy.mockResolvedValue({
77
+ workspace_id: 'T123',
78
+ workspace_name: 'existing',
79
+ token: 'xoxc-existing',
80
+ cookie: 'xoxd-old-cookie',
81
+ })
82
+ let callCount = 0
83
+ testAuthSpy.mockImplementation(() => {
84
+ callCount++
85
+ if (callCount === 1) throw new Error('invalid_auth')
86
+ return Promise.resolve({ user_id: 'U1', team_id: 'T123', user: 'user', team: 'Team' })
87
+ })
88
+ loadSpy.mockResolvedValue({
89
+ current_workspace: 'T123',
90
+ workspaces: {
91
+ T123: { workspace_id: 'T123', workspace_name: 'existing', token: 'xoxc-existing', cookie: 'xoxd-old-cookie' },
92
+ },
93
+ })
94
+
95
+ // when
96
+ await ensureSlackAuth()
97
+
98
+ // then — cookie refreshed, no full extraction
99
+ expect(extractCookieSpy).toHaveBeenCalled()
100
+ expect(extractSpy).not.toHaveBeenCalled()
101
+ expect(setWorkspaceSpy).toHaveBeenCalledWith(expect.objectContaining({ cookie: 'xoxd-fresh-cookie' }))
102
+ })
103
+
104
+ test('falls through to full extraction when cookie refresh fails', async () => {
105
+ // given
106
+ getWorkspaceSpy.mockResolvedValue({
107
+ workspace_id: 'T123',
108
+ workspace_name: 'existing',
109
+ token: 'xoxc-existing',
110
+ cookie: 'xoxd-old-cookie',
111
+ })
112
+ testAuthSpy.mockRejectedValue(new Error('invalid_auth'))
113
+ extractCookieSpy.mockResolvedValue('')
114
+
115
+ // when
116
+ await ensureSlackAuth()
117
+
118
+ // then — falls through to full extraction
119
+ expect(extractSpy).toHaveBeenCalled()
120
+ })
121
+
69
122
  test('extracts and saves credentials when none exist', async () => {
70
123
  // when
71
124
  await ensureSlackAuth()
@@ -5,7 +5,16 @@ import { TokenExtractor } from './token-extractor'
5
5
  export async function ensureSlackAuth(): Promise<void> {
6
6
  const credManager = new CredentialManager()
7
7
  const workspace = await credManager.getWorkspace()
8
- if (workspace) return
8
+
9
+ if (workspace) {
10
+ try {
11
+ const client = new SlackClient(workspace.token, workspace.cookie)
12
+ await client.testAuth()
13
+ return
14
+ } catch {
15
+ if (await refreshCookie(workspace.token, credManager)) return
16
+ }
17
+ }
9
18
 
10
19
  try {
11
20
  const extractor = new TokenExtractor()
@@ -32,6 +41,27 @@ export async function ensureSlackAuth(): Promise<void> {
32
41
  if (code === 'EBUSY' || message.includes('locking the cookie')) {
33
42
  throw error
34
43
  }
35
- // Silently ignore other extraction errors (e.g. Slack not installed)
44
+ }
45
+ }
46
+
47
+ export async function refreshCookie(
48
+ token: string,
49
+ credManager: CredentialManager,
50
+ ): Promise<{ user_id: string; team_id: string; user?: string; team?: string } | null> {
51
+ try {
52
+ const extractor = new TokenExtractor()
53
+ const freshCookie = await extractor.extractCookie()
54
+ if (!freshCookie) return null
55
+
56
+ const client = new SlackClient(token, freshCookie)
57
+ const authInfo = await client.testAuth()
58
+
59
+ const config = await credManager.load()
60
+ for (const ws of Object.values(config.workspaces)) {
61
+ await credManager.setWorkspace({ ...ws, cookie: freshCookie })
62
+ }
63
+ return authInfo
64
+ } catch {
65
+ return null
36
66
  }
37
67
  }