feat: add Docker support and inbound webhooks (Tier 2)
- Dockerfile: multi-stage build (node:22-alpine), better-sqlite3 native deps handled
- .dockerignore + docker-compose.yml for deployment
- FLYNN_DATA_DIR env var support in daemon, CLI, and TUI
- WebhookHandler: ChannelAdapter for HTTP POST /webhooks/:name
- Per-webhook HMAC auth, template rendering ({{body}}, {{json.field}})
- Config schema: automation.webhooks array with name/secret/message/output
- Gateway routes webhook requests before static files (bypasses gateway auth)
- 23 new tests for webhook functionality, 874 total tests passing
This commit is contained in:
+12
-3
@@ -15,7 +15,7 @@ import { MemoryStore } from '../memory/index.js';
|
||||
import { createMemoryTools } from '../tools/builtin/index.js';
|
||||
import { GatewayServer } from '../gateway/index.js';
|
||||
import { ChannelRegistry, TelegramAdapter, WebChatAdapter, DiscordAdapter, SlackAdapter, WhatsAppAdapter } from '../channels/index.js';
|
||||
import { CronScheduler } from '../automation/index.js';
|
||||
import { CronScheduler, WebhookHandler } from '../automation/index.js';
|
||||
import type { InboundMessage, OutboundMessage } from '../channels/index.js';
|
||||
import { McpManager } from '../mcp/index.js';
|
||||
import { SkillRegistry, SkillInstaller, loadAllSkills } from '../skills/index.js';
|
||||
@@ -521,8 +521,8 @@ function createMessageRouter(deps: {
|
||||
export async function startDaemon(config: Config): Promise<DaemonContext> {
|
||||
const lifecycle = new Lifecycle();
|
||||
|
||||
// Ensure data directory exists
|
||||
const dataDir = resolve(homedir(), '.local/share/flynn');
|
||||
// Ensure data directory exists (FLYNN_DATA_DIR overrides default for Docker/custom deployments)
|
||||
const dataDir = process.env.FLYNN_DATA_DIR ?? resolve(homedir(), '.local/share/flynn');
|
||||
mkdirSync(dataDir, { recursive: true });
|
||||
|
||||
// Initialize memory store
|
||||
@@ -816,6 +816,15 @@ export async function startDaemon(config: Config): Promise<DaemonContext> {
|
||||
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 Tier 1 agent tools ─────────────────────────────
|
||||
|
||||
// Session management tools (list, history, create, delete)
|
||||
|
||||
Reference in New Issue
Block a user