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:
William Valentin
2026-02-07 14:36:05 -08:00
parent b322e8f29c
commit b50c140d25
12 changed files with 1927 additions and 7 deletions
+2 -2
View File
@@ -8,9 +8,9 @@ export function getConfigPath(): string {
return process.env.FLYNN_CONFIG ?? resolve(homedir(), '.config/flynn/config.yaml');
}
/** Get the data directory path. */
/** Get the data directory path (FLYNN_DATA_DIR overrides default for Docker/custom deployments). */
export function getDataDir(): string {
return resolve(homedir(), '.local/share/flynn');
return process.env.FLYNN_DATA_DIR ?? resolve(homedir(), '.local/share/flynn');
}
/** Load config without throwing. Returns { config } or { error }. */
+1 -1
View File
@@ -49,7 +49,7 @@ export function registerTuiCommand(program: Command): void {
const { HookEngine } = await import('../hooks/index.js');
const { createModelRouter } = await import('../daemon/index.js');
const dataDir = resolve(homedir(), '.local/share/flynn');
const dataDir = process.env.FLYNN_DATA_DIR ?? resolve(homedir(), '.local/share/flynn');
mkdirSync(dataDir, { recursive: true });
const sessionStore = new SessionStore(resolve(dataDir, 'sessions.db'));