import fs from "node:fs"; import path from "node:path"; import { spawn, type ChildProcess } from "node:child_process"; let noReplyProcess: ChildProcess | null = null; export function startNoReplyApi( logger: { info: (m: string) => void; warn: (m: string) => void }, pluginDir: string, port = 8787, ): void { logger.info(`dirigent: startNoReplyApi called, pluginDir=${pluginDir}`); if (noReplyProcess) { logger.info("dirigent: no-reply API already running, skipping"); return; } const serverPath = path.resolve(pluginDir, "..", "no-reply-api", "server.mjs"); logger.info(`dirigent: resolved serverPath=${serverPath}`); if (!fs.existsSync(serverPath)) { logger.warn(`dirigent: no-reply API server not found at ${serverPath}, skipping`); return; } logger.info("dirigent: no-reply API server found, spawning process..."); noReplyProcess = spawn(process.execPath, [serverPath], { env: { ...process.env, PORT: String(port) }, stdio: ["ignore", "pipe", "pipe"], detached: false, }); noReplyProcess.stdout?.on("data", (d: Buffer) => logger.info(`dirigent: no-reply-api: ${d.toString().trim()}`)); noReplyProcess.stderr?.on("data", (d: Buffer) => logger.warn(`dirigent: no-reply-api: ${d.toString().trim()}`)); noReplyProcess.on("exit", (code, signal) => { logger.info(`dirigent: no-reply API exited (code=${code}, signal=${signal})`); noReplyProcess = null; }); logger.info(`dirigent: no-reply API started (pid=${noReplyProcess.pid}, port=${port})`); } export function stopNoReplyApi(logger: { info: (m: string) => void }): void { if (!noReplyProcess) return; logger.info("dirigent: stopping no-reply API"); noReplyProcess.kill("SIGTERM"); noReplyProcess = null; }