daemora 1.0.1 → 1.0.3
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/README.md +106 -76
- package/SOUL.md +100 -28
- package/config/mcp.json +9 -9
- package/package.json +15 -8
- package/skills/apple-notes.md +0 -52
- package/skills/apple-reminders.md +1 -87
- package/skills/camsnap.md +20 -144
- package/skills/coding.md +7 -7
- package/skills/documents.md +6 -6
- package/skills/email.md +6 -6
- package/skills/gif-search.md +28 -171
- package/skills/healthcheck.md +21 -203
- package/skills/image-gen.md +24 -123
- package/skills/model-usage.md +18 -165
- package/skills/obsidian.md +28 -174
- package/skills/pdf.md +30 -181
- package/skills/research.md +6 -6
- package/skills/skill-creator.md +35 -111
- package/skills/spotify.md +2 -17
- package/skills/summarize.md +36 -193
- package/skills/things.md +23 -175
- package/skills/tmux.md +1 -91
- package/skills/trello.md +32 -157
- package/skills/video-frames.md +26 -166
- package/skills/weather.md +6 -6
- package/src/a2a/A2AClient.js +2 -2
- package/src/a2a/A2AServer.js +6 -6
- package/src/a2a/AgentCard.js +2 -2
- package/src/agents/SubAgentManager.js +61 -19
- package/src/agents/Supervisor.js +4 -4
- package/src/channels/BaseChannel.js +6 -6
- package/src/channels/BlueBubblesChannel.js +112 -0
- package/src/channels/DiscordChannel.js +8 -8
- package/src/channels/EmailChannel.js +54 -26
- package/src/channels/FeishuChannel.js +140 -0
- package/src/channels/GoogleChatChannel.js +8 -8
- package/src/channels/HttpChannel.js +2 -2
- package/src/channels/IRCChannel.js +144 -0
- package/src/channels/LineChannel.js +13 -13
- package/src/channels/MatrixChannel.js +97 -0
- package/src/channels/MattermostChannel.js +119 -0
- package/src/channels/NextcloudChannel.js +133 -0
- package/src/channels/NostrChannel.js +175 -0
- package/src/channels/SignalChannel.js +9 -9
- package/src/channels/SlackChannel.js +10 -10
- package/src/channels/TeamsChannel.js +10 -10
- package/src/channels/TelegramChannel.js +8 -8
- package/src/channels/TwitchChannel.js +128 -0
- package/src/channels/WhatsAppChannel.js +10 -10
- package/src/channels/ZaloChannel.js +119 -0
- package/src/channels/iMessageChannel.js +150 -0
- package/src/channels/index.js +241 -11
- package/src/cli.js +835 -38
- package/src/config/agentProfiles.js +19 -19
- package/src/config/channels.js +1 -1
- package/src/config/default.js +12 -7
- package/src/config/models.js +3 -3
- package/src/config/permissions.js +2 -2
- package/src/core/AgentLoop.js +13 -13
- package/src/core/Compaction.js +3 -3
- package/src/core/CostTracker.js +2 -2
- package/src/core/EventBus.js +15 -15
- package/src/core/TaskQueue.js +24 -7
- package/src/core/TaskRunner.js +19 -6
- package/src/daemon/DaemonManager.js +4 -4
- package/src/hooks/HookRunner.js +4 -4
- package/src/index.js +6 -2
- package/src/mcp/MCPAgentRunner.js +3 -3
- package/src/mcp/MCPClient.js +9 -9
- package/src/mcp/MCPManager.js +14 -14
- package/src/models/ModelRouter.js +2 -2
- package/src/safety/AuditLog.js +3 -3
- package/src/safety/CircuitBreaker.js +2 -2
- package/src/safety/CommandGuard.js +132 -0
- package/src/safety/FilesystemGuard.js +23 -3
- package/src/safety/GitRollback.js +5 -5
- package/src/safety/HumanApproval.js +9 -9
- package/src/safety/InputSanitizer.js +81 -8
- package/src/safety/PermissionGuard.js +2 -2
- package/src/safety/Sandbox.js +1 -1
- package/src/safety/SecretScanner.js +90 -28
- package/src/safety/SecretVault.js +2 -2
- package/src/scheduler/Heartbeat.js +3 -3
- package/src/scheduler/Scheduler.js +6 -6
- package/src/setup/theme.js +171 -66
- package/src/setup/wizard.js +432 -57
- package/src/skills/SkillLoader.js +145 -8
- package/src/storage/TaskStore.js +39 -15
- package/src/systemPrompt.js +45 -43
- package/src/tenants/TenantManager.js +79 -22
- package/src/tools/ToolRegistry.js +3 -3
- package/src/tools/applyPatch.js +2 -2
- package/src/tools/browserAutomation.js +4 -4
- package/src/tools/calendar.js +155 -0
- package/src/tools/clipboard.js +71 -0
- package/src/tools/contacts.js +138 -0
- package/src/tools/createDocument.js +2 -2
- package/src/tools/cronTool.js +14 -14
- package/src/tools/database.js +165 -0
- package/src/tools/editFile.js +10 -10
- package/src/tools/executeCommand.js +11 -3
- package/src/tools/generateImage.js +79 -0
- package/src/tools/gitTool.js +141 -0
- package/src/tools/glob.js +1 -1
- package/src/tools/googlePlaces.js +136 -0
- package/src/tools/grep.js +2 -2
- package/src/tools/iMessageTool.js +86 -0
- package/src/tools/imageAnalysis.js +3 -3
- package/src/tools/index.js +56 -2
- package/src/tools/makeVoiceCall.js +283 -0
- package/src/tools/manageAgents.js +2 -2
- package/src/tools/manageMCP.js +38 -20
- package/src/tools/memory.js +25 -32
- package/src/tools/messageChannel.js +1 -1
- package/src/tools/notification.js +90 -0
- package/src/tools/philipsHue.js +147 -0
- package/src/tools/projectTracker.js +8 -8
- package/src/tools/readFile.js +1 -1
- package/src/tools/readPDF.js +73 -0
- package/src/tools/screenCapture.js +6 -6
- package/src/tools/searchContent.js +2 -2
- package/src/tools/searchFiles.js +1 -1
- package/src/tools/sendEmail.js +79 -24
- package/src/tools/sendFile.js +4 -4
- package/src/tools/sonos.js +137 -0
- package/src/tools/sshTool.js +130 -0
- package/src/tools/textToSpeech.js +5 -5
- package/src/tools/transcribeAudio.js +4 -4
- package/src/tools/useMCP.js +4 -4
- package/src/tools/webFetch.js +2 -2
- package/src/tools/webSearch.js +1 -1
- package/src/utils/Embeddings.js +79 -0
- package/src/voice/VoiceSessionManager.js +170 -0
- package/src/voice/VoiceWebhook.js +188 -0
package/src/channels/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
// HTTP channel is intentionally commented out
|
|
1
|
+
// HTTP channel is intentionally commented out - it has no authentication.
|
|
2
2
|
// Anyone on the network could send arbitrary tasks to the agent.
|
|
3
3
|
// Uncomment only if you've added your own auth middleware.
|
|
4
4
|
// import { HttpChannel } from "./HttpChannel.js";
|
|
5
5
|
|
|
6
|
+
// ─── Core channels ─────────────────────────────────────────────────────────────
|
|
6
7
|
import { TelegramChannel } from "./TelegramChannel.js";
|
|
7
8
|
import { WhatsAppChannel } from "./WhatsAppChannel.js";
|
|
8
9
|
import { EmailChannel } from "./EmailChannel.js";
|
|
@@ -12,10 +13,24 @@ import { LineChannel } from "./LineChannel.js";
|
|
|
12
13
|
import { SignalChannel } from "./SignalChannel.js";
|
|
13
14
|
import { TeamsChannel } from "./TeamsChannel.js";
|
|
14
15
|
import { GoogleChatChannel } from "./GoogleChatChannel.js";
|
|
16
|
+
|
|
17
|
+
// ─── Phase 24 channels ─────────────────────────────────────────────────────────
|
|
18
|
+
import { MatrixChannel } from "./MatrixChannel.js";
|
|
19
|
+
import { MattermostChannel } from "./MattermostChannel.js";
|
|
20
|
+
import { TwitchChannel } from "./TwitchChannel.js";
|
|
21
|
+
import { IRCChannel } from "./IRCChannel.js";
|
|
22
|
+
import { iMessageChannel } from "./iMessageChannel.js";
|
|
23
|
+
import { FeishuChannel } from "./FeishuChannel.js";
|
|
24
|
+
import { ZaloChannel } from "./ZaloChannel.js";
|
|
25
|
+
import { NextcloudChannel } from "./NextcloudChannel.js";
|
|
26
|
+
import { BlueBubblesChannel } from "./BlueBubblesChannel.js";
|
|
27
|
+
import { NostrChannel } from "./NostrChannel.js";
|
|
28
|
+
|
|
15
29
|
import { config } from "../config/default.js";
|
|
30
|
+
import eventBus from "../core/EventBus.js";
|
|
16
31
|
|
|
17
32
|
/**
|
|
18
|
-
* Channel Registry
|
|
33
|
+
* Channel Registry - manages all input channels.
|
|
19
34
|
* Each channel auto-starts if its credentials are configured.
|
|
20
35
|
*/
|
|
21
36
|
class ChannelRegistry {
|
|
@@ -33,7 +48,9 @@ class ChannelRegistry {
|
|
|
33
48
|
// await http.start();
|
|
34
49
|
// ─────────────────────────────────────────────────────────────────────────
|
|
35
50
|
|
|
36
|
-
//
|
|
51
|
+
// ── Core channels ─────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
// Telegram
|
|
37
54
|
const telegramToken = process.env.TELEGRAM_BOT_TOKEN;
|
|
38
55
|
if (telegramToken) {
|
|
39
56
|
try {
|
|
@@ -45,7 +62,7 @@ class ChannelRegistry {
|
|
|
45
62
|
}
|
|
46
63
|
}
|
|
47
64
|
|
|
48
|
-
// WhatsApp
|
|
65
|
+
// WhatsApp
|
|
49
66
|
const twilioSid = process.env.TWILIO_ACCOUNT_SID;
|
|
50
67
|
if (twilioSid) {
|
|
51
68
|
const whatsapp = new WhatsAppChannel({
|
|
@@ -59,7 +76,7 @@ class ChannelRegistry {
|
|
|
59
76
|
await whatsapp.start();
|
|
60
77
|
}
|
|
61
78
|
|
|
62
|
-
// Email
|
|
79
|
+
// Email
|
|
63
80
|
const emailUser = process.env.EMAIL_USER;
|
|
64
81
|
if (emailUser) {
|
|
65
82
|
const email = new EmailChannel({
|
|
@@ -72,7 +89,7 @@ class ChannelRegistry {
|
|
|
72
89
|
await email.start();
|
|
73
90
|
}
|
|
74
91
|
|
|
75
|
-
// Discord
|
|
92
|
+
// Discord
|
|
76
93
|
const discordToken = process.env.DISCORD_BOT_TOKEN;
|
|
77
94
|
if (discordToken) {
|
|
78
95
|
try {
|
|
@@ -84,7 +101,7 @@ class ChannelRegistry {
|
|
|
84
101
|
}
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
// Slack
|
|
104
|
+
// Slack
|
|
88
105
|
const slackBotToken = process.env.SLACK_BOT_TOKEN;
|
|
89
106
|
const slackAppToken = process.env.SLACK_APP_TOKEN;
|
|
90
107
|
if (slackBotToken && slackAppToken) {
|
|
@@ -97,7 +114,7 @@ class ChannelRegistry {
|
|
|
97
114
|
}
|
|
98
115
|
}
|
|
99
116
|
|
|
100
|
-
// LINE
|
|
117
|
+
// LINE
|
|
101
118
|
const lineAccessToken = process.env.LINE_CHANNEL_ACCESS_TOKEN;
|
|
102
119
|
const lineSecret = process.env.LINE_CHANNEL_SECRET;
|
|
103
120
|
if (lineAccessToken && lineSecret) {
|
|
@@ -110,7 +127,7 @@ class ChannelRegistry {
|
|
|
110
127
|
}
|
|
111
128
|
}
|
|
112
129
|
|
|
113
|
-
// Signal
|
|
130
|
+
// Signal
|
|
114
131
|
const signalCliUrl = process.env.SIGNAL_CLI_URL;
|
|
115
132
|
const signalPhone = process.env.SIGNAL_PHONE_NUMBER;
|
|
116
133
|
if (signalCliUrl && signalPhone) {
|
|
@@ -123,7 +140,7 @@ class ChannelRegistry {
|
|
|
123
140
|
}
|
|
124
141
|
}
|
|
125
142
|
|
|
126
|
-
// Microsoft Teams
|
|
143
|
+
// Microsoft Teams
|
|
127
144
|
const teamsAppId = process.env.TEAMS_APP_ID;
|
|
128
145
|
const teamsAppPwd = process.env.TEAMS_APP_PASSWORD;
|
|
129
146
|
if (teamsAppId && teamsAppPwd) {
|
|
@@ -140,7 +157,7 @@ class ChannelRegistry {
|
|
|
140
157
|
}
|
|
141
158
|
}
|
|
142
159
|
|
|
143
|
-
// Google Chat
|
|
160
|
+
// Google Chat
|
|
144
161
|
const googleServiceAccount = process.env.GOOGLE_CHAT_SERVICE_ACCOUNT;
|
|
145
162
|
if (googleServiceAccount) {
|
|
146
163
|
try {
|
|
@@ -156,10 +173,195 @@ class ChannelRegistry {
|
|
|
156
173
|
}
|
|
157
174
|
}
|
|
158
175
|
|
|
176
|
+
// ── Phase 24 channels ──────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
// Matrix
|
|
179
|
+
const matrixHomeserver = process.env.MATRIX_HOMESERVER_URL;
|
|
180
|
+
const matrixToken = process.env.MATRIX_ACCESS_TOKEN;
|
|
181
|
+
if (matrixHomeserver && matrixToken) {
|
|
182
|
+
try {
|
|
183
|
+
const matrix = new MatrixChannel({
|
|
184
|
+
homeserverUrl: matrixHomeserver,
|
|
185
|
+
accessToken: matrixToken,
|
|
186
|
+
botUserId: process.env.MATRIX_BOT_USER_ID,
|
|
187
|
+
});
|
|
188
|
+
this.channels.set("matrix", matrix);
|
|
189
|
+
await matrix.start();
|
|
190
|
+
} catch (e) {
|
|
191
|
+
console.log(`[Channel:Matrix] Failed to start: ${e.message}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Mattermost
|
|
196
|
+
const mmUrl = process.env.MATTERMOST_URL;
|
|
197
|
+
const mmToken = process.env.MATTERMOST_TOKEN;
|
|
198
|
+
if (mmUrl && mmToken) {
|
|
199
|
+
try {
|
|
200
|
+
const mattermost = new MattermostChannel({
|
|
201
|
+
url: mmUrl,
|
|
202
|
+
token: mmToken,
|
|
203
|
+
botUserId: process.env.MATTERMOST_BOT_USER_ID,
|
|
204
|
+
botUsername: process.env.MATTERMOST_BOT_USERNAME,
|
|
205
|
+
});
|
|
206
|
+
this.channels.set("mattermost", mattermost);
|
|
207
|
+
await mattermost.start();
|
|
208
|
+
} catch (e) {
|
|
209
|
+
console.log(`[Channel:Mattermost] Failed to start: ${e.message}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Twitch
|
|
214
|
+
const twitchUser = process.env.TWITCH_BOT_USERNAME;
|
|
215
|
+
const twitchToken = process.env.TWITCH_OAUTH_TOKEN;
|
|
216
|
+
const twitchChannel = process.env.TWITCH_CHANNEL;
|
|
217
|
+
if (twitchUser && twitchToken && twitchChannel) {
|
|
218
|
+
try {
|
|
219
|
+
const twitch = new TwitchChannel({
|
|
220
|
+
username: twitchUser,
|
|
221
|
+
token: twitchToken,
|
|
222
|
+
channel: twitchChannel,
|
|
223
|
+
prefix: process.env.TWITCH_COMMAND_PREFIX || "!ask",
|
|
224
|
+
});
|
|
225
|
+
this.channels.set("twitch", twitch);
|
|
226
|
+
await twitch.start();
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.log(`[Channel:Twitch] Failed to start: ${e.message}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// IRC
|
|
233
|
+
const ircServer = process.env.IRC_SERVER;
|
|
234
|
+
const ircNick = process.env.IRC_NICK;
|
|
235
|
+
if (ircServer && ircNick) {
|
|
236
|
+
try {
|
|
237
|
+
const irc = new IRCChannel({
|
|
238
|
+
server: ircServer,
|
|
239
|
+
nick: ircNick,
|
|
240
|
+
port: parseInt(process.env.IRC_PORT || "6667"),
|
|
241
|
+
channel: process.env.IRC_CHANNEL,
|
|
242
|
+
password: process.env.IRC_PASSWORD,
|
|
243
|
+
});
|
|
244
|
+
this.channels.set("irc", irc);
|
|
245
|
+
await irc.start();
|
|
246
|
+
} catch (e) {
|
|
247
|
+
console.log(`[Channel:IRC] Failed to start: ${e.message}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// iMessage (macOS only)
|
|
252
|
+
if (process.platform === "darwin" && process.env.IMESSAGE_ENABLED === "true") {
|
|
253
|
+
try {
|
|
254
|
+
const imessage = new iMessageChannel({
|
|
255
|
+
pollIntervalMs: parseInt(process.env.IMESSAGE_POLL_INTERVAL_MS || "5000"),
|
|
256
|
+
});
|
|
257
|
+
this.channels.set("imessage", imessage);
|
|
258
|
+
await imessage.start();
|
|
259
|
+
} catch (e) {
|
|
260
|
+
console.log(`[Channel:iMessage] Failed to start: ${e.message}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Feishu / Lark
|
|
265
|
+
const feishuAppId = process.env.FEISHU_APP_ID;
|
|
266
|
+
const feishuSecret = process.env.FEISHU_APP_SECRET;
|
|
267
|
+
if (feishuAppId && feishuSecret) {
|
|
268
|
+
try {
|
|
269
|
+
const feishu = new FeishuChannel({
|
|
270
|
+
appId: feishuAppId,
|
|
271
|
+
appSecret: feishuSecret,
|
|
272
|
+
verificationToken: process.env.FEISHU_VERIFICATION_TOKEN,
|
|
273
|
+
port: parseInt(process.env.FEISHU_PORT || "3004"),
|
|
274
|
+
});
|
|
275
|
+
this.channels.set("feishu", feishu);
|
|
276
|
+
await feishu.start();
|
|
277
|
+
} catch (e) {
|
|
278
|
+
console.log(`[Channel:Feishu] Failed to start: ${e.message}`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Zalo
|
|
283
|
+
const zaloAppId = process.env.ZALO_APP_ID;
|
|
284
|
+
const zaloToken = process.env.ZALO_ACCESS_TOKEN;
|
|
285
|
+
if (zaloAppId && zaloToken) {
|
|
286
|
+
try {
|
|
287
|
+
const zalo = new ZaloChannel({
|
|
288
|
+
appId: zaloAppId,
|
|
289
|
+
appSecret: process.env.ZALO_APP_SECRET,
|
|
290
|
+
accessToken: zaloToken,
|
|
291
|
+
port: parseInt(process.env.ZALO_PORT || "3005"),
|
|
292
|
+
});
|
|
293
|
+
this.channels.set("zalo", zalo);
|
|
294
|
+
await zalo.start();
|
|
295
|
+
} catch (e) {
|
|
296
|
+
console.log(`[Channel:Zalo] Failed to start: ${e.message}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Nextcloud Talk
|
|
301
|
+
const nextcloudUrl = process.env.NEXTCLOUD_URL;
|
|
302
|
+
const nextcloudUser = process.env.NEXTCLOUD_USER;
|
|
303
|
+
const nextcloudPass = process.env.NEXTCLOUD_PASSWORD;
|
|
304
|
+
if (nextcloudUrl && nextcloudUser && nextcloudPass) {
|
|
305
|
+
try {
|
|
306
|
+
const nextcloud = new NextcloudChannel({
|
|
307
|
+
url: nextcloudUrl,
|
|
308
|
+
user: nextcloudUser,
|
|
309
|
+
password: nextcloudPass,
|
|
310
|
+
roomToken: process.env.NEXTCLOUD_ROOM_TOKEN,
|
|
311
|
+
});
|
|
312
|
+
this.channels.set("nextcloud", nextcloud);
|
|
313
|
+
await nextcloud.start();
|
|
314
|
+
} catch (e) {
|
|
315
|
+
console.log(`[Channel:Nextcloud] Failed to start: ${e.message}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// BlueBubbles
|
|
320
|
+
const bbUrl = process.env.BLUEBUBBLES_URL;
|
|
321
|
+
const bbPassword = process.env.BLUEBUBBLES_PASSWORD;
|
|
322
|
+
if (bbUrl && bbPassword) {
|
|
323
|
+
try {
|
|
324
|
+
const bb = new BlueBubblesChannel({ url: bbUrl, password: bbPassword });
|
|
325
|
+
this.channels.set("bluebubbles", bb);
|
|
326
|
+
await bb.start();
|
|
327
|
+
} catch (e) {
|
|
328
|
+
console.log(`[Channel:BlueBubbles] Failed to start: ${e.message}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Nostr
|
|
333
|
+
const nostrKey = process.env.NOSTR_PRIVATE_KEY;
|
|
334
|
+
if (nostrKey) {
|
|
335
|
+
try {
|
|
336
|
+
const relays = (process.env.NOSTR_RELAYS || "wss://relay.damus.io,wss://nos.lol").split(",").map(r => r.trim());
|
|
337
|
+
const nostr = new NostrChannel({ privateKey: nostrKey, relays });
|
|
338
|
+
this.channels.set("nostr", nostr);
|
|
339
|
+
await nostr.start();
|
|
340
|
+
} catch (e) {
|
|
341
|
+
console.log(`[Channel:Nostr] Failed to start: ${e.message}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
159
345
|
const active = [...this.channels.entries()]
|
|
160
346
|
.filter(([_, ch]) => ch.running)
|
|
161
347
|
.map(([name]) => name);
|
|
162
348
|
console.log(`[ChannelRegistry] Active channels: ${active.join(", ") || "none"}`);
|
|
349
|
+
|
|
350
|
+
// Recovery reply handler
|
|
351
|
+
eventBus.on("task:reply:needed", async ({ task }) => {
|
|
352
|
+
const channel = this.channels.get(task.channel);
|
|
353
|
+
if (!channel?.running) {
|
|
354
|
+
console.log(`[ChannelRegistry] Cannot send recovered reply — channel "${task.channel}" not running`);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
const reply = task.result || "(Task completed — no output)";
|
|
359
|
+
await channel.sendReply(task.channelMeta, reply);
|
|
360
|
+
console.log(`[ChannelRegistry] Recovered reply sent via ${task.channel} for task ${task.id}`);
|
|
361
|
+
} catch (e) {
|
|
362
|
+
console.log(`[ChannelRegistry] Failed to send recovered reply for task ${task.id}: ${e.message}`);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
163
365
|
}
|
|
164
366
|
|
|
165
367
|
/**
|
|
@@ -192,7 +394,35 @@ class ChannelRegistry {
|
|
|
192
394
|
running: ch.running,
|
|
193
395
|
}));
|
|
194
396
|
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Returns all supported channel names (including unconfigured ones).
|
|
400
|
+
*/
|
|
401
|
+
static getSupportedChannels() {
|
|
402
|
+
return [
|
|
403
|
+
{ name: "telegram", env: "TELEGRAM_BOT_TOKEN", desc: "Telegram bot" },
|
|
404
|
+
{ name: "whatsapp", env: "TWILIO_ACCOUNT_SID + TWILIO_AUTH_TOKEN", desc: "WhatsApp via Twilio" },
|
|
405
|
+
{ name: "discord", env: "DISCORD_BOT_TOKEN", desc: "Discord bot" },
|
|
406
|
+
{ name: "slack", env: "SLACK_BOT_TOKEN + SLACK_APP_TOKEN", desc: "Slack Socket Mode bot" },
|
|
407
|
+
{ name: "email", env: "EMAIL_USER + EMAIL_PASSWORD", desc: "Email (IMAP/SMTP)" },
|
|
408
|
+
{ name: "line", env: "LINE_CHANNEL_ACCESS_TOKEN + LINE_CHANNEL_SECRET", desc: "LINE messaging" },
|
|
409
|
+
{ name: "signal", env: "SIGNAL_CLI_URL + SIGNAL_PHONE_NUMBER", desc: "Signal via signal-cli" },
|
|
410
|
+
{ name: "teams", env: "TEAMS_APP_ID + TEAMS_APP_PASSWORD", desc: "Microsoft Teams Bot Framework" },
|
|
411
|
+
{ name: "googlechat", env: "GOOGLE_CHAT_SERVICE_ACCOUNT", desc: "Google Chat service account" },
|
|
412
|
+
{ name: "matrix", env: "MATRIX_HOMESERVER_URL + MATRIX_ACCESS_TOKEN", desc: "Matrix (Element) protocol" },
|
|
413
|
+
{ name: "mattermost", env: "MATTERMOST_URL + MATTERMOST_TOKEN", desc: "Mattermost WebSocket bot" },
|
|
414
|
+
{ name: "twitch", env: "TWITCH_BOT_USERNAME + TWITCH_OAUTH_TOKEN + TWITCH_CHANNEL", desc: "Twitch chat commands" },
|
|
415
|
+
{ name: "irc", env: "IRC_SERVER + IRC_NICK", desc: "IRC (any server)" },
|
|
416
|
+
{ name: "imessage", env: "IMESSAGE_ENABLED=true (macOS only)", desc: "iMessage via AppleScript" },
|
|
417
|
+
{ name: "feishu", env: "FEISHU_APP_ID + FEISHU_APP_SECRET", desc: "Feishu / Lark" },
|
|
418
|
+
{ name: "zalo", env: "ZALO_APP_ID + ZALO_ACCESS_TOKEN", desc: "Zalo (Vietnam)" },
|
|
419
|
+
{ name: "nextcloud", env: "NEXTCLOUD_URL + NEXTCLOUD_USER + NEXTCLOUD_PASSWORD", desc: "Nextcloud Talk" },
|
|
420
|
+
{ name: "bluebubbles", env: "BLUEBUBBLES_URL + BLUEBUBBLES_PASSWORD", desc: "BlueBubbles iMessage relay" },
|
|
421
|
+
{ name: "nostr", env: "NOSTR_PRIVATE_KEY", desc: "Nostr decentralized protocol" },
|
|
422
|
+
];
|
|
423
|
+
}
|
|
195
424
|
}
|
|
196
425
|
|
|
197
426
|
const channelRegistry = new ChannelRegistry();
|
|
198
427
|
export default channelRegistry;
|
|
428
|
+
export { ChannelRegistry };
|