import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { TeamPanelServer } from '../../src/team/panel-server.js'; import { createUiServer } from '../../scripts/serve-ui.mjs'; // Isolated end-to-end test: no model requests and no installed CLI execution. const here = dirname(fileURLToPath(import.meta.url)); process.env.GW_ORCH_OFFLINE = '1'; process.env.GW_TEAM_STUB_CLI = resolve(here, 'fake-coding-agent.mjs'); const root = mkdtempSync(join(tmpdir(), 'gateway-conversation-preview-')); const backend = new TeamPanelServer({ root, port: 0 }); const { port } = await backend.listen(); const ui = createUiServer({ target: 'http://127.0.0.1:' + port }); ui.listen(0, '127.0.0.1', () => console.log('TEST_UI=http://127.0.0.1:' + ui.address().port)); let closing = false; async function close() { if (closing) return; closing = true; for (const child of backend.children.values()) child.kill(); ui.closeAllConnections(); backend.server.closeAllConnections(); await Promise.all([new Promise(r => ui.close(r)), new Promise(r => backend.server.close(r))]); if (dirname(root) === tmpdir() && root.includes('gateway-conversation-preview-')) rmSync(root, { recursive: true, force: true }); } process.on('SIGINT', close); process.on('SIGTERM', close);