agent-messenger 2.0.0 → 2.1.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/marketplace.json +14 -1
- package/.claude-plugin/plugin.json +4 -2
- package/README.md +33 -29
- package/dist/package.json +10 -2
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +3 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/platforms/webex/app-config.d.ts +7 -0
- package/dist/src/platforms/webex/app-config.d.ts.map +1 -0
- package/dist/src/platforms/webex/app-config.js +20 -0
- package/dist/src/platforms/webex/app-config.js.map +1 -0
- package/dist/src/platforms/webex/cli.d.ts +5 -0
- package/dist/src/platforms/webex/cli.d.ts.map +1 -0
- package/dist/src/platforms/webex/cli.js +32 -0
- package/dist/src/platforms/webex/cli.js.map +1 -0
- package/dist/src/platforms/webex/client.d.ts +45 -0
- package/dist/src/platforms/webex/client.d.ts.map +1 -0
- package/dist/src/platforms/webex/client.js +175 -0
- package/dist/src/platforms/webex/client.js.map +1 -0
- package/dist/src/platforms/webex/commands/auth.d.ts +15 -0
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/webex/commands/auth.js +124 -0
- package/dist/src/platforms/webex/commands/auth.js.map +1 -0
- package/dist/src/platforms/webex/commands/index.d.ts +6 -0
- package/dist/src/platforms/webex/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/webex/commands/index.js +6 -0
- package/dist/src/platforms/webex/commands/index.js.map +1 -0
- package/dist/src/platforms/webex/commands/member.d.ts +7 -0
- package/dist/src/platforms/webex/commands/member.d.ts.map +1 -0
- package/dist/src/platforms/webex/commands/member.js +34 -0
- package/dist/src/platforms/webex/commands/member.js.map +1 -0
- package/dist/src/platforms/webex/commands/message.d.ts +26 -0
- package/dist/src/platforms/webex/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/webex/commands/message.js +153 -0
- package/dist/src/platforms/webex/commands/message.js.map +1 -0
- package/dist/src/platforms/webex/commands/snapshot.d.ts +9 -0
- package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -0
- package/dist/src/platforms/webex/commands/snapshot.js +72 -0
- package/dist/src/platforms/webex/commands/snapshot.js.map +1 -0
- package/dist/src/platforms/webex/commands/space.d.ts +11 -0
- package/dist/src/platforms/webex/commands/space.d.ts.map +1 -0
- package/dist/src/platforms/webex/commands/space.js +59 -0
- package/dist/src/platforms/webex/commands/space.js.map +1 -0
- package/dist/src/platforms/webex/credential-manager.d.ts +23 -0
- package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/webex/credential-manager.js +148 -0
- package/dist/src/platforms/webex/credential-manager.js.map +1 -0
- package/dist/src/platforms/webex/ensure-auth.d.ts +2 -0
- package/dist/src/platforms/webex/ensure-auth.d.ts.map +1 -0
- package/dist/src/platforms/webex/ensure-auth.js +20 -0
- package/dist/src/platforms/webex/ensure-auth.js.map +1 -0
- package/dist/src/platforms/webex/index.d.ts +6 -0
- package/dist/src/platforms/webex/index.d.ts.map +1 -0
- package/dist/src/platforms/webex/index.js +5 -0
- package/dist/src/platforms/webex/index.js.map +1 -0
- package/dist/src/platforms/webex/types.d.ts +124 -0
- package/dist/src/platforms/webex/types.d.ts.map +1 -0
- package/dist/src/platforms/webex/types.js +63 -0
- package/dist/src/platforms/webex/types.js.map +1 -0
- package/dist/src/tui/adapters/webex-adapter.d.ts +14 -0
- package/dist/src/tui/adapters/webex-adapter.d.ts.map +1 -0
- package/dist/src/tui/adapters/webex-adapter.js +79 -0
- package/dist/src/tui/adapters/webex-adapter.js.map +1 -0
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +2 -0
- package/dist/src/tui/app.js.map +1 -1
- package/docs/content/docs/cli/meta.json +1 -0
- package/docs/content/docs/cli/webex.mdx +291 -0
- package/docs/content/docs/sdk/meta.json +1 -1
- package/docs/content/docs/sdk/webex.mdx +260 -0
- package/docs/content/docs/tui.mdx +4 -3
- package/docs/src/app/page.tsx +2 -2
- package/package.json +10 -2
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +1 -1
- 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 +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +386 -0
- package/skills/agent-webex/references/authentication.md +318 -0
- package/skills/agent-webex/references/common-patterns.md +723 -0
- package/skills/agent-webex/templates/monitor-space.sh +165 -0
- package/skills/agent-webex/templates/post-message.sh +170 -0
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/cli.ts +4 -0
- package/src/platforms/webex/app-config.test.ts +98 -0
- package/src/platforms/webex/app-config.ts +31 -0
- package/src/platforms/webex/cli.test.ts +58 -0
- package/src/platforms/webex/cli.ts +39 -0
- package/src/platforms/webex/client.test.ts +429 -0
- package/src/platforms/webex/client.ts +247 -0
- package/src/platforms/webex/commands/auth.test.ts +222 -0
- package/src/platforms/webex/commands/auth.ts +180 -0
- package/src/platforms/webex/commands/index.ts +5 -0
- package/src/platforms/webex/commands/member.test.ts +103 -0
- package/src/platforms/webex/commands/member.ts +45 -0
- package/src/platforms/webex/commands/message.test.ts +231 -0
- package/src/platforms/webex/commands/message.ts +204 -0
- package/src/platforms/webex/commands/snapshot.test.ts +96 -0
- package/src/platforms/webex/commands/snapshot.ts +91 -0
- package/src/platforms/webex/commands/space.test.ts +206 -0
- package/src/platforms/webex/commands/space.ts +74 -0
- package/src/platforms/webex/credential-manager.test.ts +314 -0
- package/src/platforms/webex/credential-manager.ts +197 -0
- package/src/platforms/webex/ensure-auth.test.ts +85 -0
- package/src/platforms/webex/ensure-auth.ts +19 -0
- package/src/platforms/webex/index.test.ts +25 -0
- package/src/platforms/webex/index.ts +17 -0
- package/src/platforms/webex/types.test.ts +307 -0
- package/src/platforms/webex/types.ts +127 -0
- package/src/tui/adapters/webex-adapter.ts +103 -0
- package/src/tui/app.ts +2 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
export interface WebexSpace {
|
|
4
|
+
id: string
|
|
5
|
+
title: string
|
|
6
|
+
type: 'group' | 'direct'
|
|
7
|
+
isLocked: boolean
|
|
8
|
+
teamId?: string
|
|
9
|
+
lastActivity: string
|
|
10
|
+
created: string
|
|
11
|
+
creatorId: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WebexMessage {
|
|
15
|
+
id: string
|
|
16
|
+
roomId: string
|
|
17
|
+
roomType: 'group' | 'direct'
|
|
18
|
+
text?: string
|
|
19
|
+
markdown?: string
|
|
20
|
+
html?: string
|
|
21
|
+
files?: string[]
|
|
22
|
+
personId: string
|
|
23
|
+
personEmail: string
|
|
24
|
+
created: string
|
|
25
|
+
parentId?: string
|
|
26
|
+
mentionedPeople?: string[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface WebexPerson {
|
|
30
|
+
id: string
|
|
31
|
+
emails: string[]
|
|
32
|
+
displayName: string
|
|
33
|
+
nickName?: string
|
|
34
|
+
firstName?: string
|
|
35
|
+
lastName?: string
|
|
36
|
+
avatar?: string
|
|
37
|
+
orgId: string
|
|
38
|
+
type: 'person' | 'bot'
|
|
39
|
+
created: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface WebexMembership {
|
|
43
|
+
id: string
|
|
44
|
+
roomId: string
|
|
45
|
+
personId: string
|
|
46
|
+
personEmail: string
|
|
47
|
+
personDisplayName: string
|
|
48
|
+
isModerator: boolean
|
|
49
|
+
created: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface WebexConfig {
|
|
53
|
+
accessToken: string
|
|
54
|
+
refreshToken: string
|
|
55
|
+
expiresAt: number
|
|
56
|
+
clientId?: string
|
|
57
|
+
clientSecret?: string
|
|
58
|
+
tokenType?: 'oauth' | 'manual'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class WebexError extends Error {
|
|
62
|
+
code: string
|
|
63
|
+
|
|
64
|
+
constructor(message: string, code: string) {
|
|
65
|
+
super(message)
|
|
66
|
+
this.name = 'WebexError'
|
|
67
|
+
this.code = code
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const WebexSpaceSchema = z.object({
|
|
72
|
+
id: z.string(),
|
|
73
|
+
title: z.string(),
|
|
74
|
+
type: z.enum(['group', 'direct']),
|
|
75
|
+
isLocked: z.boolean(),
|
|
76
|
+
teamId: z.string().optional(),
|
|
77
|
+
lastActivity: z.string(),
|
|
78
|
+
created: z.string(),
|
|
79
|
+
creatorId: z.string(),
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
export const WebexMessageSchema = z.object({
|
|
83
|
+
id: z.string(),
|
|
84
|
+
roomId: z.string(),
|
|
85
|
+
roomType: z.enum(['group', 'direct']),
|
|
86
|
+
text: z.string().optional(),
|
|
87
|
+
markdown: z.string().optional(),
|
|
88
|
+
html: z.string().optional(),
|
|
89
|
+
files: z.array(z.string()).optional(),
|
|
90
|
+
personId: z.string(),
|
|
91
|
+
personEmail: z.string(),
|
|
92
|
+
created: z.string(),
|
|
93
|
+
parentId: z.string().optional(),
|
|
94
|
+
mentionedPeople: z.array(z.string()).optional(),
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
export const WebexPersonSchema = z.object({
|
|
98
|
+
id: z.string(),
|
|
99
|
+
emails: z.array(z.string()),
|
|
100
|
+
displayName: z.string(),
|
|
101
|
+
nickName: z.string().optional(),
|
|
102
|
+
firstName: z.string().optional(),
|
|
103
|
+
lastName: z.string().optional(),
|
|
104
|
+
avatar: z.string().optional(),
|
|
105
|
+
orgId: z.string(),
|
|
106
|
+
type: z.enum(['person', 'bot']),
|
|
107
|
+
created: z.string(),
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
export const WebexMembershipSchema = z.object({
|
|
111
|
+
id: z.string(),
|
|
112
|
+
roomId: z.string(),
|
|
113
|
+
personId: z.string(),
|
|
114
|
+
personEmail: z.string(),
|
|
115
|
+
personDisplayName: z.string(),
|
|
116
|
+
isModerator: z.boolean(),
|
|
117
|
+
created: z.string(),
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
export const WebexConfigSchema = z.object({
|
|
121
|
+
accessToken: z.string(),
|
|
122
|
+
refreshToken: z.string(),
|
|
123
|
+
expiresAt: z.number(),
|
|
124
|
+
clientId: z.string().optional(),
|
|
125
|
+
clientSecret: z.string().optional(),
|
|
126
|
+
tokenType: z.enum(['oauth', 'manual']).optional(),
|
|
127
|
+
})
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { exec } from 'node:child_process'
|
|
2
|
+
|
|
3
|
+
import { WebexClient } from '@/platforms/webex/client'
|
|
4
|
+
import { WebexCredentialManager } from '@/platforms/webex/credential-manager'
|
|
5
|
+
import { getWebexAppCredentials } from '@/platforms/webex/app-config'
|
|
6
|
+
|
|
7
|
+
import type { AuthHint, AuthIO, PlatformAdapter, UnifiedChannel, UnifiedMessage } from './types'
|
|
8
|
+
|
|
9
|
+
export class WebexAdapter implements PlatformAdapter {
|
|
10
|
+
readonly name = 'Webex'
|
|
11
|
+
|
|
12
|
+
private client: WebexClient | null = null
|
|
13
|
+
private personEmail: string | null = null
|
|
14
|
+
|
|
15
|
+
async login(): Promise<void> {
|
|
16
|
+
const client = new WebexClient()
|
|
17
|
+
await client.login()
|
|
18
|
+
const me = await client.testAuth()
|
|
19
|
+
this.client = client
|
|
20
|
+
this.personEmail = me.emails[0] ?? null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async getChannels(): Promise<UnifiedChannel[]> {
|
|
24
|
+
this.ensureClient()
|
|
25
|
+
const spaces = await this.client!.listSpaces()
|
|
26
|
+
return spaces.map((space) => ({
|
|
27
|
+
id: space.id,
|
|
28
|
+
name: space.title,
|
|
29
|
+
}))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async getMessages(channelId: string, limit = 50): Promise<UnifiedMessage[]> {
|
|
33
|
+
this.ensureClient()
|
|
34
|
+
const messages = await this.client!.listMessages(channelId, { max: limit })
|
|
35
|
+
return messages
|
|
36
|
+
.map((msg) => ({
|
|
37
|
+
id: msg.id,
|
|
38
|
+
channelId: msg.roomId,
|
|
39
|
+
author: msg.personEmail,
|
|
40
|
+
content: msg.text ?? '',
|
|
41
|
+
timestamp: msg.created,
|
|
42
|
+
}))
|
|
43
|
+
.reverse()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async sendMessage(channelId: string, text: string): Promise<void> {
|
|
47
|
+
this.ensureClient()
|
|
48
|
+
await this.client!.sendMessage(channelId, text)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getAuthHint(): AuthHint {
|
|
52
|
+
return {
|
|
53
|
+
command: 'agent-webex auth login',
|
|
54
|
+
description: 'Authenticate with Cisco Webex using OAuth Device Grant. Run the command below to start.',
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async authenticate(io: AuthIO): Promise<void> {
|
|
59
|
+
const credManager = new WebexCredentialManager()
|
|
60
|
+
const { clientId, clientSecret } = getWebexAppCredentials()
|
|
61
|
+
|
|
62
|
+
io.print('Starting Webex OAuth Device Grant flow...')
|
|
63
|
+
const device = await credManager.requestDeviceCode(clientId)
|
|
64
|
+
|
|
65
|
+
io.print(`\nOpen this URL in your browser:\n ${device.verificationUriComplete}`)
|
|
66
|
+
io.print(`\nOr go to ${device.verificationUri} and enter code: ${device.userCode}`)
|
|
67
|
+
openBrowser(device.verificationUriComplete)
|
|
68
|
+
io.print('\nWaiting for authorization...')
|
|
69
|
+
|
|
70
|
+
const config = await credManager.pollDeviceToken(
|
|
71
|
+
device.deviceCode,
|
|
72
|
+
device.interval,
|
|
73
|
+
device.expiresIn,
|
|
74
|
+
clientId,
|
|
75
|
+
clientSecret,
|
|
76
|
+
)
|
|
77
|
+
await credManager.saveConfig(config)
|
|
78
|
+
|
|
79
|
+
const client = new WebexClient()
|
|
80
|
+
await client.login({ token: config.accessToken })
|
|
81
|
+
const me = await client.testAuth()
|
|
82
|
+
this.client = client
|
|
83
|
+
this.personEmail = me.emails[0] ?? null
|
|
84
|
+
|
|
85
|
+
io.print(`\nAuthenticated as ${me.displayName} (${this.personEmail})`)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private ensureClient(): void {
|
|
89
|
+
if (!this.client) {
|
|
90
|
+
throw new Error('Not logged in. Call login() first.')
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function openBrowser(url: string): void {
|
|
96
|
+
const command =
|
|
97
|
+
process.platform === 'darwin'
|
|
98
|
+
? `open "${url}"`
|
|
99
|
+
: process.platform === 'win32'
|
|
100
|
+
? `start "" "${url}"`
|
|
101
|
+
: `xdg-open "${url}"`
|
|
102
|
+
exec(command)
|
|
103
|
+
}
|
package/src/tui/app.ts
CHANGED
|
@@ -3,6 +3,7 @@ import blessed from 'blessed'
|
|
|
3
3
|
import { SlackAdapter } from './adapters/slack-adapter'
|
|
4
4
|
import { DiscordAdapter } from './adapters/discord-adapter'
|
|
5
5
|
import { TeamsAdapter } from './adapters/teams-adapter'
|
|
6
|
+
import { WebexAdapter } from './adapters/webex-adapter'
|
|
6
7
|
import { TelegramAdapter } from './adapters/telegram-adapter'
|
|
7
8
|
import { WhatsAppAdapter } from './adapters/whatsapp-adapter'
|
|
8
9
|
import { LineAdapter } from './adapters/line-adapter'
|
|
@@ -38,6 +39,7 @@ export async function createApp(): Promise<void> {
|
|
|
38
39
|
{ adapter: new SlackAdapter(), label: 'Slack', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|
|
39
40
|
{ adapter: new DiscordAdapter(), label: 'Discord', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|
|
40
41
|
{ adapter: new TeamsAdapter(), label: 'Teams', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|
|
42
|
+
{ adapter: new WebexAdapter(), label: 'Webex', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|
|
41
43
|
{ adapter: new TelegramAdapter(), label: 'Telegram', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|
|
42
44
|
{ adapter: new WhatsAppAdapter(), label: 'WhatsApp', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|
|
43
45
|
{ adapter: new LineAdapter(), label: 'LINE', enabled: false, channels: null, workspaces: null, listening: false, lastChannelId: null },
|