fix(cli): release Windows file handles after reads - #12097
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Reviewed the Windows file-handle fix in Files Reviewed (3 files)
Reviewed by claude-sonnet-5 · Input: 50 · Output: 22.9K · Cached: 1.6M Review guidance: REVIEW.md from base branch |
fix(cli): release Windows file handles after reads
On Windows, project files can remain open in the long-running Kilo process after the read tool truncates, aborts, or retries decoding. Atomic replacement then fails with
EPERM, preventing Kilo, editors, formatters, and filesystem tools from updating existing files until the process restarts.This regression was introduced in #11533 when streaming reads were restored after the OpenCode integration had switched the Read tool back to whole-file buffering. That restoration correctly preserved bounded UTF-8 streaming and legacy-encoding fallback, but the
Readable.from(Stream.toAsyncIterable(...))bridge did not wait for the Effect iterator and its filesystem scope to finalize when the consumer stopped early. The Read tool could therefore return while Windows still considered the source file open.Make the Node-readable bridge explicitly own the Effect stream iterator. Destroying the consumer now awaits iterator finalization, and the read operation does not complete or retry decoding until the underlying filesystem scope has closed. This keeps the behavior restored by #11533, including pull-based streaming, output-cap short-circuiting, cancellation, encoding fallback, and the injected filesystem abstraction, while establishing a reliable handle-release boundary.
Add regression coverage that immediately replaces files after truncated, aborted, and fallback reads, including the Windows sharing semantics that expose retained handles.
Fixes #12005