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.
Files changed (134) hide show
  1. package/README.md +106 -76
  2. package/SOUL.md +100 -28
  3. package/config/mcp.json +9 -9
  4. package/package.json +15 -8
  5. package/skills/apple-notes.md +0 -52
  6. package/skills/apple-reminders.md +1 -87
  7. package/skills/camsnap.md +20 -144
  8. package/skills/coding.md +7 -7
  9. package/skills/documents.md +6 -6
  10. package/skills/email.md +6 -6
  11. package/skills/gif-search.md +28 -171
  12. package/skills/healthcheck.md +21 -203
  13. package/skills/image-gen.md +24 -123
  14. package/skills/model-usage.md +18 -165
  15. package/skills/obsidian.md +28 -174
  16. package/skills/pdf.md +30 -181
  17. package/skills/research.md +6 -6
  18. package/skills/skill-creator.md +35 -111
  19. package/skills/spotify.md +2 -17
  20. package/skills/summarize.md +36 -193
  21. package/skills/things.md +23 -175
  22. package/skills/tmux.md +1 -91
  23. package/skills/trello.md +32 -157
  24. package/skills/video-frames.md +26 -166
  25. package/skills/weather.md +6 -6
  26. package/src/a2a/A2AClient.js +2 -2
  27. package/src/a2a/A2AServer.js +6 -6
  28. package/src/a2a/AgentCard.js +2 -2
  29. package/src/agents/SubAgentManager.js +61 -19
  30. package/src/agents/Supervisor.js +4 -4
  31. package/src/channels/BaseChannel.js +6 -6
  32. package/src/channels/BlueBubblesChannel.js +112 -0
  33. package/src/channels/DiscordChannel.js +8 -8
  34. package/src/channels/EmailChannel.js +54 -26
  35. package/src/channels/FeishuChannel.js +140 -0
  36. package/src/channels/GoogleChatChannel.js +8 -8
  37. package/src/channels/HttpChannel.js +2 -2
  38. package/src/channels/IRCChannel.js +144 -0
  39. package/src/channels/LineChannel.js +13 -13
  40. package/src/channels/MatrixChannel.js +97 -0
  41. package/src/channels/MattermostChannel.js +119 -0
  42. package/src/channels/NextcloudChannel.js +133 -0
  43. package/src/channels/NostrChannel.js +175 -0
  44. package/src/channels/SignalChannel.js +9 -9
  45. package/src/channels/SlackChannel.js +10 -10
  46. package/src/channels/TeamsChannel.js +10 -10
  47. package/src/channels/TelegramChannel.js +8 -8
  48. package/src/channels/TwitchChannel.js +128 -0
  49. package/src/channels/WhatsAppChannel.js +10 -10
  50. package/src/channels/ZaloChannel.js +119 -0
  51. package/src/channels/iMessageChannel.js +150 -0
  52. package/src/channels/index.js +241 -11
  53. package/src/cli.js +835 -38
  54. package/src/config/agentProfiles.js +19 -19
  55. package/src/config/channels.js +1 -1
  56. package/src/config/default.js +12 -7
  57. package/src/config/models.js +3 -3
  58. package/src/config/permissions.js +2 -2
  59. package/src/core/AgentLoop.js +13 -13
  60. package/src/core/Compaction.js +3 -3
  61. package/src/core/CostTracker.js +2 -2
  62. package/src/core/EventBus.js +15 -15
  63. package/src/core/TaskQueue.js +24 -7
  64. package/src/core/TaskRunner.js +19 -6
  65. package/src/daemon/DaemonManager.js +4 -4
  66. package/src/hooks/HookRunner.js +4 -4
  67. package/src/index.js +6 -2
  68. package/src/mcp/MCPAgentRunner.js +3 -3
  69. package/src/mcp/MCPClient.js +9 -9
  70. package/src/mcp/MCPManager.js +14 -14
  71. package/src/models/ModelRouter.js +2 -2
  72. package/src/safety/AuditLog.js +3 -3
  73. package/src/safety/CircuitBreaker.js +2 -2
  74. package/src/safety/CommandGuard.js +132 -0
  75. package/src/safety/FilesystemGuard.js +23 -3
  76. package/src/safety/GitRollback.js +5 -5
  77. package/src/safety/HumanApproval.js +9 -9
  78. package/src/safety/InputSanitizer.js +81 -8
  79. package/src/safety/PermissionGuard.js +2 -2
  80. package/src/safety/Sandbox.js +1 -1
  81. package/src/safety/SecretScanner.js +90 -28
  82. package/src/safety/SecretVault.js +2 -2
  83. package/src/scheduler/Heartbeat.js +3 -3
  84. package/src/scheduler/Scheduler.js +6 -6
  85. package/src/setup/theme.js +171 -66
  86. package/src/setup/wizard.js +432 -57
  87. package/src/skills/SkillLoader.js +145 -8
  88. package/src/storage/TaskStore.js +39 -15
  89. package/src/systemPrompt.js +45 -43
  90. package/src/tenants/TenantManager.js +79 -22
  91. package/src/tools/ToolRegistry.js +3 -3
  92. package/src/tools/applyPatch.js +2 -2
  93. package/src/tools/browserAutomation.js +4 -4
  94. package/src/tools/calendar.js +155 -0
  95. package/src/tools/clipboard.js +71 -0
  96. package/src/tools/contacts.js +138 -0
  97. package/src/tools/createDocument.js +2 -2
  98. package/src/tools/cronTool.js +14 -14
  99. package/src/tools/database.js +165 -0
  100. package/src/tools/editFile.js +10 -10
  101. package/src/tools/executeCommand.js +11 -3
  102. package/src/tools/generateImage.js +79 -0
  103. package/src/tools/gitTool.js +141 -0
  104. package/src/tools/glob.js +1 -1
  105. package/src/tools/googlePlaces.js +136 -0
  106. package/src/tools/grep.js +2 -2
  107. package/src/tools/iMessageTool.js +86 -0
  108. package/src/tools/imageAnalysis.js +3 -3
  109. package/src/tools/index.js +56 -2
  110. package/src/tools/makeVoiceCall.js +283 -0
  111. package/src/tools/manageAgents.js +2 -2
  112. package/src/tools/manageMCP.js +38 -20
  113. package/src/tools/memory.js +25 -32
  114. package/src/tools/messageChannel.js +1 -1
  115. package/src/tools/notification.js +90 -0
  116. package/src/tools/philipsHue.js +147 -0
  117. package/src/tools/projectTracker.js +8 -8
  118. package/src/tools/readFile.js +1 -1
  119. package/src/tools/readPDF.js +73 -0
  120. package/src/tools/screenCapture.js +6 -6
  121. package/src/tools/searchContent.js +2 -2
  122. package/src/tools/searchFiles.js +1 -1
  123. package/src/tools/sendEmail.js +79 -24
  124. package/src/tools/sendFile.js +4 -4
  125. package/src/tools/sonos.js +137 -0
  126. package/src/tools/sshTool.js +130 -0
  127. package/src/tools/textToSpeech.js +5 -5
  128. package/src/tools/transcribeAudio.js +4 -4
  129. package/src/tools/useMCP.js +4 -4
  130. package/src/tools/webFetch.js +2 -2
  131. package/src/tools/webSearch.js +1 -1
  132. package/src/utils/Embeddings.js +79 -0
  133. package/src/voice/VoiceSessionManager.js +170 -0
  134. package/src/voice/VoiceWebhook.js +188 -0
@@ -1,8 +1,9 @@
1
- // HTTP channel is intentionally commented out it has no authentication.
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 manages all input channels.
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
- // Telegram check process.env directly (vault may have loaded token after config init)
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 — check process.env directly
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 — check process.env directly
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 — check process.env directly
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 — requires both bot token and app token (Socket Mode)
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 — webhook-based, needs access token + channel secret
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 — requires signal-cli running as REST daemon
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 — Bot Framework v4
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 — service account + Chat API webhook
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 };