agent-messenger 2.15.0 → 2.16.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 (85) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +1 -1
  3. package/dist/package.json +1 -1
  4. package/dist/src/platforms/kakaotalk/attachment-router.d.ts +25 -0
  5. package/dist/src/platforms/kakaotalk/attachment-router.d.ts.map +1 -0
  6. package/dist/src/platforms/kakaotalk/attachment-router.js +29 -0
  7. package/dist/src/platforms/kakaotalk/attachment-router.js.map +1 -0
  8. package/dist/src/platforms/kakaotalk/client.d.ts +14 -1
  9. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  10. package/dist/src/platforms/kakaotalk/client.js +216 -0
  11. package/dist/src/platforms/kakaotalk/client.js.map +1 -1
  12. package/dist/src/platforms/kakaotalk/commands/message.d.ts.map +1 -1
  13. package/dist/src/platforms/kakaotalk/commands/message.js +49 -0
  14. package/dist/src/platforms/kakaotalk/commands/message.js.map +1 -1
  15. package/dist/src/platforms/kakaotalk/image-meta.d.ts +7 -0
  16. package/dist/src/platforms/kakaotalk/image-meta.d.ts.map +1 -0
  17. package/dist/src/platforms/kakaotalk/image-meta.js +153 -0
  18. package/dist/src/platforms/kakaotalk/image-meta.js.map +1 -0
  19. package/dist/src/platforms/kakaotalk/index.d.ts +6 -2
  20. package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
  21. package/dist/src/platforms/kakaotalk/index.js +4 -1
  22. package/dist/src/platforms/kakaotalk/index.js.map +1 -1
  23. package/dist/src/platforms/kakaotalk/media-upload.d.ts +3 -0
  24. package/dist/src/platforms/kakaotalk/media-upload.d.ts.map +1 -0
  25. package/dist/src/platforms/kakaotalk/media-upload.js +44 -0
  26. package/dist/src/platforms/kakaotalk/media-upload.js.map +1 -0
  27. package/dist/src/platforms/kakaotalk/protocol/connection.d.ts +1 -0
  28. package/dist/src/platforms/kakaotalk/protocol/connection.d.ts.map +1 -1
  29. package/dist/src/platforms/kakaotalk/protocol/connection.js +11 -0
  30. package/dist/src/platforms/kakaotalk/protocol/connection.js.map +1 -1
  31. package/dist/src/platforms/kakaotalk/protocol/media-uploader.d.ts +25 -0
  32. package/dist/src/platforms/kakaotalk/protocol/media-uploader.d.ts.map +1 -0
  33. package/dist/src/platforms/kakaotalk/protocol/media-uploader.js +99 -0
  34. package/dist/src/platforms/kakaotalk/protocol/media-uploader.js.map +1 -0
  35. package/dist/src/platforms/kakaotalk/protocol/session.d.ts +6 -0
  36. package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
  37. package/dist/src/platforms/kakaotalk/protocol/session.js +61 -0
  38. package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
  39. package/dist/src/platforms/kakaotalk/types.d.ts +44 -0
  40. package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
  41. package/dist/src/platforms/kakaotalk/types.js +9 -0
  42. package/dist/src/platforms/kakaotalk/types.js.map +1 -1
  43. package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
  44. package/dist/src/platforms/slack/commands/auth.js +6 -2
  45. package/dist/src/platforms/slack/commands/auth.js.map +1 -1
  46. package/dist/src/platforms/slack/ensure-auth.d.ts +8 -2
  47. package/dist/src/platforms/slack/ensure-auth.d.ts.map +1 -1
  48. package/dist/src/platforms/slack/ensure-auth.js +67 -10
  49. package/dist/src/platforms/slack/ensure-auth.js.map +1 -1
  50. package/docs/content/docs/cli/kakaotalk.mdx +47 -2
  51. package/docs/content/docs/sdk/kakaotalk.mdx +32 -0
  52. package/package.json +1 -1
  53. package/skills/agent-channeltalk/SKILL.md +1 -1
  54. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  55. package/skills/agent-discord/SKILL.md +1 -1
  56. package/skills/agent-discordbot/SKILL.md +1 -1
  57. package/skills/agent-instagram/SKILL.md +1 -1
  58. package/skills/agent-kakaotalk/SKILL.md +62 -4
  59. package/skills/agent-kakaotalk/references/common-patterns.md +50 -11
  60. package/skills/agent-line/SKILL.md +1 -1
  61. package/skills/agent-slack/SKILL.md +1 -1
  62. package/skills/agent-slackbot/SKILL.md +1 -1
  63. package/skills/agent-teams/SKILL.md +1 -1
  64. package/skills/agent-telegram/SKILL.md +1 -1
  65. package/skills/agent-telegrambot/SKILL.md +1 -1
  66. package/skills/agent-webex/SKILL.md +1 -1
  67. package/skills/agent-wechatbot/SKILL.md +1 -1
  68. package/skills/agent-whatsapp/SKILL.md +1 -1
  69. package/skills/agent-whatsappbot/SKILL.md +1 -1
  70. package/src/platforms/kakaotalk/attachment-router.test.ts +102 -0
  71. package/src/platforms/kakaotalk/attachment-router.ts +50 -0
  72. package/src/platforms/kakaotalk/client.ts +315 -8
  73. package/src/platforms/kakaotalk/commands/message.ts +66 -0
  74. package/src/platforms/kakaotalk/image-meta.test.ts +90 -0
  75. package/src/platforms/kakaotalk/image-meta.ts +176 -0
  76. package/src/platforms/kakaotalk/index.ts +7 -0
  77. package/src/platforms/kakaotalk/media-upload.ts +44 -0
  78. package/src/platforms/kakaotalk/protocol/connection.ts +11 -0
  79. package/src/platforms/kakaotalk/protocol/media-uploader.ts +129 -0
  80. package/src/platforms/kakaotalk/protocol/session.ts +67 -0
  81. package/src/platforms/kakaotalk/types.ts +57 -0
  82. package/src/platforms/slack/commands/auth.ts +6 -4
  83. package/src/platforms/slack/ensure-auth.test.ts +223 -1
  84. package/src/platforms/slack/ensure-auth.ts +80 -11
  85. package/src/platforms/telegrambot/cli.ts +0 -0
