agenthub/src/server/index.ts
chahinebrini ff79cbb639 feat(cli): brand all AgentHub console output with "AgentHub:" prefix
Every user-facing line — the watch stream and each command's success
line, on both the local and --server (remote) paths — now carries an
"AgentHub:" prefix so it's recognizable in any agent's console
(Claude / Codex / Kimi), independent of the board.

- watch: formatEvent rewritten to verb-based, branded lines
  ("AgentHub: Task received <id>  <title>  [status]",
   "AgentHub: Task done <id>  by <agent>", "AgentHub: Handoff …"),
  plus an "AgentHub: connected" line on stream start.
- task/handoff/decision/memory/delegate/init + server-listening lines
  branded on the local command path.
- cli/index.ts: same branding on the --server remote path (the path
  agents actually hit), so CLI line and SSE stream now match.
- tests: formatEvent assertions updated to the branded format
  (regex-tolerant of column padding). 106/106 green.

codex + kimi stay implementers by convention (role=implementer +
assignedTo) — no schema change. Bump 0.1.1 -> 0.1.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:09:15 +02:00

49 lines
1.7 KiB
TypeScript

import Fastify from 'fastify';
import { registerRoutes } from './routes.js';
import { resolveAdvertiseUrl, startDiscoveryBroadcaster } from '../discovery.js';
import { startEntityWatcher } from './fsWatch.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<typeof startDiscoveryBroadcaster> | undefined;
// Emit SSE events for CLI/file writes too, not just REST mutations.
const stopWatcher = startEntityWatcher(cwd);
app.addHook('onClose', async () => {
broadcaster?.stop();
stopWatcher();
});
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);
}
}