import http from 'node:http' import { execFile, spawn } from 'node:child_process' import { promisify } from 'node:util' const execFileAsync = promisify(execFile) const port = Number(process.env.COMFY_CONTROL_PORT || 8199) const token = process.env.COMFY_CONTROL_TOKEN || '' const comfyHttp = (process.env.COMFY_HOST || 'http://127.0.0.1:8188').replace(/\/$/, '') function json(res, status, body) { const payload = JSON.stringify(body) res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) }) res.end(payload) } function authorized(req) { if (!token) return true const header = String(req.headers.authorization || '') return header === `Bearer ${token}` } async function httpUp() { try { const res = await fetch(`${comfyHttp}/system_stats`, { signal: AbortSignal.timeout(2500) }) return res.ok } catch { return false } } async function processUp() { try { const { stdout } = await execFileAsync('tasklist', ['/FO', 'CSV', '/NH'], { windowsHide: true, timeout: 4000 }) if (/Comfy Desktop|ComfyUI/i.test(stdout)) return true } catch { /* ignore */ } try { const { stdout } = await execFileAsync('powershell.exe', [ '-NoProfile', '-Command', "Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'ComfyUI\\\\main.py|ComfyUI/main.py' } | Select-Object -First 1 -ExpandProperty ProcessId" ], { windowsHide: true, timeout: 6000 }) return Boolean(String(stdout).trim()) } catch { return false } } function launchCommand() { if (process.env.COMFY_LAUNCH_CMD) return process.env.COMFY_LAUNCH_CMD const local = process.env.LOCALAPPDATA || '' const desktop = `${local}\\Programs\\Comfy Desktop\\Comfy Desktop.exe` return `start "" "${desktop}"` } function startComfy() { const command = launchCommand() const child = spawn(command, { shell: true, detached: true, stdio: 'ignore', windowsHide: true }) child.unref() return { started: true, command } } const server = http.createServer(async (req, res) => { if (!authorized(req)) return json(res, 401, { ok: false, error: 'unauthorized' }) const url = new URL(req.url || '/', 'http://localhost') if (req.method === 'GET' && url.pathname === '/status') { const [httpReady, process] = await Promise.all([httpUp(), processUp()]) return json(res, 200, { ok: true, http: httpReady, process }) } if (req.method === 'POST' && url.pathname === '/start') { if (await httpUp()) return json(res, 200, { ok: true, started: false, already: true }) if (await processUp()) return json(res, 200, { ok: true, started: false, booting: true }) const launched = startComfy() return json(res, 200, { ok: true, ...launched }) } json(res, 404, { ok: false, error: 'not found' }) }) server.listen(port, '0.0.0.0', () => { console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'listen', port, comfyHttp })) })