(handler: MessageHandler)
| 358 | } |
| 359 | |
| 360 | start(handler: MessageHandler): void { |
| 361 | this.messageHandler = handler; |
| 362 | |
| 363 | this.socket.setEncoding('utf8'); |
| 364 | if (process.env.CODEGRAPH_MCP_DEBUG) { |
| 365 | process.stderr.write(`[mcp-debug] transport attached flowing=${String(this.socket.readableFlowing)} buffered=${this.socket.readableLength}\n`); |
| 366 | } |
| 367 | this.socket.on('data', (chunk: string) => { |
| 368 | if (process.env.CODEGRAPH_MCP_DEBUG) process.stderr.write(`[mcp-debug] transport data ${chunk.length}b\n`); |
| 369 | this.buffer += chunk; |
| 370 | let idx; |
| 371 | // Drain every complete line; tail-fragment stays in the buffer for the |
| 372 | // next chunk. The handler is async but we don't await it here — JSON-RPC |
| 373 | // permits out-of-order responses, and serializing here would deadlock if |
| 374 | // a handler issued a server-initiated request that needed a *later* line |
| 375 | // to arrive (e.g. roots/list mid-tools-call). |
| 376 | while ((idx = this.buffer.indexOf('\n')) !== -1) { |
| 377 | const line = this.buffer.slice(0, idx); |
| 378 | this.buffer = this.buffer.slice(idx + 1); |
| 379 | void this.handleLine(line); |
| 380 | } |
| 381 | }); |
| 382 | |
| 383 | this.socket.on('close', () => this.handleSocketClose()); |
| 384 | this.socket.on('error', (err) => { |
| 385 | // Don't crash the daemon over a broken pipe; just shut this connection. |
| 386 | process.stderr.write(`[CodeGraph daemon] socket error: ${err.message}\n`); |
| 387 | this.handleSocketClose(); |
| 388 | }); |
| 389 | // The daemon's hello reader hands the socket over PAUSED (so the unshifted |
| 390 | // tail can't be emitted to zero listeners and lost — the #662 wedge). |
| 391 | // Attaching 'data' does not resume an explicitly-paused stream; do it here. |
| 392 | // Harmless when the socket was never paused. |
| 393 | this.socket.resume(); |
| 394 | } |
| 395 | |
| 396 | stop(): void { |
| 397 | if (this.stopped) return; |
nothing calls this directly
no test coverage detected