agent-messenger 2.8.0 → 2.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +0 -11
- package/dist/package.json +1 -1
- package/dist/src/platforms/channeltalk/commands/snapshot.d.ts +4 -2
- package/dist/src/platforms/channeltalk/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/commands/snapshot.js +86 -31
- package/dist/src/platforms/channeltalk/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/snapshot.d.ts +3 -1
- package/dist/src/platforms/channeltalkbot/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/snapshot.js +110 -60
- package/dist/src/platforms/channeltalkbot/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/discord/commands/snapshot.d.ts +1 -0
- package/dist/src/platforms/discord/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/snapshot.js +48 -34
- package/dist/src/platforms/discord/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/snapshot.d.ts +2 -0
- package/dist/src/platforms/discordbot/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/snapshot.js +46 -34
- package/dist/src/platforms/discordbot/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/slack/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/snapshot.js +75 -55
- package/dist/src/platforms/slack/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/teams/client.d.ts +9 -1
- package/dist/src/platforms/teams/client.d.ts.map +1 -1
- package/dist/src/platforms/teams/client.js +69 -18
- package/dist/src/platforms/teams/client.js.map +1 -1
- package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/auth.js +7 -2
- package/dist/src/platforms/teams/commands/auth.js.map +1 -1
- package/dist/src/platforms/teams/commands/channel.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/channel.js +18 -3
- package/dist/src/platforms/teams/commands/channel.js.map +1 -1
- package/dist/src/platforms/teams/commands/file.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/file.js +18 -3
- package/dist/src/platforms/teams/commands/file.js.map +1 -1
- package/dist/src/platforms/teams/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/message.js +24 -4
- package/dist/src/platforms/teams/commands/message.js.map +1 -1
- package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/reaction.js +12 -2
- package/dist/src/platforms/teams/commands/reaction.js.map +1 -1
- package/dist/src/platforms/teams/commands/snapshot.d.ts +1 -0
- package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/snapshot.js +50 -32
- package/dist/src/platforms/teams/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/teams/commands/team.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/team.js +6 -1
- package/dist/src/platforms/teams/commands/team.js.map +1 -1
- package/dist/src/platforms/teams/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/user.js +18 -3
- package/dist/src/platforms/teams/commands/user.js.map +1 -1
- package/dist/src/platforms/teams/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/whoami.js +6 -1
- package/dist/src/platforms/teams/commands/whoami.js.map +1 -1
- package/dist/src/platforms/teams/credential-manager.d.ts +3 -1
- package/dist/src/platforms/teams/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/teams/credential-manager.js +6 -1
- package/dist/src/platforms/teams/credential-manager.js.map +1 -1
- package/dist/src/platforms/teams/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/teams/ensure-auth.js +7 -2
- package/dist/src/platforms/teams/ensure-auth.js.map +1 -1
- package/dist/src/platforms/teams/token-extractor.d.ts +3 -1
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +67 -10
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/dist/src/platforms/teams/types.d.ts +17 -0
- package/dist/src/platforms/teams/types.d.ts.map +1 -1
- package/dist/src/platforms/teams/types.js +2 -0
- package/dist/src/platforms/teams/types.js.map +1 -1
- package/dist/src/platforms/webex/client.d.ts +3 -0
- package/dist/src/platforms/webex/client.d.ts.map +1 -1
- package/dist/src/platforms/webex/client.js +58 -13
- package/dist/src/platforms/webex/client.js.map +1 -1
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/auth.js +61 -10
- package/dist/src/platforms/webex/commands/auth.js.map +1 -1
- package/dist/src/platforms/webex/commands/snapshot.d.ts +1 -0
- package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/snapshot.js +14 -7
- package/dist/src/platforms/webex/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/webex/credential-manager.js +18 -6
- package/dist/src/platforms/webex/credential-manager.js.map +1 -1
- package/dist/src/platforms/webex/encryption.d.ts.map +1 -1
- package/dist/src/platforms/webex/encryption.js +3 -1
- package/dist/src/platforms/webex/encryption.js.map +1 -1
- package/dist/src/platforms/webex/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/ensure-auth.js +10 -2
- package/dist/src/platforms/webex/ensure-auth.js.map +1 -1
- package/dist/src/platforms/webex/token-extractor.d.ts +1 -0
- package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/webex/token-extractor.js +21 -4
- package/dist/src/platforms/webex/token-extractor.js.map +1 -1
- package/docs/content/docs/agent-skills.mdx +0 -10
- package/docs/content/docs/cli/channeltalk.mdx +18 -8
- package/docs/content/docs/cli/channeltalkbot.mdx +16 -6
- package/docs/content/docs/cli/discord.mdx +23 -7
- package/docs/content/docs/cli/discordbot.mdx +23 -7
- package/docs/content/docs/cli/slack.mdx +24 -7
- package/docs/content/docs/cli/teams.mdx +24 -8
- package/docs/content/docs/cli/webex.mdx +15 -2
- package/e2e/webex.e2e.test.ts +57 -0
- package/package.json +1 -1
- package/skills/agent-channeltalk/SKILL.md +19 -9
- package/skills/agent-channeltalk/references/common-patterns.md +10 -9
- package/skills/agent-channeltalkbot/SKILL.md +19 -9
- package/skills/agent-channeltalkbot/references/common-patterns.md +10 -9
- package/skills/agent-discord/SKILL.md +18 -9
- package/skills/agent-discord/references/common-patterns.md +8 -7
- package/skills/agent-discordbot/SKILL.md +18 -9
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +19 -10
- package/skills/agent-slack/references/common-patterns.md +4 -7
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +18 -9
- package/skills/agent-teams/references/common-patterns.md +9 -7
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +13 -4
- package/skills/agent-webex/references/common-patterns.md +8 -2
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/channeltalk/commands/snapshot.test.ts +58 -26
- package/src/platforms/channeltalk/commands/snapshot.ts +107 -33
- package/src/platforms/channeltalkbot/commands/snapshot.test.ts +26 -8
- package/src/platforms/channeltalkbot/commands/snapshot.ts +131 -64
- package/src/platforms/discord/commands/snapshot.test.ts +1 -1
- package/src/platforms/discord/commands/snapshot.ts +58 -42
- package/src/platforms/discordbot/commands/snapshot.test.ts +40 -18
- package/src/platforms/discordbot/commands/snapshot.ts +54 -37
- package/src/platforms/slack/commands/snapshot.test.ts +63 -8
- package/src/platforms/slack/commands/snapshot.ts +98 -66
- package/src/platforms/teams/client.test.ts +34 -30
- package/src/platforms/teams/client.ts +92 -20
- package/src/platforms/teams/commands/auth.test.ts +6 -2
- package/src/platforms/teams/commands/auth.ts +7 -2
- package/src/platforms/teams/commands/channel.test.ts +6 -6
- package/src/platforms/teams/commands/channel.ts +18 -3
- package/src/platforms/teams/commands/file.ts +18 -3
- package/src/platforms/teams/commands/message.ts +24 -4
- package/src/platforms/teams/commands/reaction.ts +12 -2
- package/src/platforms/teams/commands/snapshot.test.ts +1 -1
- package/src/platforms/teams/commands/snapshot.ts +59 -39
- package/src/platforms/teams/commands/team.test.ts +2 -2
- package/src/platforms/teams/commands/team.ts +6 -1
- package/src/platforms/teams/commands/user.ts +18 -3
- package/src/platforms/teams/commands/whoami.ts +6 -1
- package/src/platforms/teams/credential-manager.test.ts +25 -0
- package/src/platforms/teams/credential-manager.ts +13 -3
- package/src/platforms/teams/ensure-auth.test.ts +6 -1
- package/src/platforms/teams/ensure-auth.ts +7 -2
- package/src/platforms/teams/token-extractor.ts +77 -12
- package/src/platforms/teams/types.test.ts +17 -0
- package/src/platforms/teams/types.ts +6 -0
- package/src/platforms/webex/client.test.ts +157 -13
- package/src/platforms/webex/client.ts +64 -15
- package/src/platforms/webex/commands/auth.test.ts +122 -1
- package/src/platforms/webex/commands/auth.ts +72 -17
- package/src/platforms/webex/commands/snapshot.test.ts +14 -1
- package/src/platforms/webex/commands/snapshot.ts +17 -9
- package/src/platforms/webex/credential-manager.test.ts +63 -0
- package/src/platforms/webex/credential-manager.ts +22 -8
- package/src/platforms/webex/encryption.test.ts +54 -0
- package/src/platforms/webex/encryption.ts +3 -1
- package/src/platforms/webex/ensure-auth.ts +10 -2
- package/src/platforms/webex/token-extractor.test.ts +32 -3
- package/src/platforms/webex/token-extractor.ts +26 -5
|
@@ -81,9 +81,54 @@ describe('snapshot command', () => {
|
|
|
81
81
|
mockListUserChats.mockClear()
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
test('returns workspace,
|
|
84
|
+
test('brief snapshot returns workspace, groups (name only), chat counts, and hint', async () => {
|
|
85
85
|
const result = await snapshotAction()
|
|
86
86
|
|
|
87
|
+
expect(result.error).toBeUndefined()
|
|
88
|
+
expect(result.workspace).toEqual({ id: 'ws-1', name: 'Workspace One' })
|
|
89
|
+
expect(result.groups).toEqual([
|
|
90
|
+
{ id: 'grp-1', name: 'Support' },
|
|
91
|
+
{ id: 'grp-2', name: 'Sales' },
|
|
92
|
+
])
|
|
93
|
+
expect(result.user_chats).toEqual({
|
|
94
|
+
total: 4,
|
|
95
|
+
by_state: { opened: 2, snoozed: 1, closed: 1 },
|
|
96
|
+
})
|
|
97
|
+
expect(result.hint).toBeDefined()
|
|
98
|
+
expect(result.managers).toBeUndefined()
|
|
99
|
+
expect(result.bots).toBeUndefined()
|
|
100
|
+
expect(mockGetGroupMessages).not.toHaveBeenCalled()
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
test('brief groups-only returns group names without messages', async () => {
|
|
104
|
+
const result = await snapshotAction({ groupsOnly: true })
|
|
105
|
+
|
|
106
|
+
expect(result.workspace).toEqual({ id: 'ws-1', name: 'Workspace One' })
|
|
107
|
+
expect(result.groups).toHaveLength(2)
|
|
108
|
+
expect(result.groups?.[0]).toEqual({ id: 'grp-1', name: 'Support' })
|
|
109
|
+
expect(result.hint).toBeDefined()
|
|
110
|
+
expect(result.user_chats).toBeUndefined()
|
|
111
|
+
expect(mockGetGroupMessages).not.toHaveBeenCalled()
|
|
112
|
+
expect(mockListUserChats).not.toHaveBeenCalled()
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
test('brief chats-only returns counts without recent details', async () => {
|
|
116
|
+
const result = await snapshotAction({ chatsOnly: true })
|
|
117
|
+
|
|
118
|
+
expect(result.workspace).toEqual({ id: 'ws-1', name: 'Workspace One' })
|
|
119
|
+
expect(result.groups).toBeUndefined()
|
|
120
|
+
expect(result.user_chats).toEqual({
|
|
121
|
+
total: 4,
|
|
122
|
+
by_state: { opened: 2, snoozed: 1, closed: 1 },
|
|
123
|
+
})
|
|
124
|
+
expect(result.hint).toBeDefined()
|
|
125
|
+
expect(mockListGroups).not.toHaveBeenCalled()
|
|
126
|
+
expect(mockGetGroupMessages).not.toHaveBeenCalled()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test('full snapshot returns workspace, managers, bots, groups, and user chats', async () => {
|
|
130
|
+
const result = await snapshotAction({ full: true })
|
|
131
|
+
|
|
87
132
|
expect(result.error).toBeUndefined()
|
|
88
133
|
expect(result).toEqual({
|
|
89
134
|
workspace: { id: 'ws-1', name: 'Workspace One' },
|
|
@@ -156,19 +201,21 @@ describe('snapshot command', () => {
|
|
|
156
201
|
})
|
|
157
202
|
})
|
|
158
203
|
|
|
159
|
-
test('groups-only
|
|
160
|
-
const result = await snapshotAction({ groupsOnly: true })
|
|
204
|
+
test('full groups-only includes messages', async () => {
|
|
205
|
+
const result = await snapshotAction({ full: true, groupsOnly: true, limit: 3 })
|
|
161
206
|
|
|
162
|
-
expect(
|
|
163
|
-
expect(
|
|
164
|
-
expect(result.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
207
|
+
expect(mockGetGroupMessages).toHaveBeenCalledWith('ws-1', 'grp-1', { limit: 3, sortOrder: 'desc' })
|
|
208
|
+
expect(mockGetGroupMessages).toHaveBeenCalledWith('ws-1', 'grp-2', { limit: 3, sortOrder: 'desc' })
|
|
209
|
+
expect(result.groups?.[0].recent_messages?.[0]).toEqual({
|
|
210
|
+
id: 'grp-1-msg-1',
|
|
211
|
+
person_type: 'manager',
|
|
212
|
+
plain_text: 'Message for grp-1',
|
|
213
|
+
created_at: 1000,
|
|
214
|
+
})
|
|
168
215
|
})
|
|
169
216
|
|
|
170
|
-
test('chats-only
|
|
171
|
-
const result = await snapshotAction({ chatsOnly: true, limit: 1 })
|
|
217
|
+
test('full chats-only includes recent details', async () => {
|
|
218
|
+
const result = await snapshotAction({ full: true, chatsOnly: true, limit: 1 })
|
|
172
219
|
|
|
173
220
|
expect(result.workspace).toEqual({ id: 'ws-1', name: 'Workspace One' })
|
|
174
221
|
expect(result.groups).toBeUndefined()
|
|
@@ -189,20 +236,5 @@ describe('snapshot command', () => {
|
|
|
189
236
|
},
|
|
190
237
|
],
|
|
191
238
|
})
|
|
192
|
-
expect(mockListGroups).not.toHaveBeenCalled()
|
|
193
|
-
expect(mockGetGroupMessages).not.toHaveBeenCalled()
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
test('includes recent messages for each group with requested limit', async () => {
|
|
197
|
-
const result = await snapshotAction({ groupsOnly: true, limit: 3 })
|
|
198
|
-
|
|
199
|
-
expect(mockGetGroupMessages).toHaveBeenCalledWith('ws-1', 'grp-1', { limit: 3, sortOrder: 'desc' })
|
|
200
|
-
expect(mockGetGroupMessages).toHaveBeenCalledWith('ws-1', 'grp-2', { limit: 3, sortOrder: 'desc' })
|
|
201
|
-
expect(result.groups?.[0].recent_messages[0]).toEqual({
|
|
202
|
-
id: 'grp-1-msg-1',
|
|
203
|
-
person_type: 'manager',
|
|
204
|
-
plain_text: 'Message for grp-1',
|
|
205
|
-
created_at: 1000,
|
|
206
|
-
})
|
|
207
239
|
})
|
|
208
240
|
})
|
|
@@ -10,6 +10,7 @@ interface SnapshotOptions {
|
|
|
10
10
|
pretty?: boolean
|
|
11
11
|
groupsOnly?: boolean
|
|
12
12
|
chatsOnly?: boolean
|
|
13
|
+
full?: boolean
|
|
13
14
|
limit?: number | string
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -33,7 +34,7 @@ interface SnapshotResult {
|
|
|
33
34
|
groups?: Array<{
|
|
34
35
|
id: string
|
|
35
36
|
name: string
|
|
36
|
-
recent_messages
|
|
37
|
+
recent_messages?: Array<{
|
|
37
38
|
id: string
|
|
38
39
|
person_type?: string
|
|
39
40
|
plain_text?: string
|
|
@@ -43,7 +44,7 @@ interface SnapshotResult {
|
|
|
43
44
|
user_chats?: {
|
|
44
45
|
total: number
|
|
45
46
|
by_state: Record<string, number>
|
|
46
|
-
recent
|
|
47
|
+
recent?: Array<{
|
|
47
48
|
id: string
|
|
48
49
|
state?: string
|
|
49
50
|
assignee_id?: string
|
|
@@ -51,6 +52,7 @@ interface SnapshotResult {
|
|
|
51
52
|
updated_at?: number
|
|
52
53
|
}>
|
|
53
54
|
}
|
|
55
|
+
hint?: string
|
|
54
56
|
error?: string
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -58,7 +60,6 @@ export async function snapshotAction(options: SnapshotOptions = {}): Promise<Sna
|
|
|
58
60
|
try {
|
|
59
61
|
const client = await getClient(options)
|
|
60
62
|
const workspaceId = await getCurrentWorkspaceId(options)
|
|
61
|
-
const limit = parseLimit(options.limit)
|
|
62
63
|
|
|
63
64
|
const channel = await client.getChannel(workspaceId)
|
|
64
65
|
const workspace = {
|
|
@@ -66,42 +67,114 @@ export async function snapshotAction(options: SnapshotOptions = {}): Promise<Sna
|
|
|
66
67
|
name: channel.name,
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
if (options.
|
|
70
|
-
|
|
71
|
-
return { workspace, groups }
|
|
70
|
+
if (options.full) {
|
|
71
|
+
return buildFullSnapshot(client, workspaceId, workspace, options)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
return buildBriefSnapshot(client, workspaceId, workspace, options)
|
|
75
|
+
} catch (error) {
|
|
76
|
+
return { error: (error as Error).message }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function buildBriefSnapshot(
|
|
81
|
+
client: Awaited<ReturnType<typeof getClient>>,
|
|
82
|
+
workspaceId: string,
|
|
83
|
+
workspace: { id: string; name: string },
|
|
84
|
+
options: SnapshotOptions,
|
|
85
|
+
): Promise<SnapshotResult> {
|
|
86
|
+
if (options.groupsOnly) {
|
|
87
|
+
const groups = await client.listGroups(workspaceId, { limit: 20 })
|
|
88
|
+
return {
|
|
89
|
+
workspace,
|
|
90
|
+
groups: groups.map((g) => ({ id: g.id, name: g.name })),
|
|
91
|
+
hint: "Use 'group messages <group>' for messages.",
|
|
77
92
|
}
|
|
93
|
+
}
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
client.
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
if (options.chatsOnly) {
|
|
96
|
+
const [openedChats, snoozedChats, closedChats] = await Promise.all([
|
|
97
|
+
client.listUserChats(workspaceId, { state: 'opened', limit: 100 }),
|
|
98
|
+
client.listUserChats(workspaceId, { state: 'snoozed', limit: 100 }),
|
|
99
|
+
client.listUserChats(workspaceId, { state: 'closed', limit: 100 }),
|
|
84
100
|
])
|
|
85
|
-
|
|
86
101
|
return {
|
|
87
102
|
workspace,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
name: bot.name,
|
|
98
|
-
avatar_url: bot.avatarUrl,
|
|
99
|
-
})),
|
|
100
|
-
groups,
|
|
101
|
-
user_chats: userChats,
|
|
103
|
+
user_chats: {
|
|
104
|
+
total: openedChats.length + snoozedChats.length + closedChats.length,
|
|
105
|
+
by_state: {
|
|
106
|
+
opened: openedChats.length,
|
|
107
|
+
snoozed: snoozedChats.length,
|
|
108
|
+
closed: closedChats.length,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
hint: "Use 'chat list --state opened' for chat details, 'chat messages <chat>' for messages.",
|
|
102
112
|
}
|
|
103
|
-
}
|
|
104
|
-
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const [groups, openedChats, snoozedChats, closedChats] = await Promise.all([
|
|
116
|
+
client.listGroups(workspaceId, { limit: 20 }),
|
|
117
|
+
client.listUserChats(workspaceId, { state: 'opened', limit: 100 }),
|
|
118
|
+
client.listUserChats(workspaceId, { state: 'snoozed', limit: 100 }),
|
|
119
|
+
client.listUserChats(workspaceId, { state: 'closed', limit: 100 }),
|
|
120
|
+
])
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
workspace,
|
|
124
|
+
groups: groups.map((g) => ({ id: g.id, name: g.name })),
|
|
125
|
+
user_chats: {
|
|
126
|
+
total: openedChats.length + snoozedChats.length + closedChats.length,
|
|
127
|
+
by_state: {
|
|
128
|
+
opened: openedChats.length,
|
|
129
|
+
snoozed: snoozedChats.length,
|
|
130
|
+
closed: closedChats.length,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
hint: "Use 'group messages <group>' for group messages, 'chat list --state opened' for chats, 'manager list' for managers.",
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function buildFullSnapshot(
|
|
138
|
+
client: Awaited<ReturnType<typeof getClient>>,
|
|
139
|
+
workspaceId: string,
|
|
140
|
+
workspace: { id: string; name: string },
|
|
141
|
+
options: SnapshotOptions,
|
|
142
|
+
): Promise<SnapshotResult> {
|
|
143
|
+
const limit = parseLimit(options.limit)
|
|
144
|
+
|
|
145
|
+
if (options.groupsOnly) {
|
|
146
|
+
const groups = await buildGroupsSnapshot(client, workspaceId, limit)
|
|
147
|
+
return { workspace, groups }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (options.chatsOnly) {
|
|
151
|
+
const userChats = await buildUserChatsSnapshot(client, workspaceId, limit)
|
|
152
|
+
return { workspace, user_chats: userChats }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const [managers, bots, groups, userChats] = await Promise.all([
|
|
156
|
+
client.listManagers(workspaceId, { limit: 50 }),
|
|
157
|
+
client.listBots(workspaceId, { limit: 50 }),
|
|
158
|
+
buildGroupsSnapshot(client, workspaceId, limit),
|
|
159
|
+
buildUserChatsSnapshot(client, workspaceId, limit),
|
|
160
|
+
])
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
workspace,
|
|
164
|
+
managers: managers.map((manager) => ({
|
|
165
|
+
id: manager.id,
|
|
166
|
+
name: manager.name,
|
|
167
|
+
email: manager.email,
|
|
168
|
+
account_id: manager.accountId,
|
|
169
|
+
role_id: manager.roleId,
|
|
170
|
+
})),
|
|
171
|
+
bots: bots.map((bot) => ({
|
|
172
|
+
id: bot.id,
|
|
173
|
+
name: bot.name,
|
|
174
|
+
avatar_url: bot.avatarUrl,
|
|
175
|
+
})),
|
|
176
|
+
groups,
|
|
177
|
+
user_chats: userChats,
|
|
105
178
|
}
|
|
106
179
|
}
|
|
107
180
|
|
|
@@ -178,10 +251,11 @@ function cliOutput(result: SnapshotResult, pretty?: boolean): void {
|
|
|
178
251
|
|
|
179
252
|
export function createSnapshotCommand(): Command {
|
|
180
253
|
return new Command('snapshot')
|
|
181
|
-
.description('Workspace overview for AI
|
|
254
|
+
.description('Workspace overview for AI agents (brief by default, use --full for comprehensive data)')
|
|
255
|
+
.option('--full', 'Include messages, managers, and bots (verbose)')
|
|
182
256
|
.option('--groups-only', 'List groups only, skip user chats')
|
|
183
257
|
.option('--chats-only', 'List user chats only, skip groups')
|
|
184
|
-
.option('--limit <n>', 'Messages per group and recent opened chats', '5')
|
|
258
|
+
.option('--limit <n>', 'Messages per group and recent opened chats with --full', '5')
|
|
185
259
|
.option('--workspace <id>', 'Workspace ID')
|
|
186
260
|
.option('--pretty', 'Pretty print JSON output')
|
|
187
261
|
.action(async (options: SnapshotOptions) => {
|
|
@@ -67,10 +67,28 @@ describe('snapshot command', () => {
|
|
|
67
67
|
})
|
|
68
68
|
|
|
69
69
|
describe('snapshotAction', () => {
|
|
70
|
-
test('returns workspace, groups
|
|
70
|
+
test('brief snapshot returns workspace, groups (names), chat counts, and hint', async () => {
|
|
71
71
|
const manager = new ChannelBotCredentialManager(tempDir)
|
|
72
72
|
const result = await snapshotAction({ _credManager: manager })
|
|
73
73
|
|
|
74
|
+
expect(result.error).toBeUndefined()
|
|
75
|
+
expect(result.workspace).toBeDefined()
|
|
76
|
+
expect(result.workspace?.id).toBe('ch1')
|
|
77
|
+
expect(result.workspace?.name).toBe('Test Workspace')
|
|
78
|
+
expect(result.groups).toBeDefined()
|
|
79
|
+
expect(result.groups?.[0]).toEqual({ id: 'grp1', name: 'Team Alpha' })
|
|
80
|
+
expect(result.user_chats).toBeDefined()
|
|
81
|
+
expect(result.user_chats?.opened_count).toBe(1)
|
|
82
|
+
expect(result.hint).toBeDefined()
|
|
83
|
+
expect(result.managers).toBeUndefined()
|
|
84
|
+
expect(result.bots).toBeUndefined()
|
|
85
|
+
expect(mockGetGroupMessages).not.toHaveBeenCalled()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
test('full snapshot returns workspace, groups, user_chats, managers, bots', async () => {
|
|
89
|
+
const manager = new ChannelBotCredentialManager(tempDir)
|
|
90
|
+
const result = await snapshotAction({ full: true, _credManager: manager })
|
|
91
|
+
|
|
74
92
|
expect(result.error).toBeUndefined()
|
|
75
93
|
expect(result.workspace).toBeDefined()
|
|
76
94
|
expect(result.workspace?.id).toBe('ch1')
|
|
@@ -83,7 +101,7 @@ describe('snapshot command', () => {
|
|
|
83
101
|
|
|
84
102
|
test('groups-only flag skips user_chats, managers, bots', async () => {
|
|
85
103
|
const manager = new ChannelBotCredentialManager(tempDir)
|
|
86
|
-
const result = await snapshotAction({ groupsOnly: true, _credManager: manager })
|
|
104
|
+
const result = await snapshotAction({ full: true, groupsOnly: true, _credManager: manager })
|
|
87
105
|
|
|
88
106
|
expect(result.error).toBeUndefined()
|
|
89
107
|
expect(result.workspace).toBeDefined()
|
|
@@ -95,7 +113,7 @@ describe('snapshot command', () => {
|
|
|
95
113
|
|
|
96
114
|
test('chats-only flag skips groups, managers, bots', async () => {
|
|
97
115
|
const manager = new ChannelBotCredentialManager(tempDir)
|
|
98
|
-
const result = await snapshotAction({ chatsOnly: true, _credManager: manager })
|
|
116
|
+
const result = await snapshotAction({ full: true, chatsOnly: true, _credManager: manager })
|
|
99
117
|
|
|
100
118
|
expect(result.error).toBeUndefined()
|
|
101
119
|
expect(result.workspace).toBeDefined()
|
|
@@ -105,21 +123,21 @@ describe('snapshot command', () => {
|
|
|
105
123
|
expect(result.bots).toBeUndefined()
|
|
106
124
|
})
|
|
107
125
|
|
|
108
|
-
test('groups include recent messages', async () => {
|
|
126
|
+
test('full groups include recent messages', async () => {
|
|
109
127
|
const manager = new ChannelBotCredentialManager(tempDir)
|
|
110
|
-
const result = await snapshotAction({ groupsOnly: true, limit: 3, _credManager: manager })
|
|
128
|
+
const result = await snapshotAction({ full: true, groupsOnly: true, limit: 3, _credManager: manager })
|
|
111
129
|
|
|
112
130
|
expect(result.groups?.[0].messages).toBeDefined()
|
|
113
131
|
expect(result.groups?.[0].messages?.[0].id).toBe('msg1')
|
|
114
132
|
})
|
|
115
133
|
|
|
116
|
-
test('user_chats includes counts and recent opened', async () => {
|
|
134
|
+
test('full user_chats includes counts and recent opened', async () => {
|
|
117
135
|
const manager = new ChannelBotCredentialManager(tempDir)
|
|
118
|
-
const result = await snapshotAction({ chatsOnly: true, _credManager: manager })
|
|
136
|
+
const result = await snapshotAction({ full: true, chatsOnly: true, _credManager: manager })
|
|
119
137
|
|
|
120
138
|
expect(result.user_chats?.opened_count).toBe(1)
|
|
121
139
|
expect(result.user_chats?.recent_opened).toHaveLength(1)
|
|
122
|
-
expect(result.user_chats?.recent_opened[0].id).toBe('chat1')
|
|
140
|
+
expect(result.user_chats?.recent_opened?.[0].id).toBe('chat1')
|
|
123
141
|
})
|
|
124
142
|
})
|
|
125
143
|
})
|
|
@@ -9,6 +9,7 @@ import { getClient } from './shared'
|
|
|
9
9
|
interface SnapshotOption extends WorkspaceOption {
|
|
10
10
|
groupsOnly?: boolean
|
|
11
11
|
chatsOnly?: boolean
|
|
12
|
+
full?: boolean
|
|
12
13
|
limit?: number
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -33,7 +34,7 @@ interface SnapshotResult {
|
|
|
33
34
|
opened_count: number
|
|
34
35
|
snoozed_count: number
|
|
35
36
|
closed_count: number
|
|
36
|
-
recent_opened
|
|
37
|
+
recent_opened?: Array<{
|
|
37
38
|
id: string
|
|
38
39
|
name?: string
|
|
39
40
|
user_id?: string
|
|
@@ -46,13 +47,13 @@ interface SnapshotResult {
|
|
|
46
47
|
}
|
|
47
48
|
managers?: Array<{ id: string; name: string; description?: string }>
|
|
48
49
|
bots?: Array<{ id: string; name: string }>
|
|
50
|
+
hint?: string
|
|
49
51
|
error?: string
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
export async function snapshotAction(options: SnapshotOption): Promise<SnapshotResult> {
|
|
53
55
|
try {
|
|
54
56
|
const client = await getClient(options)
|
|
55
|
-
const limit = options.limit ?? 5
|
|
56
57
|
|
|
57
58
|
const channel = await client.getChannel()
|
|
58
59
|
const workspace = {
|
|
@@ -62,71 +63,75 @@ export async function snapshotAction(options: SnapshotOption): Promise<SnapshotR
|
|
|
62
63
|
description: channel.description,
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
if (options.
|
|
66
|
-
|
|
67
|
-
const groupsWithMessages = await Promise.all(
|
|
68
|
-
groups.map(async (g) => {
|
|
69
|
-
const messages = await client.getGroupMessages(g.id, { limit, sortOrder: 'desc' })
|
|
70
|
-
return {
|
|
71
|
-
id: g.id,
|
|
72
|
-
name: g.name,
|
|
73
|
-
messages: messages.map((m) => ({
|
|
74
|
-
id: m.id,
|
|
75
|
-
person_type: m.personType,
|
|
76
|
-
plain_text: m.plainText,
|
|
77
|
-
created_at: m.createdAt,
|
|
78
|
-
})),
|
|
79
|
-
}
|
|
80
|
-
}),
|
|
81
|
-
)
|
|
82
|
-
return { workspace, groups: groupsWithMessages }
|
|
66
|
+
if (options.full) {
|
|
67
|
+
return buildFullSnapshot(client, workspace, options)
|
|
83
68
|
}
|
|
84
69
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
])
|
|
91
|
-
|
|
92
|
-
const recentOpened = await Promise.all(
|
|
93
|
-
openedChats.slice(0, 5).map(async (chat) => {
|
|
94
|
-
const messages = await client.getUserChatMessages(chat.id, { limit: 1, sortOrder: 'desc' })
|
|
95
|
-
return {
|
|
96
|
-
id: chat.id,
|
|
97
|
-
name: chat.name,
|
|
98
|
-
user_id: chat.userId,
|
|
99
|
-
last_message: messages[0]
|
|
100
|
-
? {
|
|
101
|
-
id: messages[0].id,
|
|
102
|
-
plain_text: messages[0].plainText,
|
|
103
|
-
created_at: messages[0].createdAt,
|
|
104
|
-
}
|
|
105
|
-
: undefined,
|
|
106
|
-
}
|
|
107
|
-
}),
|
|
108
|
-
)
|
|
70
|
+
return buildBriefSnapshot(client, workspace, options)
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return { error: (error as Error).message }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
109
75
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
76
|
+
async function buildBriefSnapshot(
|
|
77
|
+
client: Awaited<ReturnType<typeof getClient>>,
|
|
78
|
+
workspace: SnapshotResult['workspace'],
|
|
79
|
+
options: SnapshotOption,
|
|
80
|
+
): Promise<SnapshotResult> {
|
|
81
|
+
if (options.groupsOnly) {
|
|
82
|
+
const groups = await client.listGroups({ limit: 20 })
|
|
83
|
+
return {
|
|
84
|
+
workspace,
|
|
85
|
+
groups: groups.map((g) => ({ id: g.id, name: g.name })),
|
|
86
|
+
hint: "Use 'group messages <group>' for messages.",
|
|
119
87
|
}
|
|
88
|
+
}
|
|
120
89
|
|
|
121
|
-
|
|
122
|
-
|
|
90
|
+
if (options.chatsOnly) {
|
|
91
|
+
const [openedChats, snoozedChats, closedChats] = await Promise.all([
|
|
123
92
|
client.listUserChats({ state: 'opened', limit: 10, sortOrder: 'desc' }),
|
|
124
93
|
client.listUserChats({ state: 'snoozed', limit: 1 }),
|
|
125
94
|
client.listUserChats({ state: 'closed', limit: 1 }),
|
|
126
|
-
client.listManagers({ limit: 50 }),
|
|
127
|
-
client.listBots({ limit: 50 }),
|
|
128
95
|
])
|
|
96
|
+
return {
|
|
97
|
+
workspace,
|
|
98
|
+
user_chats: {
|
|
99
|
+
opened_count: openedChats.length,
|
|
100
|
+
snoozed_count: snoozedChats.length,
|
|
101
|
+
closed_count: closedChats.length,
|
|
102
|
+
},
|
|
103
|
+
hint: "Use 'chat list --state opened' for chat details, 'chat messages <chat>' for messages.",
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const [groups, openedChats, snoozedChats, closedChats] = await Promise.all([
|
|
108
|
+
client.listGroups({ limit: 20 }),
|
|
109
|
+
client.listUserChats({ state: 'opened', limit: 10, sortOrder: 'desc' }),
|
|
110
|
+
client.listUserChats({ state: 'snoozed', limit: 1 }),
|
|
111
|
+
client.listUserChats({ state: 'closed', limit: 1 }),
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
workspace,
|
|
116
|
+
groups: groups.map((g) => ({ id: g.id, name: g.name })),
|
|
117
|
+
user_chats: {
|
|
118
|
+
opened_count: openedChats.length,
|
|
119
|
+
snoozed_count: snoozedChats.length,
|
|
120
|
+
closed_count: closedChats.length,
|
|
121
|
+
},
|
|
122
|
+
hint: "Use 'group messages <group>' for group messages, 'chat list --state opened' for chats, 'manager list' for managers.",
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function buildFullSnapshot(
|
|
127
|
+
client: Awaited<ReturnType<typeof getClient>>,
|
|
128
|
+
workspace: SnapshotResult['workspace'],
|
|
129
|
+
options: SnapshotOption,
|
|
130
|
+
): Promise<SnapshotResult> {
|
|
131
|
+
const limit = options.limit ?? 5
|
|
129
132
|
|
|
133
|
+
if (options.groupsOnly) {
|
|
134
|
+
const groups = await client.listGroups({ limit: 20 })
|
|
130
135
|
const groupsWithMessages = await Promise.all(
|
|
131
136
|
groups.map(async (g) => {
|
|
132
137
|
const messages = await client.getGroupMessages(g.id, { limit, sortOrder: 'desc' })
|
|
@@ -142,6 +147,15 @@ export async function snapshotAction(options: SnapshotOption): Promise<SnapshotR
|
|
|
142
147
|
}
|
|
143
148
|
}),
|
|
144
149
|
)
|
|
150
|
+
return { workspace, groups: groupsWithMessages }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (options.chatsOnly) {
|
|
154
|
+
const [openedChats, snoozedChats, closedChats] = await Promise.all([
|
|
155
|
+
client.listUserChats({ state: 'opened', limit: 10, sortOrder: 'desc' }),
|
|
156
|
+
client.listUserChats({ state: 'snoozed', limit: 1 }),
|
|
157
|
+
client.listUserChats({ state: 'closed', limit: 1 }),
|
|
158
|
+
])
|
|
145
159
|
|
|
146
160
|
const recentOpened = await Promise.all(
|
|
147
161
|
openedChats.slice(0, 5).map(async (chat) => {
|
|
@@ -163,26 +177,78 @@ export async function snapshotAction(options: SnapshotOption): Promise<SnapshotR
|
|
|
163
177
|
|
|
164
178
|
return {
|
|
165
179
|
workspace,
|
|
166
|
-
groups: groupsWithMessages,
|
|
167
180
|
user_chats: {
|
|
168
181
|
opened_count: openedChats.length,
|
|
169
182
|
snoozed_count: snoozedChats.length,
|
|
170
183
|
closed_count: closedChats.length,
|
|
171
184
|
recent_opened: recentOpened,
|
|
172
185
|
},
|
|
173
|
-
managers: managers.map((m) => ({ id: m.id, name: m.name, description: m.description })),
|
|
174
|
-
bots: bots.map((b) => ({ id: b.id, name: b.name })),
|
|
175
186
|
}
|
|
176
|
-
}
|
|
177
|
-
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const [groups, openedChats, snoozedChats, closedChats, managers, bots] = await Promise.all([
|
|
190
|
+
client.listGroups({ limit: 20 }),
|
|
191
|
+
client.listUserChats({ state: 'opened', limit: 10, sortOrder: 'desc' }),
|
|
192
|
+
client.listUserChats({ state: 'snoozed', limit: 1 }),
|
|
193
|
+
client.listUserChats({ state: 'closed', limit: 1 }),
|
|
194
|
+
client.listManagers({ limit: 50 }),
|
|
195
|
+
client.listBots({ limit: 50 }),
|
|
196
|
+
])
|
|
197
|
+
|
|
198
|
+
const groupsWithMessages = await Promise.all(
|
|
199
|
+
groups.map(async (g) => {
|
|
200
|
+
const messages = await client.getGroupMessages(g.id, { limit, sortOrder: 'desc' })
|
|
201
|
+
return {
|
|
202
|
+
id: g.id,
|
|
203
|
+
name: g.name,
|
|
204
|
+
messages: messages.map((m) => ({
|
|
205
|
+
id: m.id,
|
|
206
|
+
person_type: m.personType,
|
|
207
|
+
plain_text: m.plainText,
|
|
208
|
+
created_at: m.createdAt,
|
|
209
|
+
})),
|
|
210
|
+
}
|
|
211
|
+
}),
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
const recentOpened = await Promise.all(
|
|
215
|
+
openedChats.slice(0, 5).map(async (chat) => {
|
|
216
|
+
const messages = await client.getUserChatMessages(chat.id, { limit: 1, sortOrder: 'desc' })
|
|
217
|
+
return {
|
|
218
|
+
id: chat.id,
|
|
219
|
+
name: chat.name,
|
|
220
|
+
user_id: chat.userId,
|
|
221
|
+
last_message: messages[0]
|
|
222
|
+
? {
|
|
223
|
+
id: messages[0].id,
|
|
224
|
+
plain_text: messages[0].plainText,
|
|
225
|
+
created_at: messages[0].createdAt,
|
|
226
|
+
}
|
|
227
|
+
: undefined,
|
|
228
|
+
}
|
|
229
|
+
}),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
workspace,
|
|
234
|
+
groups: groupsWithMessages,
|
|
235
|
+
user_chats: {
|
|
236
|
+
opened_count: openedChats.length,
|
|
237
|
+
snoozed_count: snoozedChats.length,
|
|
238
|
+
closed_count: closedChats.length,
|
|
239
|
+
recent_opened: recentOpened,
|
|
240
|
+
},
|
|
241
|
+
managers: managers.map((m) => ({ id: m.id, name: m.name, description: m.description })),
|
|
242
|
+
bots: bots.map((b) => ({ id: b.id, name: b.name })),
|
|
178
243
|
}
|
|
179
244
|
}
|
|
180
245
|
|
|
181
246
|
export const snapshotCommand = new Command('snapshot')
|
|
182
|
-
.description('Workspace overview for AI
|
|
247
|
+
.description('Workspace overview for AI agents (brief by default, use --full for comprehensive data)')
|
|
248
|
+
.option('--full', 'Include messages, managers, and bots (verbose)')
|
|
183
249
|
.option('--groups-only', 'List groups only, skip user chats')
|
|
184
250
|
.option('--chats-only', 'List user chats only, skip groups')
|
|
185
|
-
.option('--limit <n>', 'Messages per group/chat (default: 5)', '5')
|
|
251
|
+
.option('--limit <n>', 'Messages per group/chat with --full (default: 5)', '5')
|
|
186
252
|
.option('--workspace <id>', 'Workspace ID')
|
|
187
253
|
.option('--bot <name>', 'Bot name')
|
|
188
254
|
.option('--pretty', 'Pretty print JSON output')
|
|
@@ -190,6 +256,7 @@ export const snapshotCommand = new Command('snapshot')
|
|
|
190
256
|
try {
|
|
191
257
|
const result = await snapshotAction({
|
|
192
258
|
...options,
|
|
259
|
+
full: options.full,
|
|
193
260
|
limit: parseInt(options.limit, 10),
|
|
194
261
|
})
|
|
195
262
|
console.log(formatOutput(result, options.pretty))
|