Merge nucleic/keen-maple-heron-yzg3 into dev

This commit is contained in:
2026-07-27 23:00:08 -07:00
parent 049ab9bc78
commit 8ca1b081af
2 changed files with 22 additions and 0 deletions
@@ -33,6 +33,24 @@ public sealed class OutboundWriterTests
Assert.Equal("onetwo", decoded);
}
[Fact]
public async Task FramesLinesWithBareLineFeed()
{
// The wire is LF-framed on every host (docs/WINDOWS_PORT.md §3.3). TextWriter.NewLine
// would otherwise be CRLF on Windows, hiding a stray \r inside every line hostd parses.
// Forcing CRLF on the sink reproduces the Windows default on any platform, so this
// pins the framing even when CI runs the suite on Linux.
var captured = new StringWriter { NewLine = "\r\n" };
var writer = new OutboundWriter(captured);
writer.EnqueueJson("""{"a":1}""");
writer.EnqueueProcOutput(1, stderr: false, "one"u8);
await writer.CompleteAsync();
var text = captured.ToString();
Assert.DoesNotContain('\r', text);
Assert.EndsWith("\n", text);
}
[Fact]
public async Task StderrAndStdoutChunksNeverMerge()
{
+4
View File
@@ -26,6 +26,10 @@ public sealed class OutboundWriter
public OutboundWriter(TextWriter output)
{
this.output = output;
// NDJSON is LF-framed on the wire (docs/WINDOWS_PORT.md §3.3). TextWriter.NewLine
// defaults to Environment.NewLine — CRLF here — which would append a stray \r to
// every line hostd's JSONRPCConnection reads. We own this writer, so pin it.
this.output.NewLine = "\n";
loop = Task.Run(DrainAsync);
}