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.
Files changed (119) hide show
  1. package/.claude-plugin/marketplace.json +14 -1
  2. package/.claude-plugin/plugin.json +4 -2
  3. package/README.md +33 -29
  4. package/dist/package.json +10 -2
  5. package/dist/src/cli.d.ts.map +1 -1
  6. package/dist/src/cli.js +3 -0
  7. package/dist/src/cli.js.map +1 -1
  8. package/dist/src/platforms/webex/app-config.d.ts +7 -0
  9. package/dist/src/platforms/webex/app-config.d.ts.map +1 -0
  10. package/dist/src/platforms/webex/app-config.js +20 -0
  11. package/dist/src/platforms/webex/app-config.js.map +1 -0
  12. package/dist/src/platforms/webex/cli.d.ts +5 -0
  13. package/dist/src/platforms/webex/cli.d.ts.map +1 -0
  14. package/dist/src/platforms/webex/cli.js +32 -0
  15. package/dist/src/platforms/webex/cli.js.map +1 -0
  16. package/dist/src/platforms/webex/client.d.ts +45 -0
  17. package/dist/src/platforms/webex/client.d.ts.map +1 -0
  18. package/dist/src/platforms/webex/client.js +175 -0
  19. package/dist/src/platforms/webex/client.js.map +1 -0
  20. package/dist/src/platforms/webex/commands/auth.d.ts +15 -0
  21. package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -0
  22. package/dist/src/platforms/webex/commands/auth.js +124 -0
  23. package/dist/src/platforms/webex/commands/auth.js.map +1 -0
  24. package/dist/src/platforms/webex/commands/index.d.ts +6 -0
  25. package/dist/src/platforms/webex/commands/index.d.ts.map +1 -0
  26. package/dist/src/platforms/webex/commands/index.js +6 -0
  27. package/dist/src/platforms/webex/commands/index.js.map +1 -0
  28. package/dist/src/platforms/webex/commands/member.d.ts +7 -0
  29. package/dist/src/platforms/webex/commands/member.d.ts.map +1 -0
  30. package/dist/src/platforms/webex/commands/member.js +34 -0
  31. package/dist/src/platforms/webex/commands/member.js.map +1 -0
  32. package/dist/src/platforms/webex/commands/message.d.ts +26 -0
  33. package/dist/src/platforms/webex/commands/message.d.ts.map +1 -0
  34. package/dist/src/platforms/webex/commands/message.js +153 -0
  35. package/dist/src/platforms/webex/commands/message.js.map +1 -0
  36. package/dist/src/platforms/webex/commands/snapshot.d.ts +9 -0
  37. package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -0
  38. package/dist/src/platforms/webex/commands/snapshot.js +72 -0
  39. package/dist/src/platforms/webex/commands/snapshot.js.map +1 -0
  40. package/dist/src/platforms/webex/commands/space.d.ts +11 -0
  41. package/dist/src/platforms/webex/commands/space.d.ts.map +1 -0
  42. package/dist/src/platforms/webex/commands/space.js +59 -0
  43. package/dist/src/platforms/webex/commands/space.js.map +1 -0
  44. package/dist/src/platforms/webex/credential-manager.d.ts +23 -0
  45. package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -0
  46. package/dist/src/platforms/webex/credential-manager.js +148 -0
  47. package/dist/src/platforms/webex/credential-manager.js.map +1 -0
  48. package/dist/src/platforms/webex/ensure-auth.d.ts +2 -0
  49. package/dist/src/platforms/webex/ensure-auth.d.ts.map +1 -0
  50. package/dist/src/platforms/webex/ensure-auth.js +20 -0
  51. package/dist/src/platforms/webex/ensure-auth.js.map +1 -0
  52. package/dist/src/platforms/webex/index.d.ts +6 -0
  53. package/dist/src/platforms/webex/index.d.ts.map +1 -0
  54. package/dist/src/platforms/webex/index.js +5 -0
  55. package/dist/src/platforms/webex/index.js.map +1 -0
  56. package/dist/src/platforms/webex/types.d.ts +124 -0
  57. package/dist/src/platforms/webex/types.d.ts.map +1 -0
  58. package/dist/src/platforms/webex/types.js +63 -0
  59. package/dist/src/platforms/webex/types.js.map +1 -0
  60. package/dist/src/tui/adapters/webex-adapter.d.ts +14 -0
  61. package/dist/src/tui/adapters/webex-adapter.d.ts.map +1 -0
  62. package/dist/src/tui/adapters/webex-adapter.js +79 -0
  63. package/dist/src/tui/adapters/webex-adapter.js.map +1 -0
  64. package/dist/src/tui/app.d.ts.map +1 -1
  65. package/dist/src/tui/app.js +2 -0
  66. package/dist/src/tui/app.js.map +1 -1
  67. package/docs/content/docs/cli/meta.json +1 -0
  68. package/docs/content/docs/cli/webex.mdx +291 -0
  69. package/docs/content/docs/sdk/meta.json +1 -1
  70. package/docs/content/docs/sdk/webex.mdx +260 -0
  71. package/docs/content/docs/tui.mdx +4 -3
  72. package/docs/src/app/page.tsx +2 -2
  73. package/package.json +10 -2
  74. package/skills/agent-channeltalk/SKILL.md +1 -1
  75. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  76. package/skills/agent-discord/SKILL.md +1 -1
  77. package/skills/agent-discordbot/SKILL.md +1 -1
  78. package/skills/agent-instagram/SKILL.md +1 -1
  79. package/skills/agent-kakaotalk/SKILL.md +1 -1
  80. package/skills/agent-line/SKILL.md +1 -1
  81. package/skills/agent-slack/SKILL.md +1 -1
  82. package/skills/agent-slackbot/SKILL.md +1 -1
  83. package/skills/agent-teams/SKILL.md +1 -1
  84. package/skills/agent-telegram/SKILL.md +1 -1
  85. package/skills/agent-webex/SKILL.md +386 -0
  86. package/skills/agent-webex/references/authentication.md +318 -0
  87. package/skills/agent-webex/references/common-patterns.md +723 -0
  88. package/skills/agent-webex/templates/monitor-space.sh +165 -0
  89. package/skills/agent-webex/templates/post-message.sh +170 -0
  90. package/skills/agent-whatsapp/SKILL.md +1 -1
  91. package/skills/agent-whatsappbot/SKILL.md +1 -1
  92. package/src/cli.ts +4 -0
  93. package/src/platforms/webex/app-config.test.ts +98 -0
  94. package/src/platforms/webex/app-config.ts +31 -0
  95. package/src/platforms/webex/cli.test.ts +58 -0
  96. package/src/platforms/webex/cli.ts +39 -0
  97. package/src/platforms/webex/client.test.ts +429 -0
  98. package/src/platforms/webex/client.ts +247 -0
  99. package/src/platforms/webex/commands/auth.test.ts +222 -0
  100. package/src/platforms/webex/commands/auth.ts +180 -0
  101. package/src/platforms/webex/commands/index.ts +5 -0
  102. package/src/platforms/webex/commands/member.test.ts +103 -0
  103. package/src/platforms/webex/commands/member.ts +45 -0
  104. package/src/platforms/webex/commands/message.test.ts +231 -0
  105. package/src/platforms/webex/commands/message.ts +204 -0
  106. package/src/platforms/webex/commands/snapshot.test.ts +96 -0
  107. package/src/platforms/webex/commands/snapshot.ts +91 -0
  108. package/src/platforms/webex/commands/space.test.ts +206 -0
  109. package/src/platforms/webex/commands/space.ts +74 -0
  110. package/src/platforms/webex/credential-manager.test.ts +314 -0
  111. package/src/platforms/webex/credential-manager.ts +197 -0
  112. package/src/platforms/webex/ensure-auth.test.ts +85 -0
  113. package/src/platforms/webex/ensure-auth.ts +19 -0
  114. package/src/platforms/webex/index.test.ts +25 -0
  115. package/src/platforms/webex/index.ts +17 -0
  116. package/src/platforms/webex/types.test.ts +307 -0
  117. package/src/platforms/webex/types.ts +127 -0
  118. package/src/tui/adapters/webex-adapter.ts +103 -0
  119. 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 },