From 35a0061de957df04ca1200d085ac7f54ee58b355 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Mon, 9 Feb 2026 20:14:23 -0800 Subject: [PATCH] feat(01-02): extract channel adapter registration into src/daemon/channels.ts - Move Telegram, Discord, Slack, WhatsApp, WebChat adapter setup to channels.ts - Move CronScheduler, WebhookHandler, GmailWatcher registration to channels.ts - Clean up index.ts imports (remove unused adapter value imports) - index.ts calls registerChannels() and receives cronScheduler for tool wiring --- src/daemon/channels.ts | 102 +++++++++++++++++++++++++++++++++++++++++ src/daemon/index.ts | 83 ++------------------------------- 2 files changed, 107 insertions(+), 78 deletions(-) create mode 100644 src/daemon/channels.ts diff --git a/src/daemon/channels.ts b/src/daemon/channels.ts new file mode 100644 index 0000000..ee581a2 --- /dev/null +++ b/src/daemon/channels.ts @@ -0,0 +1,102 @@ +import type { Config } from '../config/index.js'; +import type { HookEngine } from '../hooks/index.js'; +import { ChannelRegistry, TelegramAdapter, WebChatAdapter, DiscordAdapter, SlackAdapter, WhatsAppAdapter, PairingManager } from '../channels/index.js'; +import { CronScheduler, WebhookHandler, GmailWatcher } from '../automation/index.js'; +import type { GatewayServer } from '../gateway/index.js'; + +export interface ChannelsDeps { + config: Config; + channelRegistry: ChannelRegistry; + hookEngine: HookEngine; + pairingManager?: PairingManager; + gateway: GatewayServer; +} + +export interface ChannelsResult { + cronScheduler?: CronScheduler; + webhookHandler?: WebhookHandler; + gmailWatcher?: GmailWatcher; +} + +export function registerChannels(deps: ChannelsDeps): ChannelsResult { + const { config, channelRegistry, hookEngine, pairingManager, gateway } = deps; + + // Register Telegram adapter + const telegramAdapter = new TelegramAdapter({ + botToken: config.telegram.bot_token, + allowedChatIds: config.telegram.allowed_chat_ids, + requireMention: config.telegram.require_mention, + hookEngine, + pairingManager, + }); + channelRegistry.register(telegramAdapter); + + // Register Discord adapter (if configured) + if (config.discord) { + const discordAdapter = new DiscordAdapter({ + botToken: config.discord.bot_token, + allowedGuildIds: config.discord.allowed_guild_ids.length > 0 ? config.discord.allowed_guild_ids : undefined, + allowedChannelIds: config.discord.allowed_channel_ids.length > 0 ? config.discord.allowed_channel_ids : undefined, + requireMention: config.discord.require_mention, + pairingManager, + }); + channelRegistry.register(discordAdapter); + } + + // Register Slack adapter (if configured) + if (config.slack) { + const slackAdapter = new SlackAdapter({ + botToken: config.slack.bot_token, + appToken: config.slack.app_token, + signingSecret: config.slack.signing_secret, + allowedChannelIds: config.slack.allowed_channel_ids.length > 0 ? config.slack.allowed_channel_ids : undefined, + requireMention: config.slack.require_mention, + pairingManager, + }); + channelRegistry.register(slackAdapter); + } + + // Register WhatsApp adapter (if configured) + if (config.whatsapp) { + const whatsappAdapter = new WhatsAppAdapter({ + allowedNumbers: config.whatsapp.allowed_numbers.length > 0 ? config.whatsapp.allowed_numbers : undefined, + allowedGroupIds: config.whatsapp.allowed_group_ids.length > 0 ? config.whatsapp.allowed_group_ids : undefined, + requireMention: config.whatsapp.require_mention, + dataDir: config.whatsapp.data_dir, + pairingManager, + }); + channelRegistry.register(whatsappAdapter); + } + + // Register WebChat adapter (wraps the gateway) + const webChatAdapter = new WebChatAdapter({ gateway }); + channelRegistry.register(webChatAdapter); + + // Register cron scheduler adapter (if any cron jobs configured) + let cronScheduler: CronScheduler | undefined; + if (config.automation.cron.length > 0) { + cronScheduler = new CronScheduler(config.automation.cron, channelRegistry); + channelRegistry.register(cronScheduler); + console.log(`Registered ${config.automation.cron.length} cron job(s)`); + } + + // Register webhook handler adapter (if any webhooks configured) + let webhookHandler: WebhookHandler | undefined; + if (config.automation.webhooks.length > 0) { + webhookHandler = new WebhookHandler(config.automation.webhooks, channelRegistry); + channelRegistry.register(webhookHandler); + gateway.setWebhookHandler(webhookHandler); + console.log(`Registered ${config.automation.webhooks.length} webhook(s)`); + } + + // Register Gmail watcher adapter (if configured and enabled) + let gmailWatcher: GmailWatcher | undefined; + if (config.automation.gmail?.enabled) { + gmailWatcher = new GmailWatcher(config.automation.gmail, channelRegistry); + channelRegistry.register(gmailWatcher); + gateway.setGmailHandler(gmailWatcher); + console.log('Registered Gmail watcher'); + } + + return { cronScheduler, webhookHandler, gmailWatcher }; +} diff --git a/src/daemon/index.ts b/src/daemon/index.ts index 9afb07f..445201b 100644 --- a/src/daemon/index.ts +++ b/src/daemon/index.ts @@ -15,8 +15,9 @@ import { HookEngine } from '../hooks/index.js'; import type { ToolRegistry, ToolExecutor, BrowserManager } from '../tools/index.js'; import { createSessionTools, createAgentsListTool, createMessageSendTool, createCronTools } from '../tools/index.js'; import { GatewayServer } from '../gateway/index.js'; -import { ChannelRegistry, TelegramAdapter, WebChatAdapter, DiscordAdapter, SlackAdapter, WhatsAppAdapter, PairingManager } from '../channels/index.js'; -import { CronScheduler, WebhookHandler, HeartbeatMonitor, GmailWatcher } from '../automation/index.js'; +import { ChannelRegistry, PairingManager } from '../channels/index.js'; +import type { CronScheduler } from '../automation/index.js'; +import { HeartbeatMonitor } from '../automation/index.js'; import { McpManager } from '../mcp/index.js'; import { SkillRegistry, SkillInstaller, loadAllSkills } from '../skills/index.js'; import { assembleSystemPrompt } from '../prompt/index.js'; @@ -265,82 +266,8 @@ export async function startDaemon(config: Config): Promise { // Wire channel agents into the getTokenUsage callback (late binding) channelAgents = messageRouter.agents; - // Register Telegram adapter - const telegramAdapter = new TelegramAdapter({ - botToken: config.telegram.bot_token, - allowedChatIds: config.telegram.allowed_chat_ids, - requireMention: config.telegram.require_mention, - hookEngine, - pairingManager, - }); - channelRegistry.register(telegramAdapter); - - // Register Discord adapter (if configured) - if (config.discord) { - const discordAdapter = new DiscordAdapter({ - botToken: config.discord.bot_token, - allowedGuildIds: config.discord.allowed_guild_ids.length > 0 ? config.discord.allowed_guild_ids : undefined, - allowedChannelIds: config.discord.allowed_channel_ids.length > 0 ? config.discord.allowed_channel_ids : undefined, - requireMention: config.discord.require_mention, - pairingManager, - }); - channelRegistry.register(discordAdapter); - } - - // Register Slack adapter (if configured) - if (config.slack) { - const slackAdapter = new SlackAdapter({ - botToken: config.slack.bot_token, - appToken: config.slack.app_token, - signingSecret: config.slack.signing_secret, - allowedChannelIds: config.slack.allowed_channel_ids.length > 0 ? config.slack.allowed_channel_ids : undefined, - requireMention: config.slack.require_mention, - pairingManager, - }); - channelRegistry.register(slackAdapter); - } - - // Register WhatsApp adapter (if configured) - if (config.whatsapp) { - const whatsappAdapter = new WhatsAppAdapter({ - allowedNumbers: config.whatsapp.allowed_numbers.length > 0 ? config.whatsapp.allowed_numbers : undefined, - allowedGroupIds: config.whatsapp.allowed_group_ids.length > 0 ? config.whatsapp.allowed_group_ids : undefined, - requireMention: config.whatsapp.require_mention, - dataDir: config.whatsapp.data_dir, - pairingManager, - }); - channelRegistry.register(whatsappAdapter); - } - - // Register WebChat adapter (wraps the gateway) - const webChatAdapter = new WebChatAdapter({ gateway }); - channelRegistry.register(webChatAdapter); - - // Register cron scheduler adapter (if any cron jobs configured) - let cronScheduler: CronScheduler | undefined; - if (config.automation.cron.length > 0) { - cronScheduler = new CronScheduler(config.automation.cron, channelRegistry); - channelRegistry.register(cronScheduler); - console.log(`Registered ${config.automation.cron.length} cron job(s)`); - } - - // Register webhook handler adapter (if any webhooks configured) - let webhookHandler: WebhookHandler | undefined; - if (config.automation.webhooks.length > 0) { - webhookHandler = new WebhookHandler(config.automation.webhooks, channelRegistry); - channelRegistry.register(webhookHandler); - gateway.setWebhookHandler(webhookHandler); - console.log(`Registered ${config.automation.webhooks.length} webhook(s)`); - } - - // Register Gmail watcher adapter (if configured and enabled) - let gmailWatcher: GmailWatcher | undefined; - if (config.automation.gmail?.enabled) { - gmailWatcher = new GmailWatcher(config.automation.gmail, channelRegistry); - channelRegistry.register(gmailWatcher); - gateway.setGmailHandler(gmailWatcher); - console.log('Registered Gmail watcher'); - } + // Register all channel adapters (Telegram, Discord, Slack, WhatsApp, WebChat, cron, webhooks, Gmail) + const { cronScheduler } = registerChannels({ config, channelRegistry, hookEngine, pairingManager, gateway }); // ── Register Tier 1 agent tools ─────────────────────────────