Hyeonsang Cho ab126d419c
fix(sandbox): keep line endings in local sandbox reads, writes and str_replace (#6343)
* fix(sandbox): keep line endings in local sandbox reads, writes and str_replace

LocalSandbox opened files in text mode with the default newline=None.
Reads translated CRLF to LF, so str_replace on a CRLF file rewrote every
line as LF and the read-before-write hash missed newline-only changes;
on Windows, writes turned LF content into CRLF (breaking `bash run.sh`).

Read with newline="\n" and write with newline="", keeping line endings
as stored like the remote providers; reads still end lines only at "\n",
the rule count_file_lines and the truncation marker number lines by.
str_replace spells an LF-written old_str/new_str with CRLF when the file
uses it, so multi-line edits still match CRLF files on any provider.

The tool-output budget middleware wrote externalized output the same
way: on Windows the file no longer matched its stamped blob ref and the
next model call deleted it when no blob store was configured. It now
writes with newline="" too.

* docs(changelog): reference #6343 for the line-ending fix

* fix(sandbox): end local grep lines where read_file does

find_grep_matches still opened files with universal newlines, so a bare
"\r" split a line for grep but not for LocalSandbox.read_file, and a hit's
line_number stopped matching the start_line that reads it back. Read with
newline="\n" like read_file, and fold a CRLF terminator back to "\n" so
$-anchored patterns keep matching CRLF lines as before.
2026-10-06 09:45:47 +08:00
..