MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / readHelloLine

Function readHelloLine

src/mcp/proxy.ts:451–500  ·  view source on GitHub ↗

* Read one CRLF/LF-terminated JSON line from the socket, parse it as the * daemon hello, and return it. Bounded to MAX_HELLO_LINE_BYTES so a * malicious or broken peer can't OOM us. Times out at 3s — a healthy daemon * sends hello immediately on accept.

(socket: net.Socket)

Source from the content-addressed store, hash-verified

449 * sends hello immediately on accept.
450 */
451function readHelloLine(socket: net.Socket): Promise<DaemonHello> {
452 return new Promise((resolve, reject) => {
453 let buffer = '';
454 const cleanup = () => {
455 socket.removeListener('data', onData);
456 socket.removeListener('error', onError);
457 socket.removeListener('close', onClose);
458 clearTimeout(timer);
459 };
460 const onData = (chunk: string | Buffer) => {
461 buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
462 const idx = buffer.indexOf('\n');
463 if (idx === -1) {
464 if (buffer.length > MAX_HELLO_LINE_BYTES) {
465 cleanup();
466 reject(new Error('daemon hello line exceeded size limit'));
467 }
468 return;
469 }
470 const line = buffer.slice(0, idx);
471 // Re-emit anything past the newline so the pipe-stage sees it.
472 const tail = buffer.slice(idx + 1);
473 cleanup();
474 if (tail.length > 0) {
475 // Push back via unshift — Node's net.Socket supports it on readable streams.
476 socket.unshift(tail);
477 }
478 try {
479 const parsed = JSON.parse(line) as DaemonHello;
480 if (typeof parsed.codegraph !== 'string' || typeof parsed.pid !== 'number') {
481 reject(new Error('daemon hello missing required fields'));
482 return;
483 }
484 resolve(parsed);
485 } catch (err) {
486 reject(new Error(`daemon hello not JSON: ${err instanceof Error ? err.message : String(err)}`));
487 }
488 };
489 const onError = (err: Error) => { cleanup(); reject(err); };
490 const onClose = () => { cleanup(); reject(new Error('daemon closed connection before hello')); };
491 const timer = setTimeout(() => {
492 cleanup();
493 reject(new Error('timed out waiting for daemon hello'));
494 }, 3000);
495 timer.unref?.();
496 socket.on('data', onData);
497 socket.on('error', onError);
498 socket.on('close', onClose);
499 });
500}
501
502/**
503 * Pipe stdin → socket and socket → stdout. Resolves once either end closes

Callers 2

runProxyFunction · 0.85
connectWithHelloFunction · 0.85

Calls 2

cleanupFunction · 0.70
onMethod · 0.65

Tested by

no test coverage detected