From 1629e0911e9cde6a4e3b46b42cae11b8fa10fcdf Mon Sep 17 00:00:00 2001 From: iris <2+iris@noreply.localhost> Date: Sat, 29 Aug 2026 15:42:32 -0400 Subject: [PATCH] Say what the line splitter would do with a bare carriage return `complete_lines` splits on `\n` only, which is right -- this stream is JSONL, and a record terminated by a bare `\r` would not be a record -- but the doc comment said why the remainder is held without saying what decides where a line ends. Worth the sentence because of what the failure would look like if the CLI ever wrote such a line: the session goes quiet, the process is healthy, nothing errors, and the cause is a line splitter. The dev-updater session hit exactly this shape today reading cargo's progress line, which is `\r`-terminated for redrawing in place, and lost a whole build's worth of output to it. --- server/src/session/claude.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server/src/session/claude.rs b/server/src/session/claude.rs index 2b57f02..99c7803 100644 --- a/server/src/session/claude.rs +++ b/server/src/session/claude.rs @@ -695,6 +695,17 @@ async fn follow( /// The offset only ever advances by this, which is what lets a read land /// anywhere -- mid-line, mid-character -- without the reader losing its /// place. See the call site for why the remainder is not kept. +/// +/// A line ends at `\n` and at nothing else, deliberately. This stream is +/// JSONL: a record is a line, and something terminated by a bare `\r` is +/// not a record, so treating one as a line would hand `serde_json` a +/// fragment. The accepted consequence is that such a line is held here +/// forever rather than being reported -- and it is worth knowing what +/// that would look like, because it looks like nothing: the session goes +/// quiet with the process healthy, no error anywhere, and the cause is a +/// line splitter, which is not where anybody would look. A progress +/// indicator is the usual reason a program writes one (`\r` is how it +/// redraws in place), and the CLI has never written one here. fn complete_lines(bytes: &[u8]) -> usize { bytes .iter()