musonda 1.0.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 (196) hide show
  1. package/IMPLEMENTATION.md +432 -0
  2. package/README.md +119 -0
  3. package/dist/agent/harness.d.ts +25 -0
  4. package/dist/agent/harness.js +215 -0
  5. package/dist/agent/harness.js.map +1 -0
  6. package/dist/agent/openaiResponsesClient.d.ts +35 -0
  7. package/dist/agent/openaiResponsesClient.js +250 -0
  8. package/dist/agent/openaiResponsesClient.js.map +1 -0
  9. package/dist/agent/systemPrompt.d.ts +9 -0
  10. package/dist/agent/systemPrompt.js +100 -0
  11. package/dist/agent/systemPrompt.js.map +1 -0
  12. package/dist/agent/types.d.ts +53 -0
  13. package/dist/agent/types.js +2 -0
  14. package/dist/agent/types.js.map +1 -0
  15. package/dist/cli/commands/chat.d.ts +6 -0
  16. package/dist/cli/commands/chat.js +8 -0
  17. package/dist/cli/commands/chat.js.map +1 -0
  18. package/dist/cli/commands/doctor.d.ts +4 -0
  19. package/dist/cli/commands/doctor.js +336 -0
  20. package/dist/cli/commands/doctor.js.map +1 -0
  21. package/dist/cli/commands/gateway.d.ts +20 -0
  22. package/dist/cli/commands/gateway.js +135 -0
  23. package/dist/cli/commands/gateway.js.map +1 -0
  24. package/dist/cli/commands/help.d.ts +4 -0
  25. package/dist/cli/commands/help.js +159 -0
  26. package/dist/cli/commands/help.js.map +1 -0
  27. package/dist/cli/commands/plugins.d.ts +18 -0
  28. package/dist/cli/commands/plugins.js +250 -0
  29. package/dist/cli/commands/plugins.js.map +1 -0
  30. package/dist/cli/commands/service.d.ts +16 -0
  31. package/dist/cli/commands/service.js +136 -0
  32. package/dist/cli/commands/service.js.map +1 -0
  33. package/dist/cli/commands/setup.d.ts +4 -0
  34. package/dist/cli/commands/setup.js +8 -0
  35. package/dist/cli/commands/setup.js.map +1 -0
  36. package/dist/cli/commands/status.d.ts +4 -0
  37. package/dist/cli/commands/status.js +73 -0
  38. package/dist/cli/commands/status.js.map +1 -0
  39. package/dist/cli/commands/update.d.ts +22 -0
  40. package/dist/cli/commands/update.js +226 -0
  41. package/dist/cli/commands/update.js.map +1 -0
  42. package/dist/cli/daemon.d.ts +33 -0
  43. package/dist/cli/daemon.js +208 -0
  44. package/dist/cli/daemon.js.map +1 -0
  45. package/dist/cli/interactiveMenu.d.ts +5 -0
  46. package/dist/cli/interactiveMenu.js +225 -0
  47. package/dist/cli/interactiveMenu.js.map +1 -0
  48. package/dist/cli/musondaCli.d.ts +30 -0
  49. package/dist/cli/musondaCli.js +269 -0
  50. package/dist/cli/musondaCli.js.map +1 -0
  51. package/dist/cli/ui.d.ts +49 -0
  52. package/dist/cli/ui.js +90 -0
  53. package/dist/cli/ui.js.map +1 -0
  54. package/dist/cli.d.ts +9 -0
  55. package/dist/cli.js +315 -0
  56. package/dist/cli.js.map +1 -0
  57. package/dist/config/loader.d.ts +12 -0
  58. package/dist/config/loader.js +217 -0
  59. package/dist/config/loader.js.map +1 -0
  60. package/dist/config/paths.d.ts +11 -0
  61. package/dist/config/paths.js +18 -0
  62. package/dist/config/paths.js.map +1 -0
  63. package/dist/config/types.d.ts +246 -0
  64. package/dist/config/types.js +155 -0
  65. package/dist/config/types.js.map +1 -0
  66. package/dist/gateway/channels/cli.d.ts +37 -0
  67. package/dist/gateway/channels/cli.js +298 -0
  68. package/dist/gateway/channels/cli.js.map +1 -0
  69. package/dist/gateway/channels/discord.d.ts +18 -0
  70. package/dist/gateway/channels/discord.js +419 -0
  71. package/dist/gateway/channels/discord.js.map +1 -0
  72. package/dist/gateway/channels/slack.d.ts +26 -0
  73. package/dist/gateway/channels/slack.js +470 -0
  74. package/dist/gateway/channels/slack.js.map +1 -0
  75. package/dist/gateway/channels/webhook.d.ts +18 -0
  76. package/dist/gateway/channels/webhook.js +49 -0
  77. package/dist/gateway/channels/webhook.js.map +1 -0
  78. package/dist/gateway/http.d.ts +33 -0
  79. package/dist/gateway/http.js +605 -0
  80. package/dist/gateway/http.js.map +1 -0
  81. package/dist/gateway/server.d.ts +38 -0
  82. package/dist/gateway/server.js +233 -0
  83. package/dist/gateway/server.js.map +1 -0
  84. package/dist/gateway/types.d.ts +28 -0
  85. package/dist/gateway/types.js +2 -0
  86. package/dist/gateway/types.js.map +1 -0
  87. package/dist/index.d.ts +17 -0
  88. package/dist/index.js +32 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/memory/memoryManager.d.ts +22 -0
  91. package/dist/memory/memoryManager.js +200 -0
  92. package/dist/memory/memoryManager.js.map +1 -0
  93. package/dist/memory/storage.d.ts +24 -0
  94. package/dist/memory/storage.js +187 -0
  95. package/dist/memory/storage.js.map +1 -0
  96. package/dist/memory/types.d.ts +43 -0
  97. package/dist/memory/types.js +2 -0
  98. package/dist/memory/types.js.map +1 -0
  99. package/dist/plugins/manifest.d.ts +23 -0
  100. package/dist/plugins/manifest.js +185 -0
  101. package/dist/plugins/manifest.js.map +1 -0
  102. package/dist/plugins/mcp/mcpBridge.d.ts +31 -0
  103. package/dist/plugins/mcp/mcpBridge.js +115 -0
  104. package/dist/plugins/mcp/mcpBridge.js.map +1 -0
  105. package/dist/plugins/mcp/mcpClient.d.ts +43 -0
  106. package/dist/plugins/mcp/mcpClient.js +309 -0
  107. package/dist/plugins/mcp/mcpClient.js.map +1 -0
  108. package/dist/plugins/mcp/mcpConfig.d.ts +34 -0
  109. package/dist/plugins/mcp/mcpConfig.js +326 -0
  110. package/dist/plugins/mcp/mcpConfig.js.map +1 -0
  111. package/dist/plugins/mcp/types.d.ts +48 -0
  112. package/dist/plugins/mcp/types.js +2 -0
  113. package/dist/plugins/mcp/types.js.map +1 -0
  114. package/dist/plugins/pluginManager.d.ts +164 -0
  115. package/dist/plugins/pluginManager.js +1016 -0
  116. package/dist/plugins/pluginManager.js.map +1 -0
  117. package/dist/plugins/skills/frontmatterParser.d.ts +28 -0
  118. package/dist/plugins/skills/frontmatterParser.js +189 -0
  119. package/dist/plugins/skills/frontmatterParser.js.map +1 -0
  120. package/dist/plugins/skills/skillDiscovery.d.ts +15 -0
  121. package/dist/plugins/skills/skillDiscovery.js +148 -0
  122. package/dist/plugins/skills/skillDiscovery.js.map +1 -0
  123. package/dist/plugins/skills/skillTools.d.ts +8 -0
  124. package/dist/plugins/skills/skillTools.js +195 -0
  125. package/dist/plugins/skills/skillTools.js.map +1 -0
  126. package/dist/plugins/skills/types.d.ts +25 -0
  127. package/dist/plugins/skills/types.js +2 -0
  128. package/dist/plugins/skills/types.js.map +1 -0
  129. package/dist/plugins/types.d.ts +30 -0
  130. package/dist/plugins/types.js +2 -0
  131. package/dist/plugins/types.js.map +1 -0
  132. package/dist/scheduler/scheduler.d.ts +25 -0
  133. package/dist/scheduler/scheduler.js +239 -0
  134. package/dist/scheduler/scheduler.js.map +1 -0
  135. package/dist/scheduler/types.d.ts +39 -0
  136. package/dist/scheduler/types.js +2 -0
  137. package/dist/scheduler/types.js.map +1 -0
  138. package/dist/security/childProcessEnv.d.ts +5 -0
  139. package/dist/security/childProcessEnv.js +42 -0
  140. package/dist/security/childProcessEnv.js.map +1 -0
  141. package/dist/security/fileSandbox.d.ts +153 -0
  142. package/dist/security/fileSandbox.js +779 -0
  143. package/dist/security/fileSandbox.js.map +1 -0
  144. package/dist/service/index.d.ts +30 -0
  145. package/dist/service/index.js +41 -0
  146. package/dist/service/index.js.map +1 -0
  147. package/dist/service/systemd.d.ts +36 -0
  148. package/dist/service/systemd.js +409 -0
  149. package/dist/service/systemd.js.map +1 -0
  150. package/dist/service/types.d.ts +118 -0
  151. package/dist/service/types.js +6 -0
  152. package/dist/service/types.js.map +1 -0
  153. package/dist/tools/builtin/calcTools.d.ts +2 -0
  154. package/dist/tools/builtin/calcTools.js +51 -0
  155. package/dist/tools/builtin/calcTools.js.map +1 -0
  156. package/dist/tools/builtin/fileTools.d.ts +11 -0
  157. package/dist/tools/builtin/fileTools.js +352 -0
  158. package/dist/tools/builtin/fileTools.js.map +1 -0
  159. package/dist/tools/builtin/memoryTools.d.ts +4 -0
  160. package/dist/tools/builtin/memoryTools.js +123 -0
  161. package/dist/tools/builtin/memoryTools.js.map +1 -0
  162. package/dist/tools/builtin/noteTools.d.ts +4 -0
  163. package/dist/tools/builtin/noteTools.js +91 -0
  164. package/dist/tools/builtin/noteTools.js.map +1 -0
  165. package/dist/tools/builtin/pluginTools.d.ts +29 -0
  166. package/dist/tools/builtin/pluginTools.js +406 -0
  167. package/dist/tools/builtin/pluginTools.js.map +1 -0
  168. package/dist/tools/builtin/scheduleTools.d.ts +4 -0
  169. package/dist/tools/builtin/scheduleTools.js +156 -0
  170. package/dist/tools/builtin/scheduleTools.js.map +1 -0
  171. package/dist/tools/builtin/timeTools.d.ts +2 -0
  172. package/dist/tools/builtin/timeTools.js +41 -0
  173. package/dist/tools/builtin/timeTools.js.map +1 -0
  174. package/dist/tools/builtin/webTools.d.ts +12 -0
  175. package/dist/tools/builtin/webTools.js +325 -0
  176. package/dist/tools/builtin/webTools.js.map +1 -0
  177. package/dist/tools/registry.d.ts +15 -0
  178. package/dist/tools/registry.js +111 -0
  179. package/dist/tools/registry.js.map +1 -0
  180. package/dist/tools/types.d.ts +41 -0
  181. package/dist/tools/types.js +2 -0
  182. package/dist/tools/types.js.map +1 -0
  183. package/dist/utils/logger.d.ts +29 -0
  184. package/dist/utils/logger.js +124 -0
  185. package/dist/utils/logger.js.map +1 -0
  186. package/dist/wizard/onboarding.d.ts +3 -0
  187. package/dist/wizard/onboarding.js +408 -0
  188. package/dist/wizard/onboarding.js.map +1 -0
  189. package/package.json +69 -0
  190. package/plugins/example-calc/mcp.json +11 -0
  191. package/plugins/example-calc/plugin.json +12 -0
  192. package/plugins/example-calc/server.mjs +92 -0
  193. package/plugins/example-calc/skills/math-assistant/SKILL.md +15 -0
  194. package/plugins/plugin-builder/plugin.json +12 -0
  195. package/plugins/plugin-builder/skills/create-plugin/SKILL.md +149 -0
  196. package/plugins/plugin-builder/skills/manage-plugins/SKILL.md +157 -0