@@ -21,20 +21,29 @@ export async function ensureSlackAuth(): Promise<void> {
21
21
  const workspaces = await extractor.extract()
22
22
  const workspaceDomains = extractor.getWorkspaceDomains()
23
23
 
24
- const validWorkspaces = []
24
+ const validWorkspaces: ExtractedWorkspace[] = []
25
+ const resolvedTeamIds = new Set<string>()
26
+ const refreshCache = new Map<string, RefreshResult | null>()
27
+
25
28
  for (const ws of workspaces) {
26
29
  try {
27
30
  const client = await new SlackClient().login({ token: ws.token, cookie: ws.cookie })
28
31
  const authInfo = await client.testAuth()
32
+ if (!authInfo.team_id) throw new Error('testAuth returned empty team_id')
29
33
  ws.workspace_id = authInfo.team_id
30
34
  ws.workspace_name = authInfo.team || ws.workspace_name
31
- await credManager.setWorkspace(ws)
32
- validWorkspaces.push(ws)
35
+ if (!resolvedTeamIds.has(ws.workspace_id)) {
36
+ resolvedTeamIds.add(ws.workspace_id)
37
+ await credManager.setWorkspace(ws)
38
+ validWorkspaces.push(ws)
39
+ }
33
40
  } catch {
34
- const refreshed = await tryWebTokenRefresh(ws, workspaceDomains)
35
- if (refreshed) {
41
+ const refreshed = await tryWebTokenRefresh(ws, workspaceDomains, { resolvedTeamIds, refreshCache })
42
+ if (refreshed && !resolvedTeamIds.has(refreshed.workspace_id)) {
36
43
  ws.token = refreshed.token
44
+ ws.workspace_id = refreshed.workspace_id
37
45
  ws.workspace_name = refreshed.workspace_name
46
+ resolvedTeamIds.add(ws.workspace_id)
38
47
  await credManager.setWorkspace(ws)
39
48
  validWorkspaces.push(ws)
40
49
  }
@@ -54,21 +63,81 @@ export async function ensureSlackAuth(): Promise<void> {
54
63
  }
55
64
  }
56
65
 
66
+ // Bound worst-case HTTP traffic for users with very large root-state.json workspace lists.
67
+ const MAX_DOMAIN_ATTEMPTS = 16
68
+
69
+ // Slack workspace subdomains match `^[a-z][a-z0-9-]*$` per signup rules; validating here
70
+ // prevents a tampered root-state.json from steering the cookie-bearing fetch to a non-Slack
71
+ // host (e.g. a domain value containing `.`, `/`, `:`, `@`, `#`, or `?`).
72
+ const SLACK_DOMAIN_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]*$/
73
+
74
+ export type RefreshResult = { token: string; workspace_id: string; workspace_name: string }
75
+
76
+ export type RefreshContext = {
77
+ resolvedTeamIds?: Set<string>
78
+ refreshCache?: Map<string, RefreshResult | null>
79
+ }
80
+
57
81
  export async function tryWebTokenRefresh(
58
82
  ws: ExtractedWorkspace,
59
83
  workspaceDomains: Record<string, string>,
60
- ): Promise<{ token: string; workspace_name: string } | null> {
84
+ context: RefreshContext = {},
85
+ ): Promise<RefreshResult | null> {
61
86
  if (!ws.cookie) return null
62
- const domain = workspaceDomains[ws.workspace_id]
63
- if (!domain) return null
64
87
 
88
+ // Try the domain that maps to this workspace_id first (when known), then fall back to
89
+ // every other known domain. Slack tokens extracted from LevelDB blobs sometimes carry
90
+ // workspace_id="unknown" because the regex window around the xoxc- bytes does not
91
+ // contain the T... team id; in that case the cookie may still be valid for one of the
92
+ // other workspaces the user is signed into.
93
+ const candidates = orderCandidateDomains(ws.workspace_id, workspaceDomains)
94
+ if (candidates.length === 0) return null
95
+
96
+ for (const { domain } of candidates) {
97
+ if (!SLACK_DOMAIN_REGEX.test(domain)) continue
98
+
99
+ const cacheKey = `${ws.cookie}\u0000${domain}`
100
+ const cached = context.refreshCache?.get(cacheKey)
101
+ let result: RefreshResult | null
102
+ if (cached !== undefined) {
103
+ result = cached
104
+ } else {
105
+ result = await refreshAndVerify(ws.cookie, domain, ws.workspace_name)
106
+ context.refreshCache?.set(cacheKey, result)
107
+ }
108
+ if (!result) continue
109
+ if (context.resolvedTeamIds?.has(result.workspace_id)) continue
110
+ return result
111
+ }
112
+ return null
113
+ }
114
+
115
+ function orderCandidateDomains(
116
+ workspaceId: string,
117
+ workspaceDomains: Record<string, string>,
118
+ ): Array<{ workspace_id: string; domain: string }> {
119
+ const entries = Object.entries(workspaceDomains).map(([workspace_id, domain]) => ({ workspace_id, domain }))
120
+ const exact = entries.findIndex((e) => e.workspace_id === workspaceId)
121
+ if (exact > 0) {
122
+ const [match] = entries.splice(exact, 1)
123
+ entries.unshift(match)
124
+ }
125
+ return entries.slice(0, MAX_DOMAIN_ATTEMPTS)
126
+ }
127
+
128
+ async function refreshAndVerify(cookie: string, domain: string, fallbackName: string): Promise<RefreshResult | null> {
65
129
  try {
66
- const freshToken = await refreshTokenFromWeb(domain, ws.cookie)
130
+ const freshToken = await refreshTokenFromWeb(domain, cookie)
67
131
  if (!freshToken) return null
68
132
 
69
- const client = await new SlackClient().login({ token: freshToken, cookie: ws.cookie })
133
+ const client = await new SlackClient().login({ token: freshToken, cookie })
70
134
  const authInfo = await client.testAuth()
71
- return { token: freshToken, workspace_name: authInfo.team || ws.workspace_name }
135
+ if (!authInfo.team_id) return null
136
+ return {
137
+ token: freshToken,
138
+ workspace_id: authInfo.team_id,
139
+ workspace_name: authInfo.team || fallbackName,
140
+ }
72
141
  } catch {
73
142
  return null
74
143
  }
File without changes