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

Function readHelloLine

src/mcp/proxy.ts:446–495  ·  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

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

Callers 2

runProxyFunction · 0.85
connectWithHelloFunction · 0.85

Calls 2

cleanupFunction · 0.85
onMethod · 0.65

Tested by

no test coverage detected