@@ -0,0 +1,470 @@
1
+ import { App, SocketModeReceiver, LogLevel as SlackLogLevel } from '@slack/bolt';
2
+ import { logger } from '../../utils/logger.js';
3
+ export class SlackChannelAdapter {
4
+ name = 'slack';
5
+ app = null;
6
+ config;
7
+ slackConfig;
8
+ messageHandler;
9
+ connected = false;
10
+ userCache = new Map();
11
+ botUserId = null;
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.slackConfig = config.channels.slack;
15
+ }
16
+ isConnected() {
17
+ return this.connected;
18
+ }
19
+ onMessage(handler) {
20
+ this.messageHandler = handler;
21
+ }
22
+ async start() {
23
+ if (!this.slackConfig.enabled) {
24
+ logger.channel('slack', 'Slack channel is disabled in configuration.');
25
+ return;
26
+ }
27
+ if (!this.slackConfig.botToken || !this.slackConfig.botToken.trim()) {
28
+ logger.warn('Slack bot token (SLACK_BOT_TOKEN) is missing. Skipping Slack channel startup.');
29
+ return;
30
+ }
31
+ const useSocketMode = this.slackConfig.socketMode ?? true;
32
+ if (useSocketMode && (!this.slackConfig.appToken || !this.slackConfig.appToken.trim())) {
33
+ logger.warn('Slack Socket Mode is enabled but SLACK_APP_TOKEN is missing. Please provide an App-Level token (xapp-...) with connections:write scope.');
34
+ return;
35
+ }
36
+ try {
37
+ let receiver;
38
+ if (useSocketMode) {
39
+ // Configure SocketModeReceiver with extended ping/pong timeout (30s client / 60s server)
40
+ // to prevent premature WebSocket drop and reconnect churn while the LLM generates answers
41
+ receiver = new SocketModeReceiver({
42
+ appToken: this.slackConfig.appToken,
43
+ clientPingTimeout: 30000,
44
+ serverPingTimeout: 60000,
45
+ autoReconnectEnabled: true,
46
+ logLevel: SlackLogLevel.WARN,
47
+ });
48
+ }
49
+ this.app = new App({
50
+ token: this.slackConfig.botToken,
51
+ receiver,
52
+ signingSecret: this.slackConfig.signingSecret || undefined,
53
+ logLevel: SlackLogLevel.WARN,
54
+ });
55
+ // Fetch Bot User ID to filter own messages and strip mentions
56
+ const authTest = await this.app.client.auth.test({ token: this.slackConfig.botToken });
57
+ this.botUserId = authTest.user_id || null;
58
+ const botUserName = authTest.user || 'MusondaBot';
59
+ logger.channel('slack', `Authenticated as @${botUserName} (${this.botUserId})`);
60
+ // 1. Listen for App Mentions (@Musonda in channels/groups)
61
+ this.app.event('app_mention', async ({ event, client }) => {
62
+ await this.handleSlackEvent({
63
+ channelId: event.channel,
64
+ userId: event.user || 'unknown-user',
65
+ text: event.text,
66
+ messageTs: event.ts,
67
+ threadTs: event.thread_ts || event.ts,
68
+ channelType: 'guild',
69
+ client,
70
+ });
71
+ });
72
+ // 2. Listen for Direct Messages (DMs)
73
+ this.app.message(async ({ message, client }) => {
74
+ const msg = message;
75
+ // Ignore messages from bots or message deletions/updates
76
+ if (msg.subtype && msg.subtype !== 'file_share')
77
+ return;
78
+ if (msg.bot_id || msg.user === this.botUserId)
79
+ return;
80
+ // Check if DM (channel starts with 'D')
81
+ const isDM = msg.channel_type === 'im' || (msg.channel && msg.channel.startsWith('D'));
82
+ if (!isDM)
83
+ return;
84
+ await this.handleSlackEvent({
85
+ channelId: msg.channel,
86
+ userId: msg.user,
87
+ text: msg.text || '',
88
+ messageTs: msg.ts,
89
+ threadTs: msg.thread_ts,
90
+ channelType: 'dm',
91
+ client,
92
+ });
93
+ });
94
+ // Start Socket Mode or HTTP server
95
+ if (useSocketMode) {
96
+ await this.app.start();
97
+ }
98
+ else {
99
+ await this.app.start(3000);
100
+ }
101
+ this.connected = true;
102
+ const assistantName = this.config.assistant.customName || this.config.assistant.name || 'Musonda';
103
+ logger.channel('slack', `Slack adapter connected via ${useSocketMode ? 'Socket Mode' : 'HTTP'} for "${assistantName}"`);
104
+ }
105
+ catch (err) {
106
+ this.connected = false;
107
+ logger.error('Failed to start Slack channel adapter:', err.message || err);
108
+ }
109
+ }
110
+ async stop() {
111
+ if (this.app) {
112
+ await this.app.stop();
113
+ this.connected = false;
114
+ logger.channel('slack', 'Slack channel adapter stopped.');
115
+ }
116
+ }
117
+ async getDisplayName(client, userId) {
118
+ if (this.userCache.has(userId)) {
119
+ return this.userCache.get(userId);
120
+ }
121
+ try {
122
+ const info = await client.users.info({ user: userId });
123
+ const name = info.user?.profile?.display_name ||
124
+ info.user?.profile?.real_name ||
125
+ info.user?.name ||
126
+ userId;
127
+ this.userCache.set(userId, name);
128
+ return name;
129
+ }
130
+ catch {
131
+ return userId;
132
+ }
133
+ }
134
+ async handleSlackEvent(params) {
135
+ const { channelId, userId, messageTs, channelType, client } = params;
136
+ let rawText = params.text.trim();
137
+ // Security Guardrail: Channel authorization check
138
+ const isPublicAllowed = Boolean(this.slackConfig.allowPublic);
139
+ const hasUserAllowlist = Boolean(this.slackConfig.allowedUsers && this.slackConfig.allowedUsers.length > 0);
140
+ const hasChannelAllowlist = Boolean(this.slackConfig.allowedChannels && this.slackConfig.allowedChannels.length > 0);
141
+ const hasAnyAllowlist = hasUserAllowlist || hasChannelAllowlist;
142
+ // In private mode (default), if no allowlists configured at all, block all inbound messages
143
+ if (!isPublicAllowed && !hasAnyAllowlist) {
144
+ logger.warn(`[SLACK] Ignored message from ${userId}. No allowlists (allowedUsers/allowedChannels) configured and allowPublic is false.`);
145
+ return;
146
+ }
147
+ // In DMs, require user to be in allowedUsers unless allowPublic is explicitly enabled
148
+ if (channelType === 'dm' && !isPublicAllowed && !hasUserAllowlist) {
149
+ logger.warn(`[SLACK] Ignored DM from unauthorized user ${userId}. Add to allowedUsers or set allowPublic: true.`);
150
+ return;
151
+ }
152
+ // Check user allowlist if configured
153
+ if (hasUserAllowlist && !this.slackConfig.allowedUsers.includes(userId)) {
154
+ return;
155
+ }
156
+ // Check channel allowlist if configured
157
+ if (hasChannelAllowlist && !this.slackConfig.allowedChannels.includes(channelId)) {
158
+ return;
159
+ }
160
+ // Strip bot mention tags: <@U012345>
161
+ if (this.botUserId) {
162
+ rawText = rawText.replace(new RegExp(`<@${this.botUserId}>`, 'g'), '').trim();
163
+ }
164
+ // Also strip generic mention tags at start of message
165
+ rawText = rawText.replace(/^<@[A-Z0-9]+>/g, '').trim();
166
+ const assistantName = this.config.assistant.customName || this.config.assistant.name || 'Musonda';
167
+ if (rawText.toLowerCase().startsWith(assistantName.toLowerCase())) {
168
+ rawText = rawText.substring(assistantName.length).replace(/^[,:\s]+/, '').trim();
169
+ }
170
+ if (!rawText) {
171
+ const userName = await this.getDisplayName(client, userId);
172
+ await client.chat.postMessage({
173
+ channel: channelId,
174
+ text: `Hello ${userName}! How can I help you today?`,
175
+ thread_ts: this.slackConfig.replyInThread && channelType === 'guild' ? params.threadTs : undefined,
176
+ });
177
+ return;
178
+ }
179
+ const targetThreadTs = params.threadTs ||
180
+ (this.slackConfig.replyInThread && channelType === 'guild' ? messageTs : undefined);
181
+ // Reaction indicator for visual feedback while thinking
182
+ let reactionAdded = false;
183
+ try {
184
+ await client.reactions.add({
185
+ channel: channelId,
186
+ timestamp: messageTs,
187
+ name: 'eyes',
188
+ });
189
+ reactionAdded = true;
190
+ }
191
+ catch { }
192
+ const removeReaction = async () => {
193
+ if (reactionAdded) {
194
+ try {
195
+ await client.reactions.remove({
196
+ channel: channelId,
197
+ timestamp: messageTs,
198
+ name: 'eyes',
199
+ });
200
+ reactionAdded = false;
201
+ }
202
+ catch { }
203
+ }
204
+ };
205
+ const setSlackStatus = async (statusText) => {
206
+ try {
207
+ await client.apiCall('agents.sessions.setStatus', {
208
+ channel_id: channelId,
209
+ thread_ts: targetThreadTs || messageTs,
210
+ status: statusText,
211
+ });
212
+ }
213
+ catch (err) {
214
+ try {
215
+ await client.apiCall('assistant.threads.setStatus', {
216
+ channel_id: channelId,
217
+ thread_ts: targetThreadTs || messageTs,
218
+ status: statusText,
219
+ });
220
+ }
221
+ catch { }
222
+ }
223
+ };
224
+ const clearSlackStatus = async () => {
225
+ try {
226
+ await client.apiCall('agents.sessions.setStatus', {
227
+ channel_id: channelId,
228
+ thread_ts: targetThreadTs || messageTs,
229
+ status: '',
230
+ });
231
+ }
232
+ catch {
233
+ try {
234
+ await client.apiCall('assistant.threads.setStatus', {
235
+ channel_id: channelId,
236
+ thread_ts: targetThreadTs || messageTs,
237
+ status: '',
238
+ });
239
+ }
240
+ catch { }
241
+ }
242
+ };
243
+ let streamTs = null;
244
+ let streamFailed = false;
245
+ let hasStreamed = false;
246
+ const startStream = async () => {
247
+ if (streamTs)
248
+ return true;
249
+ if (streamFailed)
250
+ return false;
251
+ try {
252
+ const payload = {
253
+ channel: channelId,
254
+ thread_ts: targetThreadTs,
255
+ };
256
+ if (userId) {
257
+ payload.recipient_user_id = userId;
258
+ }
259
+ const res = await client.apiCall('chat.startStream', payload);
260
+ if (res && (res.ts || res.stream_ts)) {
261
+ streamTs = res.ts || res.stream_ts;
262
+ return true;
263
+ }
264
+ }
265
+ catch (err) {
266
+ logger.debug('[SLACK] chat.startStream not supported or failed, falling back to chat.postMessage:', err.message);
267
+ streamFailed = true;
268
+ }
269
+ return false;
270
+ };
271
+ const appendStream = async (chunkText) => {
272
+ if (streamFailed)
273
+ return;
274
+ if (!streamTs) {
275
+ const started = await startStream();
276
+ if (!started)
277
+ return;
278
+ }
279
+ try {
280
+ await client.apiCall('chat.appendStream', {
281
+ channel: channelId,
282
+ ts: streamTs,
283
+ chunks: [
284
+ {
285
+ type: 'markdown_text',
286
+ text: this.formatForSlack(chunkText),
287
+ },
288
+ ],
289
+ });
290
+ hasStreamed = true;
291
+ }
292
+ catch (err) {
293
+ logger.debug('[SLACK] chat.appendStream failed:', err.message);
294
+ }
295
+ };
296
+ const stopStream = async () => {
297
+ if (streamTs) {
298
+ try {
299
+ await client.apiCall('chat.stopStream', {
300
+ channel: channelId,
301
+ ts: streamTs,
302
+ });
303
+ }
304
+ catch (err) {
305
+ logger.debug('[SLACK] chat.stopStream failed:', err.message);
306
+ }
307
+ streamTs = null;
308
+ }
309
+ };
310
+ const userName = await this.getDisplayName(client, userId);
311
+ // Reply handler with Slack markdown formatting and chunking
312
+ const replyFn = async (text) => {
313
+ await removeReaction();
314
+ await clearSlackStatus();
315
+ if (hasStreamed) {
316
+ return;
317
+ }
318
+ const formatted = this.formatForSlack(text);
319
+ const chunks = this.splitMessage(formatted, 3000);
320
+ for (const chunk of chunks) {
321
+ try {
322
+ await client.chat.postMessage({
323
+ channel: channelId,
324
+ text: chunk,
325
+ thread_ts: targetThreadTs,
326
+ });
327
+ }
328
+ catch (err) {
329
+ logger.error('Failed to send Slack reply chunk:', err.message);
330
+ }
331
+ }
332
+ };
333
+ const inbound = {
334
+ id: `slack_${channelId}_${messageTs}`,
335
+ channel: 'slack',
336
+ channelType,
337
+ channelId,
338
+ userId,
339
+ userName,
340
+ threadTs: targetThreadTs,
341
+ text: rawText,
342
+ reply: replyFn,
343
+ onEvent: async (event) => {
344
+ switch (event.type) {
345
+ case 'run.started': {
346
+ await setSlackStatus('Thinking…');
347
+ break;
348
+ }
349
+ case 'status': {
350
+ await setSlackStatus(event.text);
351
+ break;
352
+ }
353
+ case 'tool.started': {
354
+ const toolText = event.name.toLowerCase().includes('search')
355
+ ? 'Searching…'
356
+ : `Running \`${event.name}\`…`;
357
+ await setSlackStatus(toolText);
358
+ break;
359
+ }
360
+ case 'tool.completed': {
361
+ break;
362
+ }
363
+ case 'output.delta': {
364
+ await removeReaction();
365
+ await appendStream(event.text);
366
+ break;
367
+ }
368
+ case 'run.completed': {
369
+ await stopStream();
370
+ await clearSlackStatus();
371
+ await removeReaction();
372
+ break;
373
+ }
374
+ case 'run.failed': {
375
+ await stopStream();
376
+ await clearSlackStatus();
377
+ await removeReaction();
378
+ break;
379
+ }
380
+ }
381
+ },
382
+ onStreamDelta: async (delta) => {
383
+ await removeReaction();
384
+ await appendStream(delta);
385
+ },
386
+ };
387
+ if (this.messageHandler) {
388
+ try {
389
+ await this.messageHandler(inbound);
390
+ }
391
+ catch (err) {
392
+ await removeReaction();
393
+ await clearSlackStatus();
394
+ await stopStream();
395
+ logger.error('Error handling Slack message:', err);
396
+ await client.chat.postMessage({
397
+ channel: channelId,
398
+ text: `⚠️ Sorry, an error occurred in Musonda: ${err.message}`,
399
+ thread_ts: targetThreadTs,
400
+ });
401
+ }
402
+ finally {
403
+ await removeReaction();
404
+ await clearSlackStatus();
405
+ }
406
+ }
407
+ }
408
+ /**
409
+ * Convert standard Markdown to Slack mrkdwn
410
+ * Converts bold **text** to *text*, while preserving triple backticks.
411
+ */
412
+ formatForSlack(text) {
413
+ const parts = text.split(/(```[\s\S]*?```)/g);
414
+ return parts
415
+ .map((part) => {
416
+ if (part.startsWith('```')) {
417
+ return part; // keep code block untouched
418
+ }
419
+ // Replace **bold** with *bold*
420
+ return part.replace(/\*\*([^*]+)\*\*/g, '*$1*');
421
+ })
422
+ .join('');
423
+ }
424
+ splitMessage(text, maxLength = 3000) {
425
+ if (text.length <= maxLength)
426
+ return [text];
427
+ const chunks = [];
428
+ let remaining = text;
429
+ while (remaining.length > 0) {
430
+ if (remaining.length <= maxLength) {
431
+ chunks.push(remaining);
432
+ break;
433
+ }
434
+ let splitIndex = remaining.lastIndexOf('\n\n', maxLength);
435
+ if (splitIndex === -1 || splitIndex < maxLength * 0.5) {
436
+ splitIndex = remaining.lastIndexOf('\n', maxLength);
437
+ }
438
+ if (splitIndex === -1 || splitIndex < maxLength * 0.5) {
439
+ splitIndex = remaining.lastIndexOf(' ', maxLength);
440
+ }
441
+ if (splitIndex === -1 || splitIndex === 0) {
442
+ splitIndex = maxLength;
443
+ }
444
+ chunks.push(remaining.substring(0, splitIndex).trim());
445
+ remaining = remaining.substring(splitIndex).trim();
446
+ }
447
+ return chunks;
448
+ }
449
+ async sendDirect(channelId, text, threadTs) {
450
+ if (!this.app || !this.connected)
451
+ return false;
452
+ try {
453
+ const formatted = this.formatForSlack(text);
454
+ const chunks = this.splitMessage(formatted, 3000);
455
+ for (const chunk of chunks) {
456
+ await this.app.client.chat.postMessage({
457
+ channel: channelId,
458
+ text: chunk,
459
+ thread_ts: threadTs,
460
+ });
461
+ }
462
+ return true;
463
+ }
464
+ catch (err) {
465
+ logger.error(`Failed to send Slack direct message to ${channelId}:`, err.message);
466
+ return false;
467
+ }
468
+ }
469
+ }
470
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/gateway/channels/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { ChannelAdapter, InboundMessage } from '../types.js';
2
+ import { AgentEvent } from '../../agent/types.js';
3
+ export declare class WebhookChannelAdapter implements ChannelAdapter {
4
+ readonly name = "webhook";
5
+ private messageHandler?;
6
+ private connected;
7
+ isConnected(): boolean;
8
+ onMessage(handler: (message: InboundMessage) => Promise<void>): void;
9
+ start(): Promise<void>;
10
+ stop(): Promise<void>;
11
+ dispatchDirect(text: string, options?: {
12
+ userId?: string;
13
+ userName?: string;
14
+ channelId?: string;
15
+ onDelta?: (delta: string) => void | Promise<void>;
16
+ onEvent?: (event: AgentEvent) => void | Promise<void>;
17
+ }): Promise<string>;
18
+ }
@@ -0,0 +1,49 @@
1
+ import { logger } from '../../utils/logger.js';
2
+ export class WebhookChannelAdapter {
3
+ name = 'webhook';
4
+ messageHandler;
5
+ connected = false;
6
+ isConnected() {
7
+ return this.connected;
8
+ }
9
+ onMessage(handler) {
10
+ this.messageHandler = handler;
11
+ }
12
+ async start() {
13
+ this.connected = true;
14
+ logger.channel('webhook', 'Webhook/API channel adapter ready.');
15
+ }
16
+ async stop() {
17
+ this.connected = false;
18
+ logger.channel('webhook', 'Webhook adapter stopped.');
19
+ }
20
+ async dispatchDirect(text, options = {}) {
21
+ if (!this.messageHandler) {
22
+ throw new Error('No message handler registered for WebhookChannelAdapter.');
23
+ }
24
+ return new Promise((resolve, reject) => {
25
+ let resolved = false;
26
+ const inbound = {
27
+ id: `wh_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`,
28
+ channel: 'webhook',
29
+ channelType: 'webhook',
30
+ channelId: options.channelId || 'default-webhook',
31
+ userId: options.userId || 'api-user',
32
+ userName: options.userName || 'API User',
33
+ text,
34
+ onStreamDelta: options.onDelta,
35
+ onEvent: options.onEvent,
36
+ reply: async (replyText) => {
37
+ resolved = true;
38
+ resolve(replyText);
39
+ },
40
+ };
41
+ this.messageHandler(inbound).catch((err) => {
42
+ if (!resolved) {
43
+ reject(err);
44
+ }
45
+ });
46
+ });
47
+ }
48
+ }
49
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../../src/gateway/channels/webhook.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,MAAM,OAAO,qBAAqB;IAChB,IAAI,GAAG,SAAS,CAAC;IACzB,cAAc,CAA8C;IAC5D,SAAS,GAAY,KAAK,CAAC;IAE5B,WAAW;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,SAAS,CAAC,OAAmD;QAClE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;IAChC,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,oCAAoC,CAAC,CAAC;IAClE,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACxD,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,IAAY,EACZ,OAAO,GAMH,EAAE;QAEN,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7C,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,MAAM,OAAO,GAAmB;gBAC9B,EAAE,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;gBACpE,OAAO,EAAE,SAAS;gBAClB,WAAW,EAAE,SAAS;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,iBAAiB;gBACjD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,UAAU;gBACpC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,UAAU;gBACxC,IAAI;gBACJ,aAAa,EAAE,OAAO,CAAC,OAAO;gBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,KAAK,EAAE,SAAiB,EAAE,EAAE;oBACjC,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,CAAC,SAAS,CAAC,CAAC;gBACrB,CAAC;aACF,CAAC;YAEF,IAAI,CAAC,cAAe,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import { MusondaConfig } from '../config/types.js';
2
+ import { AgentHarness } from '../agent/harness.js';
3
+ import { WebhookChannelAdapter } from './channels/webhook.js';
4
+ import { DiscordChannelAdapter } from './channels/discord.js';
5
+ import { SlackChannelAdapter } from './channels/slack.js';
6
+ import { CliChannelAdapter } from './channels/cli.js';
7
+ import { MusondaScheduler } from '../scheduler/scheduler.js';
8
+ export declare class HttpGatewayServer {
9
+ private server;
10
+ private port;
11
+ private host;
12
+ private startTime;
13
+ private harness;
14
+ private webhookAdapter;
15
+ private discordAdapter;
16
+ private slackAdapter;
17
+ private cliAdapter?;
18
+ private scheduler;
19
+ private config;
20
+ private rateLimits;
21
+ private cleanupInterval;
22
+ constructor(config: MusondaConfig, harness: AgentHarness, webhookAdapter: WebhookChannelAdapter, discordAdapter: DiscordChannelAdapter, slackAdapter: SlackChannelAdapter, scheduler: MusondaScheduler, cliAdapter?: CliChannelAdapter);
23
+ start(): Promise<void>;
24
+ stop(): Promise<void>;
25
+ private parseJsonBody;
26
+ private isOriginAllowed;
27
+ private isAuthenticated;
28
+ private timingSafeEqual;
29
+ private checkRateLimit;
30
+ private checkStorageReadiness;
31
+ private getReadiness;
32
+ private handleRequest;
33
+ }