import Fastify from 'fastify'; import { registerRoutes } from './routes.js'; import { resolveAdvertiseUrl, startDiscoveryBroadcaster } from '../discovery.js'; export function buildApp(cwd: string) { const app = Fastify({ logger: false }); registerRoutes(app, cwd); return app; } export async function startServer(cwd: string, options: { port?: number; host?: string } = {}): Promise<{ app: Fastify.FastifyInstance; url: string }> { const app = buildApp(cwd); const port = options.port ?? 3377; const host = options.host ?? '127.0.0.1'; let broadcaster: ReturnType | undefined; app.addHook('onClose', async () => { broadcaster?.stop(); }); try { await app.listen({ port, host }); const address = app.server.address(); const actualPort = typeof address === 'string' ? port : (address?.port ?? port); const url = `http://${host === '0.0.0.0' ? '127.0.0.1' : host}:${actualPort}`; console.log(`AgentHub server listening on ${url}`); const advertiseUrl = resolveAdvertiseUrl(host, actualPort); broadcaster = startDiscoveryBroadcaster(advertiseUrl); return { app, url }; } catch (err) { const e = err as NodeJS.ErrnoException; if (e.code === 'EADDRINUSE') { console.error( `Port ${port} is already in use by another process that is not AgentHub. ` + `Stop it, or start with a different --port.`, ); } else { console.error(err); } process.exit(1); } }