#!/usr/bin/env node /** * Starts webhook API + ingest + inbound workers in one terminal. * Purge worker is not started here (scheduled job; use npm run dev:purge if needed). */ const { spawn } = require('child_process'); const path = require('path'); const root = path.join(__dirname, '..'); require('dotenv').config({ path: path.join(root, '.env') }); require('dotenv').config({ path: path.join(root, '../backend/.env') }); /** @type {import('child_process').ChildProcess[]} */ const children = []; function run(name, script) { const child = spawn(process.execPath, ['--watch', script], { cwd: root, env: process.env, stdio: ['inherit', 'pipe', 'pipe'], }); const prefix = `[${name}]`; child.stdout?.on('data', (chunk) => { for (const line of String(chunk).split('\n')) { if (line) process.stdout.write(`${prefix} ${line}\n`); } }); child.stderr?.on('data', (chunk) => { for (const line of String(chunk).split('\n')) { if (line) process.stderr.write(`${prefix} ${line}\n`); } }); child.on('exit', (code, signal) => { if (signal === 'SIGTERM' || signal === 'SIGINT') return; console.error(`${prefix} exited with code ${code ?? signal}`); shutdown(typeof code === 'number' ? code : 1); }); children.push(child); return child; } function shutdown(exitCode = 0) { for (const child of children) { if (!child.killed) child.kill('SIGTERM'); } setTimeout(() => process.exit(exitCode), 300); } process.on('SIGINT', () => { console.log('\nShutting down chatbot dev processes…'); shutdown(0); }); process.on('SIGTERM', () => shutdown(0)); console.log('Starting chatbot API + ingest + inbound workers (Ctrl+C to stop all)…\n'); run('api', 'server.js'); run('ingest', 'workers/ingest.js'); run('inbound', 'workers/inbound.js');