- Added `replace block N:` syntax in grammar/parser/tokenizer/types, emitting `kind: "block"` edits with empty-body checks.
- Added block-resolution in hashline apply/recovery, wiring `BlockResolver` to resolve edits with throw/drop unresolved behavior.
- Added native `blockRangeAt` support and exported block range/options types through pi-ast, pi-natives, and JS bindings.
- Added coding-agent resolver wiring plus internal visibility/exports updates and new parser, patcher, and setup-wizard tests.
- Renamed non-terminal stdin pipeline tests and updated non-terminal expectations to DetachSession behavior.
- Updated child_session_action behavior so non-terminal, non-pipeline stdin now yields DetachSession instead of None.
- Updated execute_external_command to skip process_group for detached children and move take_foreground into its foreground arm.
- Added async regression coverage for detached pipeline stages and logged the fix in the natives CHANGELOG.
- Removed legacy lowercase Alt+arrow byte handling so alt-arrow sequences are matched through kitty-aware CSI/u paths instead of deprecated escape-letter forms.
- Added support for `alt+enter` from both `\x1b\r` and `\x1b\n` during key parsing and matching.
- Expanded tests to cover mixed Kitty/tmux modes and to restrict legacy uppercase Alt+arrow aliases to non-Kitty protocol mode only.
- Preserved Alt and Ctrl+Alt letter ESC-prefix matching when kitty_protocol_active is true to support mixed tmux and Kitty keyboard modes.
- Parsed two-byte ESC sequences before legacy sequence lookup so mixed-mode Meta pairs are treated as Alt letter keys instead of legacy aliases.
- Updated native and TUI key tests to verify Alt+letter and Alt+Shift+letter parsing and matching while enhanced mode is active.
Fixes#1511
- Changed `bridge_chunks` to drain all currently queued output chunks into one string before invoking the JS callback.
- Added a 64 KiB batch cap with a small initial buffer so each N-API dispatch stays bounded while reducing callback churn from chatty processes.
- Added `unfoldUntilLines`/`unfoldLimitLines` options to progressively reveal nested elidable spans breadth-first instead of collapsing everything behind the outermost elision.
- Added `minTotalLines` setting to skip summarization for short files, returning verbatim content instead.
- Added `:` selector support to `search` paths for constraining matches to specific line ranges.
- Extracted `parseLineRanges`/`parseLineRangeChunk`/`isLineInRanges` from `read.ts` into shared `path-utils.ts`.
- Removed inline_body from grammar; op sigils (↑, ↓, :) now accept no trailing content.
- Executor emits INLINE_PAYLOAD_ACCEPTED_WARNING when legacy inline form is encountered but still applies the edit leniently.
- Updated prompt docs and all tests to use bare op + `+`-prefixed continuation rows.
- Queued modified file contents during ast_edit and flushed writes only after all file edits succeeded.
- Extracted write-logic into ast_edit_blocking with in-memory pending writes to avoid partial disk updates.
- Added a regression test ensuring no file is written when overlapping apply_edits fails partway through a run.
- Added a Bun-based `scripts/ci-release-notes.ts` utility that extracts `## [version]` entries from `packages/*/CHANGELOG.md` and writes a combined `release-notes.md` for the release tag.
- Updated the GitHub release workflow to install Bun, run the notes generator, and pass the generated `release-notes.md` to `softprops/action-gh-release` via `body_path`.
- Updated the auth-gateway OpenAI responses caching test to use shared E2E helper utilities and the common gateway URL constant.
- Initialized and reset in-memory settings in the nested live rendering test fixture to isolate test state between runs.
brush_core::interp::setup_open_file_with_contents wrote the entire heredoc/here-string body into an anonymous pipe synchronously before handing the reader to the downstream command. Bodies that exceed the OS pipe buffer (~4 KiB on Windows, 16-64 KiB on macOS) deadlocked the writer forever, and the bash tool tripped its 305 s hard timeout without ever launching the consumer. The Linux fast path still uses F_SETPIPE_SZ to grow the pipe inline; every other platform (and Linux bodies that overflow pipe-max-size) now decouples the write onto a fire-and-forget thread that terminates on drain or BrokenPipe.
Adds a 256 KiB regression test that exercises the worst-case shape (: builtin, which never drains stdin), guarded by tokio::time::timeout(10s) so a regression fails CI fast instead of hanging.
- Updated `TempDirGuard` creation in grep tests to include PID and an atomic sequence, preventing temp path collisions.
- Removed the `branch` filter from GitHub action run queries so results are matched by `head_sha` only.
- Adjusted run-watch calls to the simplified `fetchRunsForCommit` interface without the branch argument.
The Hangul Compatibility Jamo width correction (U+3131..=U+318E → 1 cell)
was applied unconditionally, but macOS terminals (Ghostty, Terminal.app,
iTerm2) are the only ones that render jamo as 1 cell. WezTerm and most
Linux terminals follow UAX#11 and render them as 2 cells.
The unconditional correction caused a width mismatch between the TUI's
calculated column positions and the terminal's actual rendering, resulting
in corrupted layout and broken Korean input on non-macOS platforms.
- Rust: gate the correction with cfg!(target_os = "macos")
- TS: gate the correction with process.platform === "darwin"
- On non-macOS, use UnicodeWidthStr for multi-char graphemes (perf)
Constraint: macOS terminals render jamo as 1 cell despite UAX#11.
Rejected: removing the correction entirely — would break macOS.
Tested: native build succeeds, typecheck passes.
Not-tested: visual verification on macOS terminals.
Scope-risk: narrow
- Updated `terminate_new_descendants` to require the `Sync` marker on its hash-set hasher.
- This tightened async helper bounds without changing its termination-wave logic.
Stopped marking persistent bash sessions as permanently broken when the JavaScript abort or timeout race wins.
Stopped the Rust descendant kill-wave helper once no cancellation targets remain so later commands are not swept into old cancels.
Fixes#1347
Added Rust-side descendant termination on shell cancellation paths so aborts and timeouts escalate to SIGKILL even if brush cleanup stalls.
Covered SIGTERM-ignoring shell workloads in native tests.
Fixes#1347