- Delayed reader cancellation so pipeline consumers can flush after producers are terminated.
- Kept the JavaScript watchdog behind bounded native timeout cleanup.
- Added native and executor regressions for timeout-time output draining.
Fixes#5316
- Added an `[Unreleased]` Fixed entry documenting that the in-process `grep` builtin now treats GNU basic-regex `\|` as escaped alternation in default and `-G` modes while `-E`/`-F`/`-P` keep their dialects (code shipped in `fix(pi-uu-grep)`).
Added a direct-argv PTY entry point and used it for Windows launch sessions so portable-pty no longer re-quotes cmd.exe command text.
Rejected direct .bat and .cmd applications with guidance to use cmd.exe /c.
Fixes#5416
A long-lived process that survives an in-place upgrade keeps the previous
pi-natives NAPI addon resident. A tab worker spawned afterwards runs the
new JS loader, which expects the new version sentinel, but require returns
the resident old exports carrying the prior sentinel. validateLoadedBindings
previously reported "reinstall to re-sync" for this case even though disk was
already consistent, so only a restart helped.
Detect a versioned __piNativesV* export other than the expected one on the
loaded bindings and report that omp was upgraded mid-session and must be
restarted, reserving the reinstall guidance for genuinely disk-stale addons.
Fixes#4812
- Enabled deduplication of byte-identical edits in `apply_edits` to prevent false overlap errors.
- Added logic in `ast_edit_blocking` to filter out duplicate rewrite matches before staging.
- Updated `apply_edits` to collapse multiple identical replacements into a single deterministic operation.
- Added regression tests for both `apply_edits` and `ast_edit_blocking` to ensure identical matches resolve cleanly.
- Integrated 17 new coreutils-based shell builtins including `diff`, `date`, `ln`, `stat`, `seq`, `touch`, and others.
- Refactored vendored utilities to execute as in-process shell builtins by routing I/O, environment access, and path resolution through `pi_uutils_ctx`.
- Disabled process-level modifications (e.g., clock setting, hostname modification) to ensure safety and scope adherence within the shell environment.
- Implemented shell-specific features such as cancellation polling, custom exit code management, and efficient output streaming for all new builtins.
- Added base64, checksum utilities (md5, sha1, sha224, sha256, sha384, sha512, b2sum), path utilities (basename, dirname), and text processing tools (cut, tee, tr, paste, comm) to the shell.
- Registered new utility builtins in crates/pi-shell/src/coreutils.rs and crates/pi-shell/src/shell.rs.
- Updated Cargo.toml to include the necessary dependencies for the new core utilities.
- Built the generic Windows release binary with Bun's baseline x64 runtime so older Windows 10 CPUs do not hit the AVX2-only modern executable.
- Forced pi-natives release builds to link PCRE2 statically so macOS installs do not depend on Homebrew's libpcre2 dylib.
- Added release dry-run and native-build regression coverage for the portable artifact contracts.
Fixes#5172
- Implemented path_depth as a tie-break mechanism for fuzzy search results.
- Updated fuzzy_find_sync sorting logic to surface shallow matches before deeper ones during score ties.
- Added a regression test confirming that root-level directories rank above nested ones when scores are identical.
- Updated gitignore loading to filter out ancestor ignore rules that match the current explicit walk root.
- Retained unrelated parent ignore rules and processed local ignore files within the root normally.
- Added a regression test to ensure ignored roots still respect nested ignore rules.
- Added `walk_depth_bound` to calculate the maximum file path depth based on glob pattern segments.
- Configured the glob walker to restrict traversal depth for non-recursive patterns, preventing unnecessary scanning of subtrees that cannot match.
- Improved response times for narrow globs over large directories by pruning the search space earlier.
- Added test cases to verify depth-bounded matching behavior and pattern edge cases.
Regression test for the WSL crash where a timed-out bash command got OMP
OOM-killed: an output-heavy command (in-process 'yes | cat') with a short
timeoutMs must resolve near its deadline with bounded RSS, on both
executeShell and Shell.run. On the pre-fix bridge the same harness measured
~4 GiB RSS growth and minutes-late resolution (JS event loop starved by the
unbounded callback flood); with the bounded backpressured bridge it resolves
at the deadline with flat memory. Also added the user-facing changelog entry
for the crash symptom.
Fixes#4866
arboard's Windows reader feeds Qt-style CF_DIBV5 payloads (BI_RGB plus
alpha mask, rewritten to BI_BITFIELDS by its header tweak) to a
header-less BMP decode that mis-places the pixel offset for V4/V5
bitfield headers, so PixPin/Snipaste screenshots failed with
ConversionFailure. read_image_from_clipboard now falls back to reading
the raw CF_DIB clipboard bytes and decoding them through the BMP file
path with an explicit bfOffBits, keeping native Windows image paste off
the PowerShell bridge.
Fixes#3426
The non-PTY bash streaming bridge queued every decoded chunk into
flume::unbounded and fired ThreadsafeFunction callbacks NonBlocking
with no budget, so a producer outrunning the JS event loop grew the
native queue (and the napi queue behind it) without bound — measured
33.5 MB queued for a 32 MiB stream with a stalled consumer, and
multi-GB RSS on longer runs. The downstream OutputSink caps sit after
the N-API boundary and cannot bound either queue.
Bound the pipeline end to end without dropping data:
- pi-natives: bridge_chunks now creates flume::bounded(64) and the
drain task (extracted as pump_chunks) awaits on_chunk.call_async per
coalesced <=64 KiB batch, so at most one batch sits in the napi
queue and the JS event loop's real consumption rate backpressures
the whole pipeline. If the JS side is gone, the pump exits and
drops the receiver so senders fail fast.
- pi-shell: emit_chunk sends with send_async().await — a full bridge
queue parks the pipe reader, which parks the child on its
stdout/stderr pipe (ordinary pipe backpressure) instead of
buffering; a disconnected receiver fails immediately so child pipes
always keep draining.
Unlike a drop-after-cap design, every byte still reaches JS: the
rolling tail view, lossless [raw output: artifact://…] capture, and
totalBytes accounting keep working for outputs past the display cap.
E2E (darwin-arm64 addon): 32 MiB through a JS callback stalling 1 ms
per call — lossless, 472 coalesced callbacks, peak RSS +21.8 MiB.
Fixes#4078
The build script joined PATH entries with ':' (Unix), so Bun.which could not
locate the @napi-rs/cli napi binary on Windows where the separator is ';'.
This blocked native builds and every test importing countTokens (its import
chain eager-loads the .node).