82 KiB
82 KiB
Changelog
[Unreleased]
[17.2.5] - 2026-08-03
Breaking Changes
- Replaced DesktopSession.execute(actions, window) and action batches with dedicated per-operation methods for capture, pointer, keyboard, window, and accessibility. Capture capabilities now apply per call, and coordinate input requires a prior frame for the same target.
Added
- Added a cross-platform, in-process ps shell builtin supporting BSD/procps selection forms, custom output columns, sorting, process metrics, and header suppression.
- Added unified desktop backends for macOS, Win32, X11, and Wayland behind a single session API, featuring capture-free window discovery, isolated capture, explicit background/foreground delivery, native accessibility trees (AX/UIA/AT-SPI) with generational references, and structured errors for unsupported background input.
Fixed
- Fixed accessibility snapshots incorrectly marking a window root as focused based on its app-local AXFocused attribute when another application held global focus; the root annotation now correctly reflects the global window-roster focus flag.
- Improved coordinate-frame error messages for pointer input before capture, out-of-frame coordinates, and between-display points to clearly explain the capture-frame contract and remedy instead of throwing a generic bounds check.
- Fixed duplicated characters in AppKit targets on macOS caused by background keyboard events being posted through both CoreGraphics and SkyLight; events are now delivered once via the authenticated SkyLight route.
[17.2.2] - 2026-07-31
Changed
- Updated native HTML-to-Markdown rendering to html-to-markdown-rs 3.9.2 defaults, which may result in formatting differences (such as fenced code blocks and cycling nested-list bullets) compared to version 2.30.0.
Fixed
- Fixed a heap corruption crash when opening PulseAudio on Linux ARM64 by shipping target-specific miniaudio Rust layouts for GNU and musl native addons.
- Fixed local Bazel addon builds on NixOS by exposing system CMake tools to sandboxed build scripts and correctly bundling Opus.
- Fixed workspace native addon loading to correctly prefer the workspace build over an installed leaf package.
- Fixed process crashes caused by pathological HTML inputs; conversions that exceed the native-stack DOM depth limit now reject instead of returning silently truncated Markdown.
[17.2.1] - 2026-07-30
Fixed
- Fixed the
computertool advertising Wayland support that never worked: on the default rootless XWayland (GNOME/KDE/sway) the X11 root window has no readable pixmap, so rootGetImagefailed on every screenshot with a rawBadMatchprotocol dump.Monitor::allnow probes root drawability at initialization and fails fast with an actionableDESKTOP_BACKEND_UNAVAILABLEmessage naming the rootless-XWayland constraint, anddocs/computer-use.mdnow lists rootless XWayland as unsupported (#7085).
[17.2.0] - 2026-07-30
Changed
- Split the native voice engine (miniaudio capture/playback, WebRTC peer, Opus media) out of the
pi-nativesaddon crate into a napi-freepi-voicerlib. The addon keeps thin#[napi]adapters, so the JS API is unchanged; the webrtc/opus/miniaudio dependency graph now compiles once into the library and no longer rebuilds with the addon leaf (which recompiles every release via its version-sentinel edit). - Release binaries now build in parallel with the test fan-out; npm leaf publishing moved to a dedicated post-validation job (
release_native_leaves), and darwin release bazel caches are pre-warmed on native-affecting main pushes — cutting release wall time from the previous serialized tests → cold darwin build pipeline.
[17.1.8] - 2026-07-28
Fixed
- Fixed an issue on macOS (darwin) where the native addon delivered zero AudioCapture callbacks, which prevented microphone audio from being captured.
[17.1.6] - 2026-07-27
Changed
- CI now exports Bazel disk caches only after exact misses and reuses one native addon artifact across Linux test and release jobs. macOS release jobs now build only their own architecture.
- Native addons now build with Bazel (rules_rust + hermetic zig cc toolchains for linux-gnu/musl, host Xcode for darwin, and a hermetic clang-cl + xwin toolchain for windows-msvc) instead of the napi CLI + cargo-zigbuild/cargo-xwin pipeline.
bun run builddrivesscripts/bazel-natives.ts; TypeScript binding regeneration moved tobun run build:bindings(needed only when the Rust API surface changes). CI caches through a content-addressed bazel-remote action cache instead of sccache + target-directory snapshots, cutting warm native rebuilds from ~20 minutes to seconds and cold cache-hit builds to ~2.5 minutes.
Fixed
- napi binding build failures now surface the exit code and the tail of stdout/stderr instead of a bare "napi build failed" message (#6799).
- Silenced cross-platform Rust build warnings: dead-code on unix-only fields/helpers in
pi-uutils-ctx,pi-shell(fd owner filters, coreutils argv), and vendoreduu-find/uu-statwhen compiling for Windows, and deprecatedlibc::time_tcasts inpi-isoon musl.pi-walkernow declares thewindows-sysfeatures it uses (Win32_Foundation,Win32_Security,Win32_Storage_FileSystem,Win32_System_IO) instead of relying on workspace-wide feature unification.
[17.1.5] - 2026-07-27
Fixed
- Fixed the native
sortbuiltin panicking withSendError(..)atchunks.rs:248when the chunk-channel receiver disconnected early (e.g. a consumer thread stopping after an error or closed output); the reader now stops gracefully instead of unwrapping the failed send, and a panicking external-sort worker thread is surfaced as an error instead of silently emitting truncated output (#6736).
[17.1.4] - 2026-07-26
Added
- Added the
@oh-my-pi/pi-natives/desktopfactory entry, which defers native addon loading until a desktop worker initializes its session.
Fixed
- Fixed Linux native audio over forwarded PulseAudio servers: capture now handles 125 ms Android fragments without stalling, and playback buffers enough audio to avoid TCP underruns and stuttering (#6628 by @anatoli-tsinovoy).
- Fixed older running OMP versions deleting newer native addon cache directories during cleanup, which could race a new version's first-run extraction and crash with
ENOENT. - Fixed macOS computer screenshots occasionally returning the pre-action frame instead of reflecting completed keyboard and pointer input (#6595 by @wolfiesch).
[17.1.3] - 2026-07-24
Changed
astEditwithout an explicitlangnow rewrites mixed-language paths per file (each file parsed in its own inferred language, patterns compiled per language) instead of erroring when the path/glob spans multiple languages. A pattern that parses in no discovered language is still reported (or fails the call underfailOnParseError); files whose language cannot be inferred surface as per-file parse errors instead of aborting the whole call.
[17.1.2] - 2026-07-24
Fixed
- Fixed native addon builds with CMake 4.x (bundled opus policy floor) and stopped passing
-C target-cpu=nativeon darwin arm64, which baked build-host CPU features into shipped addons and brokeringcompilation.
[17.1.1] - 2026-07-24
Added
- Added native
AudioCapture,AudioPlayback, andLiveWebRtcPeerclasses for low-latency microphone capture, gapless speaker playback, and WebRTC offer/answer sessions with Opus media andoai-eventsdata-channel delivery. - Added a macOS
deviceCheckGenerateTokenexport that generates Apple DeviceCheck attestation tokens natively: it drivesDCDevice.generateTokenthrough raw Objective-C runtime FFI with a hand-built completion block literal and a bounded one-second wait, resolving{ supported, tokenBase64, error, latencyMs }to mirror the ChatGPT desktop app'sdevicecheck.nodeaddon contract. Non-macOS builds resolvesupported: falsewithout touching the network. - Added a genuine native desktop backend for computer use, bundled in the core addon on every published platform: macOS Quartz/CGEvent, Windows Win32/
SendInput, and a pure-Rust Linux X11 backend (x11rbcapture over the display socket, XTest input with keysym mapping) that links no GUI system libraries — so Linux x64/arm64, glibc and musl are all supported and headless hosts are unaffected. Wayland sessions work through XWayland. Execute batches enforce a 60-second native deadline (DESKTOP_DEADLINE_EXCEEDED) and never emit input after it expires; unsupported pure-Wayland capture and out-of-XTest-range or negative-origin coordinate layouts fail closed.
Fixed
- Fixed macOS computer screenshots taking roughly 30 seconds under Bun by replacing xcap's deprecated window-list capture with a bounded system capture path; direct screenshots now complete in under half a second on the verified host.
[17.0.8] - 2026-07-22
Added
- Added jsdiff-compatible native diff exports:
diffLines,diffWords,diffLineRuns, andstructuredPatchHunks. - Added batch vector kernels for mnemopi recall paths:
cosineSimilarityPairs,vectorIndexTopK, andmmrRerankIndices.
Changed
- Updated diff functions (
diffLines,diffWords,diffLineRuns,structuredPatchHunks) to process UTF-16 code units natively end to end viaUtf16String, supporting ill-formed JS strings with unpaired surrogates without throwing or converting to UTF-8.
Fixed
- Fixed a critical issue where the in-process
rmbuiltin treated an empty path operand as the current working directory, causingrm -rf ""to recursively delete the current directory. Empty operands are now rejected, matching GNUrmbehavior.
Removed
- Removed unused
similarcrate dependency and dev-dependency on npmdiff.
[17.0.5] - 2026-07-18
Added
- Added optional PTY start callbacks that report the spawned child PID before command completion.
[17.0.3] - 2026-07-17
Fixed
- Fixed
~(tilde) not expanding for every element of a brace expansion in the bash tool, somkdir -p ~/project/{a,b}now creates bothaandbunder$HOME/projectinstead of leaving a literal~/project/bin the working directory (#5819). - Fixed ANSI text wrapping to close and restore OSC 8 hyperlinks at physical line boundaries, preventing link targets from leaking into appended content (#5885).
[17.0.2] - 2026-07-17
Fixed
- Fixed an issue where running
uv run --extra <package> pytestbypassed native pytest minimization due to a wrapper parsing error. - Fixed a bug where timed-out shell pipelines dropped captured output and could cause Windows hosts to terminate during teardown. (#5316)
[17.0.1] - 2026-07-16
Fixed
- Fixed the pi-natives version sentinel emitting "reinstall to re-sync" when a long-lived process survives an in-place upgrade: the loader now detects that the resident addon exposes a prior release's sentinel and reports "omp was upgraded while this session was running — restart to pick up the new version (disk is already consistent)" instead of misdiagnosing it as a stale on-disk file (#4812).
[17.0.0] - 2026-07-15
Fixed
- Fixed the in-process grep builtin to correctly handle escaped alternation (|) in default and -G (GNU basic-regex) searches, while preserving the correct regex dialects for -E, -F, and -P.
[16.5.2] - 2026-07-14
Fixed
- Fixed an issue where Windows PTY callers were forced through shell command re-quoting by supporting direct executable and argument launching.
[16.4.6] - 2026-07-12
Added
- Added an in-process
readlinkshell builtin (vendored from uutils coreutils 0.8.0), supporting-f/-e/-mcanonicalization,-n/-zdelimiters, and-v/-q/-sverbosity, with path operands resolved against the shell working directory. - Added in-process shell builtins for
realpath,touch,stat,date,mktemp,seq,yes,printenv,ln,truncate,tac,nproc,uname,whoami, andhostname(vendored from uutils coreutils 0.8.0), plus nativewhich(shell PATH lookup) anddiff(unified output,-U/-q/-N, binary detection, recursive directory compare) builtins. All resolve path operands against the shell working directory, read the shell's exported environment, and honor abort/timeout cancellation;lnis gated with the destructive set (PI_DISABLE_UUTILS_DESTRUCTIVE), and system-mutating modes (date --set, hostname setting) are disabled.
Fixed
- Fixed
ast_editrejecting byte-identical duplicate replacements as "Overlapping replacements detected": multiple rewrite ops matching the same node with the same output now collapse into one deterministic edit (deduped in both the preview listing/counts and the apply pass), so only genuinely divergent overlaps error.
[16.4.5] - 2026-07-11
Added
- Added context-safe, in-process shell builtins for common utilities including base64, basename, dirname, cut, tee, tr, paste, comm, sed, xargs, jq, and the md5sum/sha/b2sum checksum family. These builtins run without spawning external binaries, support pipelines, respect shell-relative paths and environment variables, and honor abort/timeout cancellation.
[16.4.4] - 2026-07-11
Fixed
- Fixed fuzzyFind tie-breaking logic to prefer shallower paths first, preventing deeply nested matches from ranking above shallow ones on score ties.
- Fixed macOS installation issues for pi-natives by statically linking PCRE2, removing the runtime dependency on Homebrew's dynamic libpcre2-8.0.dylib library.
[16.4.3] - 2026-07-11
Fixed
- Optimized non-recursive glob patterns (e.g.,
dir/*.json) to prevent traversing entire subtrees, significantly improving performance and preventing timeouts when searching large directories. - Fixed native filesystem searches (
glob,grep, and AST search/edit) incorrectly excluding explicitly rooted directories due to ancestor ignore rules.
[16.3.13] - 2026-07-09
Fixed
- Fixed unbounded memory growth in the native bash output bridge when a command produces output faster than the JS event loop consumes it: the shell streaming path now uses a bounded chunk queue with real backpressure (pipe readers park until the JS callback catches up, parking the child on its pipe) instead of buffering the entire surplus in memory. No output is dropped — the rolling tail view,
[raw output: artifact://…]lossless capture, and byte accounting are unaffected (#4078). - Fixed
readImageFromClipboardon Windows failing with "could not be converted to the appropriate format" for screenshots taken by Qt-based tools such as PixPin and Snipaste. arboard hands theirCF_DIBV5payload (BI_RGBplus an alpha mask, rewritten toBI_BITFIELDS) to a header-less BMP decode that mis-places the pixel offset for V4/V5 bitfield headers; the native reader now falls back to decoding the rawCF_DIBclipboard bytes directly, so image paste no longer depends on the PowerShell bridge. (#3426) - Fixed OMP being killed outright (OOM on memory-capped hosts such as WSL) when an output-heavy bash command hit its timeout: the unbounded output-bridge backlog could grow by gigabytes before cancellation and starve the JS event loop far past the deadline; with the bounded backpressured bridge the run resolves at its deadline with flat memory (#4866).
[16.3.12] - 2026-07-08
Fixed
- Fixed the native build script failing to locate the
@napi-rs/clinapibinary on Windows because thePATHlookup joined entries with a Unix:separator instead of the platform delimiter (path.delimiter). - Fixed a Windows regression where an abnormal
ompexit or bash cancellation couldTerminateProcessunrelatedpwsh.exe/powershell.exesessions (including other Cursor terminal tabs).SpawnRegistrystored only the raw pid of each brush-spawned child and re-opened it viaProcess::from_pidat cancellation time; between those two moments Windows could recycle a freed pid onto an unrelated PowerShell, andsignal_treethen walked the wrong subtree via Toolhelp. The observer now pins a stableProcesshandle at spawn time — on Windows the open handle keeps the pid slot reserved, on Linux the pidfd carries identity, on macOS the(pid, start_time)triple detects impersonation — so cancellation can only reach children this run actually launched. The registry sweeps exited entries once the recorded set crosses a small threshold so a long bash loop of short external commands cannot pin one owned OS handle per historical spawn. (#4605)
[16.3.6] - 2026-07-04
Changed
- Rewrote native
grepdirectory search to stream while the tree is walked: a work-stealing parallel traversal feeds searchers directly, and content-mode match budgets now terminate the walk itself instead of only the search. Limited searches keep deterministic path-ordered first pages at every budget size via windowed commits, with oversized files still deferred behind normal-sized results. - Faster filesystem walker: gitignore/ignore state is now derived from each directory's own listing instead of up to five per-directory stat probes, per-entry allocations were eliminated through pooled directory scratch buffers and reusable path builders, and a new parallel unordered file-candidate walk API backs full-scan grep.
- Concurrent
grepcalls are no longer serialized against each other, searchers are reused per worker instead of rebuilt per file, and non-multiline patterns opt into grep-regex's line-terminator fast path with a compatibility fallback.
[16.3.0] - 2026-07-02
Added
- Added
workingDirtoShellRunResultto allow hosts to synchronize the session's current working directory without executing a hidden probe command.
Fixed
- Fixed an issue where panics in native worker tasks (such as grep, AST parsing, globbing, workspace listing, HTML-to-markdown conversion, fuzzy finding, and clipboard image reading) would abort the host process instead of properly rejecting the returned JavaScript Promise.
- Fixed a crash on Windows under low memory or commit charge conditions when spawning worker threads for token counting or sorting operations.
[16.2.11] - 2026-07-01
Fixed
- Fixed high memory usage in native
astGrepandastMatchby retaining only the requested page window of match payloads during broad searches while preserving exact totals.
[16.2.10] - 2026-06-30
Added
- Added a platform-native no-ignore filesystem traversal path for
glob/grepscans, usinggetattrlistbulkon macOS,getdents64/statxon Linux, andNtQueryDirectoryFilewithFileIdFullDirectoryInformationon Windows while preserving the existingWalkBuilderpath for gitignore-aware scans.
[16.2.7] - 2026-06-30
Added
- Added embedded Silver TrueType font rendering support to
renderSnapcompactPng, featuring automatic per-glyph fallback for missing bitmap characters and anti-aliased scaling for East Asian wide code points. - Added the
snapcompactSupportedCharsfunction to check font capability for specific characters.
[16.2.5] - 2026-06-28
Fixed
- Fixed the in-process
grepbuiltin rejecting GNU-grep's--color/--colour(with or without=WHEN) and--versionflags. The shadowing rejection broke bash's near-universalalias grep='grep --color=auto', causing baregrepin any pipeline to fail with exit 2. The builtin now accepts and ignores--color[=WHEN](its output goes through in-process file descriptors, never a TTY, so ANSI injection would corrupt downstream consumers) and reports its version through the context streams (#3755).
[16.2.4] - 2026-06-28
Fixed
- Fixed a crash in the in-process
tailbuiltin where the host process would abort with aBrokenPipepanic if the stdout consumer closed the pipe early.
[16.1.23] - 2026-06-26
Added
- Added Nix and Mermaid syntax highlighting support to
highlightCode/supportsLanguagevia vendoredNix.sublime-syntaxandMermaid.sublime-syntaxdefinitions plusnix,mermaid, andmmdaliases. - Added in-process uutils-backed shell builtins to the embedded brush
Shell:cat,head,tail,wc,sort,uniq,ls,find,grep,mkdir,rm, andmv. These vendored + patched utilities run inside the shell process (nofork/exec), resolve path operands against the shell working directory, route stdio through the command's (possibly piped/redirected) file descriptors, read the shell's exported environment, and honor abort/timeout cancellation (a blockedstdinread unwinds cleanly).grepis built on the ripgrepgrep-*crates andfindonuutils/findutils; the rest are pinned touutils/coreutils0.8.0 (matching the bundleduucore). Registration is gated: setPI_DISABLE_UUTILS_BUILTINSto fall back to the system binaries for the whole set, orPI_DISABLE_UUTILS_DESTRUCTIVE/PI_DISABLE_RM_BUILTIN/PI_DISABLE_MV_BUILTINto disable only the destructiverm/mvshadows.
[16.1.17] - 2026-06-24
Added
- Added
setHangulCompatJamoWidthOverride(value)to override the Hangul Compatibility Jamo (U+3131..U+318E) display width at runtime via a process-global atomic, instead of relying solely on the compile-timecfg!(target_os = "macos")heuristic. The actual width is decided by the client terminal (not the host OS), so the TUI resolves it from the terminal identity and pushes the result here. Encoding:0= platform default (macOS narrow, otherwise UAX#11),1= narrow (1 cell),2= wide (2 cells),3= Unicode width (no correction). The leaf width helpers read this override, so no width/slice/truncate/wrap signatures change.
[16.1.15] - 2026-06-22
Added
- Added
Shell.liveBackgroundJobCount()reporting the number of live external background jobs (&/nohupchildren) on a persistent session, reaping completed jobs first via a silentpoll(). Lets the host retain a shell whose background process is still running instead of dropping it (which would SIGKILL the child via kill-on-drop).
Fixed
- Fixed
pi_nativesfailing to load in Bun worker threads on macOS x64 when the host built only themodern(AVX2) variant. The runtime detector'schild_process.spawnSync("sysctl", …)returned null from the worker even though the build-time detector succeeded in the parent, soloadNative()resolvedvariant=baselineand searched a file list that excluded the on-diskpi_natives.darwin-x64-modern.node. Resolution now prefersBun.spawnSync, tries/usr/sbin/sysctlbefore baresysctl, and caches the first context's verdict via a private env key so child workers and subprocesses inherit it instead of re-detecting (#3238).
[16.1.14] - 2026-06-22
Fixed
- Enabled full Julia syntax highlighting support in highlightCode
[16.1.12] - 2026-06-21
Added
- Added Julia syntax highlighting to
highlightCode/supportsLanguagevia a vendoredJulia.sublime-syntaxfolded into syntect's default set (jl/juliaaliases); syntect ships no Julia grammar.
[16.1.8] - 2026-06-20
Breaking Changes
- Changed renderSnapcompactPng to return a promise instead of a string value
Fixed
- Fixed directory
grepcontinuing to walk large trees after the requested content match budget had already been satisfied, which could make broad coding-agent searches time out before returning the first page of matches (#2738).
[16.0.11] - 2026-06-19
Fixed
- Fixed native shell execution reporting
pi-natives:command: syntax error at end of inputfor a valid&&/;chain whose later pipeline stage is a compound command, e.g.echo x && git log | while read h; do …; done | head. The output minimizer's segmented-chain runner rebuilds each chain segment from the brush-parser AST viapipeline.to_string()and re-executes that string, butsimple_segmentonly validated the first pipeline stage — so a compound later stage (while/for/if/subshell) was re-serialized without its terminator (Displaydrops it) and re-run as broken shell.simple_segmentnow requires every stage to be aDisplay-safe simple command, and — closing the recurring class of brushDisplayround-trip divergences (here-doc close-tag quoting, multi-byte char/byte offsets) at its root — each reconstructed segment is re-parsed and must match the original pipeline shape before the chain runner executes it; any divergence runs the command whole via the unsegmented path instead of corrupting it.
[16.0.7] - 2026-06-18
Added
- Added Fortran support to the AST tooling, including file/alias resolution.
[16.0.6] - 2026-06-18
Removed
- Removed the
cacheoption fromGrepOptions
[16.0.4] - 2026-06-17
Fixed
- Fixed
summarizeCodeBFS unfold aborting the entire pass when it hit an oversized, un-unfoldable leaf span (e.g. an HTML<style>raw-text block, an embedded blob, or a minified line) whose only unfold candidate is its whole body. The overflow check used tobreakthe breadth-first loop, so any large leaf encountered before its siblings starved the rest of the tree — an HTML page summarized to<style> ... </style>plus<div class="page"> ... </div>, collapsing the document body into one dead.... An overflowing span is now skipped (left folded, its subtree unexplored) and the BFS keeps unfolding the remaining queued siblings, so structured siblings like the<body>DOM are revealed up tounfoldLimitwhile the oversized leaf stays folded.
[16.0.2] - 2026-06-16
Added
- Added Emacs Lisp (
.el,.emacs,emacs-lisp/elisp) support to native tree-sitter language inference, enabling astGrep/astEdit, summarizeCode, and blockRangeAt on Emacs Lisp source.
[16.0.1] - 2026-06-15
Fixed
- Fixed shipped Linux native addons failing to load with
version 'GLIBC_2.39' not foundon distributions older than Ubuntu 24.04. After native builds moved onto the Ubuntu 24.04 (glibc 2.39) self-hosted runner, the x64 addon was a plain host build that linked the runner's glibc and the arm64 cross-build floated up to GLIBC_2.30; thelinux-x64(baseline + modern) andlinux-arm64addons are now built throughcargo-zigbuildagainst a pinned glibc 2.17 floor, restoring portability to any glibc ≥ 2.17 (CentOS 7 / Ubuntu 14.04 era). - Fixed Linux native builds hard-failing when
RUSTC_WRAPPER=sccachepoints at an unavailable shared cache backend. The native build script now retries thenapibuild once without the sccache wrapper after a cache-storage startup failure, so install smoke tests and local fallback builds can proceed while preserving the cached fast path when the backend is healthy. - Fixed shell cancellation cleanup failing to reap child processes inside containers whose guest kernel was built without
CONFIG_PROC_CHILDREN(e.g. some Kata/microVM guests): the Linux descendant walk relied solely on/proc/<pid>/task/<tid>/children, which does not exist there, sochildren()/live_descendants()returned empty and termination waves never reached the children. It now falls back to scanning/procand grouping by parent pid (the primitive the macOS path already uses) when nochildrenfile is readable, keeping the cheap per-task fast path on kernels that support it.
[15.13.1] - 2026-06-15
Fixed
- Fixed
pi-nativesdeadlocking at addon load (dlopenhang) on some Linux hosts. The load-time Tokio runtime install added in 15.12.6 ran inside#[module_init], which executes while the dynamic-loader lock is held; building the multi-thread runtime there eagerly spawns worker threads, and a fresh worker blocking to acquire the loader lock the init thread still owns deadlocks the whole load (every native consumer hangs at startup). The runtime is now built from an exported__ompInstallTokioRuntimethat the JS loader calls once, immediately afterdlopenreturns and before any async native runs;#[module_init]only installs the crash handler. napi-rs materializes its runtime lazily on first async use (RTis aLazyLock) andcreate_custom_tokio_runtimeonly records the runtime, so the post-load install is still adopted — preserving the Windows commit-limit thread probing/back-off from 15.12.6 without spawning under the loader lock. - Fixed
blockRangeAt(and thus the edit tool'sreplace block/delete block/insert after blockops) returning no block for a construct whose opening line follows a blank line — most visibly in Swift, wherereplace blockon a SwiftUIvar body: some View {(or any statement/declaration after a blank line) failed with "could not resolve a syntactic block… (unsupported language, blank/closer line, or parse error)". tree-sitter-swift inserts a zero-width separator node at the start of a statement that follows a blank line; the resolver queried the first content column with a zero-width point range, whichts_node_named_descendant_for_point_rangeabsorbs into that invisible node and bubbles back up to the enclosing body (or the file root), so no block was found. The query now spans the first content character (a one-column-wide range) so it skips zero-width nodes and descends into the node that actually begins on the line. - Fixed native shell execution reporting
unterminated here document sequencefor a multi-command line that contains a here-doc with a quoted or escaped delimiter (<<'TAG',<<"TAG",<<\TAG) followed by another command (e.g. asqlite3 … <<'SQL' … SQLquery followed by anecho/second command). The output minimizer's segmented-chain runner rebuilds each&&/;/newline segment from the brush-parser AST viapipeline.to_string(), and thatDisplayimpl re-emits a quoted/escaped here-doc's closing delimiter with its quotes intact ('SQL'instead of the required bareSQL) — an invalid close tag that the re-run segment never matches. Here-doc-bearing pipelines are now ineligible for segmentation, so the command runs whole via the unsegmented path (where the executor parses it correctly); a lone here-doc was unaffected because it was never segmented. - Fixed native addon loading leaving stale
~/.omp/natives/<version>cache directories behind after updates; successful loads now remove older version directories best-effort. - Fixed Linux source-built native addons hanging during package import by keeping the Windows-only Tokio worker probe out of non-Windows module initialization (#2553).
- Fixed
pi-isoWindows clippy failures in symlink placeholder metadata, block-clone path resolution, and readonly cleanup handling (#2379 by @oldschoola).
[15.12.6] - 2026-06-14
Fixed
- Fixed
pi-nativesaborting the whole process at addon load on memory-constrained Windows hosts (OS can't spawn worker thread, typically OS error 1455 — pagefile/commit limit). napi-rs builds its own Tokio runtime with one eagerly-spawned worker per CPU, and that spawn panics rather than erroring, so underpanic = "abort"the failure was uncatchable. The addon now installs its own runtime at load: it probes how many threads the OS will actually grant (starting from the Tokio default, clamped to a small ceiling since CPU-heavy native work runs on libuv/Rayon and Tokio's separate blocking pool, not the scheduler workers), sizes the multi-thread runtime to the probed count, and falls back to a current-thread runtime if not even one worker can be spawned — no panic on any path.
[15.12.4] - 2026-06-13
Fixed
- Fixed native shell execution rejecting quoted heredocs whose closing delimiter is the final line without a trailing newline, matching bash paste-run snippets.
[15.11.7] - 2026-06-12
Added
- Added the X.org misc
6x12and8x13BDF fonts (public domain, vendored incrates/pi-natives/src/fonts/) torenderSnapcompactPng, alongside two new options for the snapcompact eval-winner shapes:stretch: falserenders glyphs at natural size on the requested cell box while keeping the 4-bit indexed encoder (e.g. 8x13 glyphs on an 8x16 pitch, the "8on16" shapes), andcolumns: 2flows pre-wrapped newline-separated lines down two newspaper columns with a 3-cell gutter (the "doc" shapes); in doc mode sentence hues also advance across a terminator followed by a newline - Added a line-break marker to
renderSnapcompactPng:U+2588(FULL BLOCK) fills its entire cell box with pitch-black ink in both grid and doc layouts, ignoring the sentence hue and dim state, and counts as a sentence boundary after a./!/?terminator
Changed
renderSnapcompactPngnow clips the frame height to the text: the PNG stayssizepixels wide but is onlyusedRows * lineRepeat * cellHeighttall (dim toggles are zero-width; doc layout counts\n-separated lines), so a partially filled frame no longer pads to a full square of blank rowsrenderSnapcompactPngindexed frames now narrow the palette to the colors actually printed and pick the matching bit depth (plainbw1-bit, dim/banded 2-bit, sentence hues up to 4-bit), and both encode paths moved fromBalancedtoHighdeflate:8on16-bwframes shrink ~35%,6x12-dim~10%, sentence-hue doc frames ~9% — pure PNG, no decoder-side changes (lossless WebP was measured at only ~8% beyond this and rejected for provider-compatibility risk)
[15.11.4] - 2026-06-12
Fixed
- Fixed
blockRangeAt(and thus the edit tool'sreplace block/insert after blockops) failing on extensionless shell rc/profile files.Path::extensionreturnsNonefor both bare (zshrc) and dotfile (.zshrc,.bashrc) forms, so language inference fell through to "unrecognized" and block resolution was permanently unresolvable on those files — an agent retrying the block op would loop on the same error. Known shell rc/profile basenames (zshrc/zshenv/zprofile/zlogin/zlogout/bashrc/bash_profile/bash_login/bash_logout/bash_aliases/profile/kshrc/mkshrc/shrc, with or without a leading dot) now resolve to the bash grammar.
[15.11.0] - 2026-06-10
Breaking Changes
- Changed
renderSnapcompactPng(text, options)to return a base64-encoded PNGstringinstead of aUint8Array
Added
- Added dim-span ink toggles to
renderSnapcompactPng:U+000E/U+000Fin the input switch to a dim gray ink (palette index 9) and back without occupying a glyph cell, letting callers visually de-emphasize spans such as archived tool output - Added
renderSnapcompactPng(text, options): rasterizes pre-normalized text onto a square PNG in an eval-validated snapcompact shape. Options select the bundled font (5x8X.org BDF or8x8unscii-8, both public domain, shipped incrates/pi-natives/src/fonts/), the ink variant (sentsix-hue sentence cycling orbwblack), line repetition (each text line printed N times, copies on a pale highlight band), and a target cell size — cells differing from the font's natural cell render via Lanczos3 stretch into an anti-aliased RGB frame (e.g. the OpenAI-optimal 6x6 unscii shape); native-cell shapes encode as 4-bit indexed PNG. Replaces the JS rasterizer/PNG writer previously in@oh-my-pi/pi-agent-core.
[15.10.12] - 2026-06-10
Added
- Added deterministic shell-output minimization to the native shell pipeline, including opt-in per-command rewrite telemetry surfaced through
executeShell().minimizedfor callers that want compact inline output plus a separately persisted original capture.
Fixed
- Fixed native crash-log directory resolution diverging from the JS logger when
PI_CONFIG_DIRis absolute: the config root now mirrorspath.join(homedir, PI_CONFIG_DIR)semantics (absolute values re-rooted under$HOME,./..components normalized), and an emptyPI_CODING_AGENT_DIRno longer disables XDG state-dir resolution. - Fixed shell-output minimization condensing
pyright/basedpyright--outputjsonruns into a diagnostics summary; machine-readable JSON output now passes through untouched. - Fixed
pi-nativesaborting Bun on Windows withmemory allocation of N bytes failedand no backtrace whenever the native cdylib hit a Rust panic or out-of-memory condition. The release profile usespanic = "abort", so neither default handler emitted any context — Bun received only the bare message and tore down the TUI session before flushing. Module load now installsstd::panic::set_hookandstd::alloc::set_alloc_error_hookvia#[napi::module_init]; both hooks captureBacktrace::force_capture()(so it works withoutRUST_BACKTRACE=1) and write a structured report — pid, thread, size/alignment for OOM, source location and message for panics, full backtrace — to the same logs directory the JS logger uses ($XDG_STATE_HOME/omp/logs/on Linux/macOS when the user has migrated to XDG andPI_CODING_AGENT_DIRisn't customized, otherwise~/.omp/logs/) and to stderr before the host process exits. The OOM hook prints the canonical allocation-failure line before any allocation-prone diagnostics and aborts immediately on re-entry, so real process-wide OOM still surfaces the fallback message instead of recursing in the report path (#2211).
[15.10.11] - 2026-06-10
Added
- Added a
maxCountPerFileoption togrepthat caps how many matches a single file may contribute, so one hot file can no longer exhaust the globalmaxCountbudget in path order and starve every file sorted after it out of the result set entirely. - Added
PI_DEBUG_STARTUPstreaming markers to the addon loader (native:loadNative:start,native:extractEmbeddedAddon:start,native:require:<file>,native:loadNative:done), written with synchronous stderr writes so a hang inside first-run extraction ordlopen()— which blocks the event loop and defeats any timer-based diagnostics — still leaves the failing step as the last marker on stderr. - Added a
skippedOversizedcount toGrepResult: directory walks now report how many files were silently skipped for exceeding the 4MB per-file grep limit (previously they vanished without a trace, letting callers conclude a symbol does not exist).
Changed
- Parallelized the mtime-ranked
glob()walk (the path OMPfindalways takes): per-thread bounded top-N heaps replace the single-threaded full-stat traversal, so large trees rank in a fraction of the wall clock while keeping the deterministic mtime-desc/path ordering and bounded memory.
Fixed
- Fixed cross-line grep being a silent no-op on real files:
multilineset the(?m)flag on the regex matcher but never enabledmulti_lineon theSearcher, which stayed line-oriented, so any pattern spanning a\nreturned zero matches with no error.
[15.10.5] - 2026-06-08
Added
- Added the
enclosingBlockBoundariesnative API (withEnclosingBoundaryOptionsandLineRangetypes) that returns, for a set of visible line ranges, the off-window boundary lines of every multi-line tree-sitter node whose span crosses the window — the closer when an opener is shown and the opener when a closer is shown. Covers brace and indentation languages (Python) via real syntactic spans; returnsnullfor unrecognized languages or sources with syntax errors so callers can fall back to a lexical scan. - Added a
nohupshell builtin to the embeddedpi_shell, shadowing the external/usr/bin/nohup. It runs its operand command and propagates that command's exit status (and reportsmissing operand/ exit 125 with no operand), but deliberately does not maskSIGHUPor detach the child into a new session the way realnohupdoes. Agents reach fornohup … &assuming the shell is one-shot; in this persistent embedded shell that assumption is wrong and the only effect of realnohupwas to leak background processes that outlived the host. The builtin keeps such commands as ordinary descendants so they are reaped with the host instead of surviving as orphans.
[15.10.2] - 2026-06-08
Added
- Added the
supermodifier tomatchesKey/parseKey/parseKittySequence. Key identifiers may now includesuper+(anywhere in the modifier prefix), and Kitty CSI-u sequences whose modifier mask contains the super bit (8) — e.g. Ghostty's macOS Option+BackspaceESC [127;11u— are now recognised instead of dropped (#2064).
Fixed
- Fixed the native
copyToClipboardleaving the X11 clipboard empty on Linux even while the process kept running. arboard answers clipboardSelectionRequests from a background thread that lives only as long as aClipboardinstance exists, and the binding dropped its transientClipboardimmediately afterset_text— tearing that thread down so the selection lost its owner and the clipboard read back empty (matching thereturned ok but clipboard=''symptom). The Linux path now holds a singleClipboardfor the lifetime of the process so the owner thread keeps serving, with noxclip/wl-copysubprocess; macOS/Windows keep the transient write on the calling thread (#2075).
[15.10.1] - 2026-06-07
Fixed
- Fixed
applyBashFixupscorrupting commands that contain multi-byte UTF-8 before a trailing| head/| tail(or2>&1).brush-parserreports source positions as Unicode-scalar (char) offsets, butpi_shell::fixupsliced the command&strby those numbers as if they were byte offsets, so each multi-byte char (e.g.✓/×in agrep -Epattern) shifted the cut earlier and left a mangled command — e.g.… |✓|×|XCTAssert" | tail -80became… |✓|×-80, orphaning the closing quote and making the shell reject the whole pipeline withunterminated double quote. Positions are now translated to byte offsets before slicing.
[15.9.0] - 2026-06-04
Fixed
- Bounded sorted
glob()scans tomaxResultsduring uncached traversal and emittedonMatchcallbacks only for entries admitted to the bounded top-maxResultsheap so broad OMPfindprogress and timeout partials stay consistent with the returned mtime-ranked set while keeping parent-process memory bounded (#1761). - Fixed
wrapTextWithAnsihanging (infinite loop) on text containing a BEL-terminated string escape — DCS/SOS/PM/APC (ESC P/ESC X/ESC ^/ESC _) closed byBELinstead ofST.ansi_seq_len_u16only accepted theST(ESC \) terminator for these (OSC already accepted both), so a BEL-terminated APC such as the TUI cursor marker (ESC _ pi:c BEL) was left unclassified: it was miscounted as visible width andbreak_long_word's non-ESC scan could not advance past theESC, spinning forever. The terminator set now matches OSC (ST or BEL), andbreak_long_worddefensively emits and steps over any escape it cannot classify so a malformed/unknown sequence can never wedge the wrap loop.
[15.7.0] - 2026-05-31
Added
- Added
blockRangeAtnative API along withBlockRangeandBlockRangeOptionstypes to return the 1-indexed line span of the outermost tree-sitter node beginning on a given line
Fixed
- Fixed an interactive shell inside a pipeline (
zsh -i ... | awk,time zsh -i | cat, etc.) suspending the embedded host withsuspended (tty input). The earlier embedded-host fixsetsid-detached external children so they could not seize the host's controlling tty, but carved pipeline stages out because a later stage thatsetpgid-joined a detached leader failed with EPERM — leaving every pipeline stage in the host session, where an interactive child opened/dev/tty,tcsetpgrp'd itself to the foreground, and stopped the host (OMP) on its next tty read.pi_shellnow detaches pipeline stages too:child_session_actionreturnsDetachSessionfor any non-terminal-stdin child regardless of pipeline membership, andexecute_external_commandskipsprocess_group(...)entirely for detached children so no cross-sessionsetpgidis attempted. Pipeline stages no longer share one process group, which the embedded host does not rely on (cancellation walks the descendant tree and pipes are session-independent).
[15.6.0] - 2026-05-30
Changed
- Changed npm publishing to ship
@oh-my-pi/pi-nativesas a small core loader package plus per-platform optional dependency leaf packages, so installs fetch only the host platform's native addon instead of every supported.nodebinary.
[15.5.10] - 2026-05-28
Fixed
- Fixed background bash jobs pinning the JS main thread at ~200% CPU when the child process emits output in many tiny writes (printf-style progress, llama-cli token streams).
pi_shell's pipe reader forwarded every chunk through a separateThreadsafeFunction::callper kernelread(2), so a chatty child produced millions of cross-thread napi callbacks that the JS main thread had to drain serially — even after the child exited, the queue kept the process saturated for seconds. The bridge now greedily coalesces every chunk already in the mpsc queue into a single batched call (capped at 64 KiB) before crossing into JS, collapsing 1-byte writes into one napi dispatch and bringing the steady-state callback rate back to the JS event-loop's throughput.
[15.5.9] - 2026-05-28
Changed
- Changed native addon extraction to skip re-extracting cached
.nodefiles when their size already matches embedded archive metadata - Changed standalone binaries to embed native addons as a compressed tarball and unpack them into the versioned native cache on first run instead of embedding each
.nodefile uncompressed.
Fixed
- Fixed CI native addon builds retaining ELF debug and symbol sections in release artifacts; stripped builds are now verified to reject
.debug_*,.zdebug_*,.symtab, and.strtabsections.
Security
- Hardened embedded addon archive extraction by rejecting unsafe entry names and non-file archive entries before writing binaries to disk
[15.5.4] - 2026-05-27
Added
- Added
Hashlineclass with methods to format headers, parse/apply hashline edits, split inputs, compute diffs, generate previews, and recover from stale hashes - Added
HashlineChunkerclass to stream UTF-8 text into numbered hashline chunks incrementally - Added
HashlineCursorKind,HashlineEditKind, andHashlineTokenKindexports for hashline cursor/edit/token discrimination - Added
unfoldUntilLinesandunfoldLimitLinesoptions toSummaryOptionsto control BFS unfold visibility with an optional hard cap
[15.5.0] - 2026-05-26
Fixed
- Fixed bash heredocs (
<<) and here-strings (<<<) deadlocking the shell on Windows past ~4 KiB and on macOS past 16-64 KiB.brush_core::interp::setup_open_file_with_contentswrote the entire body into an anonymous pipe synchronously before handing the reader to the next command; once the body exceeded the OS pipe buffer the writer blocked forever and thebashtool timed out at the hard 305 s ceiling without ever launching the consumer. The Linux fast path still usesF_SETPIPE_SZto grow the pipe in-place; every other OS-threaded platform (and Linux bodies abovepipe-max-size) now decouples the write onto a fire-and-forget thread that terminates naturally on drain orBrokenPipe; no-thread targets keep the upstream synchronous path so heredocs do not fail at thread spawn.
[15.3.2] - 2026-05-25
Fixed
- Fixed
matchesKeyclaimingctrl+m/ctrl+j/ctrl+i/ctrl+h/ctrl+[for the single bytes terminals emit for Enter/Tab/Backspace/Escape in legacy mode. Pressing Enter no longer triggers actrl+mbinding; the named keys now own those bytes and the collidingctrl+<letter>combinations only match when the terminal disambiguates via the Kitty keyboard protocol ormodifyOtherKeys. The same gate now also applies toctrl+alt+<letter>legacyESC + <ctrl-char>sequences (e.g.\x1b\ris Alt+Enter, not Ctrl+Alt+M). (#1354)
[15.0.2] - 2026-05-15
Added
- Added a per-release version sentinel napi export (
__piNativesV{major}_{minor}_{patch}). The Rustjs_nameis bumped in lock-step with the package version byscripts/release.ts; the JS loader computes the expected name frompackage.json#versionand throws an actionable error when the on-disk.nodedoesn't expose it. This converts the silent<sym> is not a functioncrash from a stale addon into a load-time failure pointing at the real fix. - Added
applyBashFixups(command)— a synchronous brush-parser-driven rewrite that strips trailing| head|tail …, redundant2>&1, and the|&shorthand from top-level pipelines, returning{ command, stripped }. Replaces the hand-rolled top-level mask scanner inpi-coding-agent; tokenization, quoting, heredocs, command substitution, and nested compound commands are now handled by the real shell AST instead of regex/character-walking. Lives inpi_shell::fixupon the Rust side.
Fixed
- Fixed
<sym> is not a functioncrashes on Windows afterbun install -g @oh-my-pi/pi-coding-agentupdates while anompprocess was running. Bun cannot overwrite a lockednode_modules/@oh-my-pi/pi-natives/native/pi_natives.win32-x64.nodeand silently keeps the old binary alongside the new ESM wrapper, so the next launch loads mismatched code. The loader now mirrors the addon into~/.omp/natives/<version>/on Windows npm installs and prefers that copy at load time — each version gets its own filesystem path, so future updates land innode_modulesunchallenged. The new version sentinel detects any remaining drift up front. - Fixed
$env:NAMEPowerShell references being collapsed to:NAMEwhen brush forwarded a command to a PowerShell (or any) subprocess.pi-shellnow definesenv=$envas a non-exported global on every brush session so the bash parameter expansion of$envyields the literal$env, leaving$env:NAMEintact. User-driven assignments (env=prod) push their own command-scope binding and shadow the fallback, preserving the bash POSIX contract. (#1079)
[15.0.1] - 2026-05-14
Breaking Changes
- Raised the minimum required Bun runtime version to >=1.3.14
- Removed
PhotonImageclass,ImageFormatenum, andSamplingFilterenum from native exports. General-purpose image decode/resize/encode now usesBun.Image, which ships in Bun 1.3.14+ with statically-linked libjpeg-turbo, libspng, and libwebp plus SIMD geometry kernels — same operations, zero native-addon footprint.encodeSixelstays (no Bun equivalent for the SIXEL terminal protocol). - Removed
webpRust workspace dependency along withPhotonImage's WebP encoder.
[14.9.9] - 2026-05-12
Breaking Changes
- Removed
projfsOverlayProbe,projfsOverlayStart, andprojfsOverlayStopoverlays APIs andProjfsOverlayProbeResulttype from the public natives interface
Added
- Added unified isolation APIs
isoBackend,isoProbe,isoResolve,isoStart,isoStop,isoDiff, andisoIsUnavailableErrorfor selecting, probing, resolving, starting, stopping, and diffing isolated filesystems - Added
IsoBackendKind,IsoChangeKind,IsoDiff,IsoFileChange,IsoProbeResult, andIsoResolveResulttype exports to describe isolation backend capabilities and diff outcomes
Changed
- Changed
nativeexports to remove the platform-specific ProjFS-only overlay surface in favor of generic isolation controls
[14.9.5] - 2026-05-12
Fixed
- Fixed shell cancellation occasionally killing the harness. The
pi_shelldescendant tracker harvested every descendant'spgidinto the kill set, so any subprocess that inherited the harness's pgid (any helper spawned via APIs that do not callsetpgid— sibling LSP/MCP processes, etc.) draggedharness.pgidinto the list and the follow-upkill(-harness.pgid, SIGTERM)terminated the harness alongside the targets. The classifier now only adopts apgidwhen its leader is itself one of the new descendants, andkill_process_grouprefuses the harness's own process group as a last-line defense. - Fixed macOS process-tree termination silently doing nothing. The descendant walk relied on
proc_listchildpids, which on recent darwin kernels (25.4+) returns no entries when a process queries its own children, soProcess::descendantscame back empty and tree-kill cleanup never reached grandchildren. The walk now builds a one-shotppid → [pid]map fromproc_listallpids+proc_pidinfo, matching the approach already used byfind_by_pathand the Windows Toolhelp path.
Changed
- Removed the 20 Hz background descendant tracker that scanned the harness's process tree for the entire lifetime of every shell command. Cancellation now does a small rescan-and-signal loop on demand (up to three waves — SIGTERM, then SIGKILL, then SIGKILL — with early exit as soon as no descendants remain). The previous tracker existed to pin process identities against PID reuse races, but
Process::from_pidalready pins identity by kernel start time / pidfd, so the constant scanning paid for nothing and added meaningful syscall load on macOS where each scan now doesproc_listallpids+proc_pidinfoper pid.
[14.9.3] - 2026-05-10
Added
- Added
idle,system, anduseroptions toMacOSPowerAssertionso callers can request specific macOS sleep-prevention modes (caffeinate -i,-s, and-u) in addition to the existingdisplayoption - Added support for combining multiple macOS power assertion flags in a single
MacOSPowerAssertionhandle
Changed
- Changed
MacOSPowerAssertion.stop()documentation to indicate it releases all held assertions and is safe to call repeatedly as a no-op
[14.9.2] - 2026-05-10
Added
- Added
listWorkspace, a native single-pass workspace walker that returns bounded tree entries and AGENTS.md directory-context candidates together.
[14.7.1] - 2026-05-06
Added
- Added
sizeproperty toGlobMatchfor regular files to expose their byte size
Changed
- Sped up native
grepfiles-with-matches searches by stopping after the first match per file, reading small files without mmap overhead, and relying on grep-searcher binary detection instead of a separate full-file NUL scan.
Fixed
- Fixed native
grepfilesWithMatchesmode sototalMatchesreports the number of matching files rather than line-match totals - Fixed native
grepcount-mode limits applying to files instead of matches, and restored timeout/abort cancellation checks for small native filesystem scans.
[14.7.0] - 2026-05-04
Added
- Added
summarizeCodefunction to expose native code summarization withkind,startLine,endLine, and optionaltextsegments plus parse/elision metadata - Added
minBodyLinesandminCommentLinesoptions tosummarizeCodeto control when function/body and multiline comment elision is applied - Added
SummaryOptionsandSummaryResultTypeScript definitions for typedsummarizeCodeinput and output
[14.6.1] - 2026-05-02
Changed
- Changed the native package loader from CommonJS analyzer-visible assignments to a template-rendered ESM entry point with explicit named exports
[14.5.13] - 2026-05-01
Changed
- Stopped overriding
CARGO_TARGET_DIRwith an internaltarget/napi-build/...directory during native builds, so Cargo now uses the default or caller-provided target directory - Simplified native build profile suffix formatting without changing
localandcivalues - Changed the native build output behavior to avoid setting an isolated Cargo target directory automatically
Removed
- Removed the host Zig CPU contract wrapper (
zig-safe-wrapper.ts) and itsZIG/PI_NATIVE_REAL_ZIG/PI_NATIVE_ZIG_TARGET/PI_NATIVE_ZIG_CPUenv handling, since thezlobRust dependency that required Zig is gone - Removed the
ci-release-verify-nativesscript and its AVX-512 marker scan from the release pipeline
[14.5.12] - 2026-04-30
Breaking Changes
- Changed
waitForExitto accept a single options object instead of a numeric timeout argument
Added
- Added a
signaloption toterminatefor cancelling termination while waiting for process shutdown - Added abort
signalsupport towaitForExitviaProcessWaitOptions - Added a
ProcessWaitOptionstype and updatedwaitForExitto accept an options object
[14.5.9] - 2026-04-30
Fixed
- Fixed shell minimizer output so successful commands whose noise is fully stripped still return
OKinstead of an artifact-only result
[14.5.6] - 2026-04-29
Added
- Added shell minimizer support for CMake, CTest, Ninja, GoogleTest binaries, and Bun/Bunx wrappers that run those tools
[14.5.2] - 2026-04-26
Changed
- Changed local native build profile from
devtolocalfor non-CI builds, updating the profile used by the build and local build output label
[14.4.2] - 2026-04-26
Removed
- Removed the
chunknapi module (ChunkState, chunk schema, chunk rendering, chunk edit) and droppedgenerate_chunk_schema()from the build script
[14.3.0] - 2026-04-25
Added
- Added
texttoMinimizerResultso consumers can replace rewritten output with the minimized replacement text - Added
settingsHashtoMinimizerOptionsto verify the minimizersettingsPathcontents against a xxHash64 digest before applying them - Added
minimizedoutput telemetry viaMinimizerResultonShellExecuteResultandShellRunResult, exposing the applied minimizer filter and original/minimized byte counts when output is rewritten - Added a new
minimizeroption toShellExecuteOptionsandShellOptionsto configure per-command output minimization - Added the
MinimizerOptionsAPI with controls for enabling minimization, overriding settings viasettingsPath, allow/deny lists (only,except), andmaxCaptureBytescapture limits
Changed
- Changed the shell output minimizer to more aggressively compact successful test runs, git output, large listings, grep/find results, source reads, and dependency manifests
- Changed compound and piped shell commands to bypass output minimization entirely, keeping minimization limited to eligible whole-command output after the command exits
Fixed
- Fixed chunk edit batches so later operations can reuse an initially validated checksum after an earlier operation changes that same chunk
Removed
- Removed
PI_DEVloader diagnostic env var and associated console logging in the native addon loader
Security
- Added trust-gated loading for minimizer settings by requiring a matching
settingsHashbefore accepting a settings file
[14.2.0] - 2026-04-23
Added
- Added Dart support to
astGrepandastEditthrough the native tree-sitter Dart grammar (#748 by @0fflineuser)
[14.1.1] - 2026-04-14
Added
- Added support for honoring the
ZIGenvironment variable when resolving the Zig executable for native builds
Removed
- Removed the
SearchDbAPI from the natives type declarations - Removed the optional
dbparameter fromfuzzyFind,glob, andgrep - Removed the
fuzzyFind,glob, andgrepcache database argument previously used for search state
[14.0.5] - 2026-04-11
Breaking Changes
- Made
tabWidthparameter required (no longer optional) forvisibleWidth,truncateToWidth,wrapTextWithAnsi,sliceWithWidth, andextractSegments - Removed
getIndentation,getDefaultTabWidth, andsetDefaultTabWidth(moved to@oh-my-pi/pi-utils) visibleWidth,truncateToWidth,wrapTextWithAnsi,sliceWithWidth, andextractSegmentsnow require an explicittabWidthargument
[14.0.4] - 2026-04-10
Added
- Added
normalizeIndentoption toEditParamsto control indentation normalization for response rendering and inserted content - Added
hasConflicts()method to detect unresolved merge conflicts in parsed files - Added
conflictCount()method to count unresolved merge conflicts in the chunk tree
[14.0.2] - 2026-04-09
Added
- Added
Declvariant toChunkRegionenum for accessing semantic declarations without leading trivia - Added
check:typesscript for explicit TypeScript type checking - Added
lintscript for running Biome linter - Added
fmtscript for code formatting with Biome - Added package exports field with typed entry point configuration
- Added turbo.json configuration for build task caching and optimization
Changed
- Renamed
build:nativescript tobuildfor simpler invocation - Updated
checkscript to separately callcheck:typesfor type checking - Modified tsconfig.json to extend
tsconfig.workspace.jsoninstead oftsconfig.base.json
[14.0.0] - 2026-04-08
Breaking Changes
- Changed
ChunkRegion.Innerenum value toChunkRegion.Bodyto align with region semantics - Changed
ChunkRegionenum values fromContainer,Prologue,Body,EpiloguetoHead,Inner,Tailwith updated semantics for region targeting - Replaced
ChunkEditOpenum values —AppendChild,PrependChild,AppendSibling,PrependSibling, andReplaceBodyare nowBefore,After,Prepend, andAppendwith updated semantics for region-scoped operations - Removed
ReplaceBodyoperation — useReplacewithregion: ChunkRegion.Bodyto replace only chunk body content - Moved package entry point from
src/index.tstonative/index.js— consumers must update imports to use the new native module path - Removed TypeScript source files from
src/directory — all APIs now exported from auto-generatednative/index.jswith types innative/index.d.ts - Changed enum exports to runtime objects —
const enumvalues are now available at runtime via generated enum exports innative/index.js
Added
- Added
ChunkRegionenum withContainer,Prologue,Body, andEpiloguevalues for targeting specific regions within chunks - Added
regionparameter toEditOperationto specify which chunk region to target (defaults toContainer) - Added
UnsupportedRegionstatus toChunkReadStatusenum to indicate when a chunk does not support the requested region - Added
normalizeIndentparameter toRenderParamsandReadRenderParamsto normalize displayed indentation to canonical tabs - Added
ReplaceBodychunk edit operation to replace only the inner body of a chunk while preserving signature and closing delimiter - Added
ChunkFocusModeenum withExpanded,Collapsed, andContainermodes for controlling chunk participation in focus-scoped render passes - Added
FocusedPathinterface to pair paths with focus modes for the N-API boundary - Added
focusedPathsparameter toRenderParamsto restrict rendering to specified chunks with their focus modes - Generated native module bindings in
native/index.jsandnative/index.d.tsfrom napi-rs build output - Added
gen-enums.tsscript to extract and export runtime enum values from TypeScript const enums - Added
embedded-addon.jsfor managing embedded native addon variants and metadata - Added
MacOSPowerAssertionfor session-scoped macOS idle-sleep prevention without shelling out
Changed
- Changed
ChunkInfo.namefield to optionalidentifierfield — now provides bare chunk identifier without kind prefix instead of display name - Updated
regionparameter documentation inEditOperationto clarify full chunk targeting when omitted instead of container-scoped default - Updated
ChunkEditOpdocumentation to reflect region-scoped semantics — operations now target specific regions rather than chunk structure positions - Changed
ChunkEditOp.Replacedocumentation to clarify substring replacement viafindparameter instead of line-based replacement - Changed
EditOperationinterface to usefindparameter for scoped find/replace operations instead oflineandendLineparameters - Changed
EditParamsdocumentation to remove mention of scheduling reordering for line-scoped groups - Simplified native build pipeline by removing
--devflag support; debug builds no longer available through npm scripts - Updated native module loader to check
XDG_DATA_HOMEenvironment variable for native addon location before falling back to~/.omp/natives - Removed native binding validation function that checked for required exports at load time
- Refactored build pipeline to use napi-rs generated bindings instead of hand-written TypeScript wrappers
- Updated
build-native.tsto generate runtime enum exports after native compilation - Updated
embed-native.tsto output JavaScript instead of TypeScript for embedded addon metadata
Removed
- Removed
dev:nativenpm script — usebuild:nativefor all build scenarios - Removed inline pi-utils helpers and dependency on
@oh-my-pi/pi-utilsfrom native module loader - Removed
logger.time()wrapper calls from native module loading - Removed all TypeScript wrapper modules from
src/directory (appearance, ast, chunk, clipboard, glob, grep, highlight, html, image, keys, projfs, ps, pty, shell, text, work) - Removed
src/bindings.tsandsrc/index.tsentry points - Removed
src/search-db.tsandsrc/search-db-types.ts
[13.16.1] - 2026-03-27
Added
- Exported
SearchDbclass from main package entry point for direct instantiation - Added
SearchDbclass for stateful shared search database instances to improve performance across multiple search operations - Added optional
dbparameter togrep(),glob(), andfuzzyFind()functions to enable database-backed searching
Changed
- Updated
grep(),glob(), andfuzzyFind()function signatures to accept optionaldbparameter for database-backed searching
[13.12.0] - 2026-03-14
Breaking Changes
- Changed
abort()method signature: removed optionalreasonparameter and changed return type fromvoidtoPromise<void>
[13.4.0] - 2026-03-01
Breaking Changes
- Changed
AstFindOptions.patterntopatterns(now accepts array of strings instead of single string) - Replaced
AstReplaceOptions.patternandrewritewith singlerewritesoption (Record<string, string>)
Added
astGrepnow accepts multiple patterns in a single call; results from all patterns are merged and sorted by file path then position before offset/limit are appliedastEditnow accepts arewritesmap (Record<string, string>) and applies all patterns per file in a single pass, compiling them once upfront- Result ordering in
astGrepis now deterministic: sorted by path, line, column usingBTreeSet/BTreeMap
[13.3.8] - 2026-02-28
Added
- Added
astFind()function for structural code search using AST patterns with support for language-specific matching, selectors, and meta-variable extraction - Added
astReplace()function for structural code rewriting with dry-run mode, replacement limits, and parse error handling - Added
./astexport path for accessing AST search and rewrite functionality
[12.18.0] - 2026-02-21
Changed
- Replaced custom
TextDecoderusage with nativetoString('utf-8')for buffer decoding - Replaced custom debug logging with structured
logger.time()calls for startup performance tracking
[12.17.1] - 2026-02-21
Added
- Expanded package exports to support subpath imports for clipboard, glob, grep, highlight, html, image, keys, ps, pty, shell, text, and work modules
- Added wildcard export patterns (
./*) for all submodules to enable flexible import paths
Changed
- Updated package description to clarify native bindings for grep, clipboard, image processing, syntax highlighting, PTY, and shell operations
- Expanded package keywords to include clipboard, image, pty, shell, and syntax-highlighting for better discoverability
- Added README.md to package distribution files
[12.10.0] - 2026-02-18
Changed
- Updated addon filename resolution to include default filename fallback in both modern and baseline variant paths
[12.8.2] - 2026-02-17
Breaking Changes
- Removed
getSystemInfo()andSystemInfofrom package exports, breaking consumers that imported system info APIs from this package
[12.8.0] - 2026-02-16
Added
- Added support for x64 CPU variant selection with
TARGET_VARIANTenvironment variable (modern/baseline) during build to optimize for specific ISA levels - Added automatic AVX2 detection on Linux, macOS, and Windows to select optimal native addon variant at runtime
- Added
PI_NATIVE_VARIANTenvironment variable to override CPU variant selection at runtime - Added support for multiple native addon variants per platform (modern with AVX2, baseline without AVX2) for improved performance portability
Changed
- Changed native addon filename scheme to include CPU variant suffix for x64 builds (e.g.,
pi_natives.linux-x64-modern.node) - Changed embedded addon structure to support multiple variant files per platform instead of single file
- Changed native addon loader to automatically select appropriate variant based on CPU capabilities or explicit override
- Changed build output to include variant information in console messages
Removed
- Removed fallback untagged
pi_natives.nodebinary creation for native builds; platform-tagged variants are now required
Fixed
- Fixed regex patterns containing literal braces (e.g.
${platform}) failing with "repetition quantifier expects a valid decimal" by escaping{/}that don't form valid repetition quantifiers
[12.5.0] - 2026-02-15
Added
- Added
recursiveoption toGlobOptionsto control whether simple patterns match recursively (defaults to true)
Changed
- Changed default glob pattern behavior to always use recursive matching for simple patterns instead of requiring explicit
**/prefix - Updated
fileTypefilter documentation to clarify that symlinks match file/dir filters based on their target type
[12.4.0] - 2026-02-14
Added
- Exported
sanitizeTextfunction to strip ANSI codes, remove binary garbage, and normalize line endings in text output
[12.1.0] - 2026-02-13
Added
- Added
cacheoption toglob(),grep(), andfuzzyFind()to enable shared filesystem scan caching - Added
invalidateFsScanCache()function to manually invalidate filesystem scan cache entries
[11.14.0] - 2026-02-12
Added
- Added
PtySessionclass for PTY-backed interactive command execution with streaming output - Added
PtyStartOptionsinterface to configure pseudo-terminal sessions with command, working directory, environment variables, and terminal dimensions - Added
PtyRunResultinterface to report command exit code, cancellation, and timeout status - Added
write()method to send raw input to PTY stdin - Added
resize()method to dynamically adjust PTY column and row dimensions - Added
kill()method to force-terminate active commands
[11.3.0] - 2026-02-06
Added
- OSC 52 fallback for clipboard operations over SSH/mosh connections
- Termux support with
termux-clipboard-setintegration - Headless environment guards to prevent clipboard errors when no display server is available
- Async clipboard API with improved error handling and fallback strategies
Changed
- OSC 52 clipboard emission now only occurs in real terminal environments (when stdout is a TTY), preventing unnecessary output in piped or headless contexts
- Improved error handling for OSC 52 writes to gracefully handle EPIPE errors when stdout is closed or piped to processes that exit early
- Clipboard functions now return promises for better async handling
- Native clipboard operations are now best-effort with graceful degradation
[11.0.0] - 2026-02-05
Removed
- Removed legacy type aliases
WasmMatchandWasmSearchResult
[10.6.0] - 2026-02-04
Changed
- Added separate grep context before/after options in bindings
[10.2.2] - 2026-02-02
Added
- Exported
getWorkProfilefunction andWorkProfiletype for work profiling capabilities
[10.2.0] - 2026-02-02
Breaking Changes
- Replaced
find()withglob()- update imports and function calls - Changed file type filtering from string values to
FileTypeenum - Removed
abortShellExecution()function - useShell.abort()method instead - Removed
RequestOptionsparameter fromhtmlToMarkdown()- pass options directly
Added
- Added
glob()function for file discovery with glob pattern matching and .gitignore support - Added
Cancellableinterface for timeout and abort signal support across async operations - Added
FileTypeenum to filter glob results by file type (File, Dir, Symlink) - Added
signalparameter to shell operations for cancellation via AbortSignal
Changed
- Renamed
find()toglob()for file discovery operations - Renamed
FindMatchtoGlobMatchandFindOptionstoGlobOptions - Moved timeout and abort signal handling into unified
Cancellableinterface across grep, glob, and shell modules - Updated
Shell.abort()to accept optional abort reason parameter - Simplified
htmlToMarkdown()signature by removingRequestOptionsparameter
Removed
- Removed
RequestOptionstype andwrapRequestOptions()utility function - Removed
abortShellExecution()function; useShell.abort()instead - Removed
executionIdparameter fromShellExecuteOptions
[10.1.0] - 2026-02-01
Breaking Changes
- Changed
executionIdparameter type fromstringtonumberinabortShellExecution()andShellExecuteOptions - Removed
sessionKeyfield fromShellExecuteOptions
Added
- Added
getWorkProfile()function to retrieve work scheduling profiling data from a circular buffer of recent activity - Added
WorkProfiletype with folded stack format, markdown summary, SVG flamegraph, and sample metrics for profiling results
[9.8.0] - 2026-02-01
Breaking Changes
- Removed
resize()function; usePhotonImage.resize()method instead - Removed
terminateImageWorker()function - Changed
PhotonImage.new_from_byteslice()toPhotonImage.parse() - Changed
PhotonImage.get_bytes()toencode(ImageFormat.PNG, 100) - Changed
PhotonImage.get_bytes_jpeg(quality)toencode(ImageFormat.JPEG, quality) - Removed
get_width()andget_height()methods; usewidthandheightproperties instead - Removed manual resource management via
free()andSymbol.dispose
Added
- Added automatic extraction of embedded native addon to
~/.omp/natives/<version>on first run for compiled binaries - Added
embed:nativebuild script to embed platform-specific native addon payloads into compiled binaries - Exported
Shellclass for creating persistent shell sessions withrun()method and session options - Exported
ShellOptions,ShellRunOptions, andShellRunResulttypes for shell session management - Exported
find()function for file discovery with glob patterns and .gitignore support - Exported
FindOptions,FindMatch, andFindResulttypes for file search operations - Exported
ImageFormatenum for specifying output formats (PNG, JPEG, WEBP, GIF) in image encoding - Added
ImageFormatenum for specifying output format (PNG, JPEG, WEBP, GIF) inencode()method - Added
SamplingFilteras exported enum instead of object - Added
Shellclass with persistent session options (sessionEnv,snapshotPath) and arun()command API - Exported
getSystemInfo()function andSystemInfotype for retrieving system information including distro, kernel, CPU, and disk details - Exported
copyToClipboard()andreadImageFromClipboard()functions for clipboard operations - Exported
ClipboardImagetype for clipboard image data with MIME type information - Added
wrapTextWithAnsi()function to wrap text to a visible width while preserving ANSI escape codes across line breaks - Added native clipboard helpers for copying text and reading images via arboard
Changed
- Enhanced native addon loading to prioritize extracted embedded addon for compiled binaries before falling back to system paths
- Improved error messages to provide platform-specific guidance for addon loading failures, including manual download instructions for compiled binaries
- Reorganized native bindings into modular type files with declaration merging via
NativeBindingsinterface - Moved type definitions from implementation files to dedicated
types.tsmodules for better separation of concerns - Enhanced
SystemInfotype with additional fields:os,arch,hostname,shell,terminal,de,wm, andgpu - Refactored module exports to use direct destructuring from native bindings instead of wrapper functions
- Changed
PhotonImageAPI to use instance methods (resize(),encode()) instead of standalone functions - Changed
PhotonImageto use property accessors forwidthandheightinstead of getter methods - Embedded native addon payload for compiled binaries and extract to
~/.omp/natives/<version>on first run
[9.7.0] - 2026-02-01
Added
- Exported
killTreefunction to kill a process and all its descendants using platform-native APIs - Exported
listDescendantsfunction to list all descendant PIDs of a process - Added
dev:nativenpm script to build debug native binaries with--devflag - Added
OMP_DEVenvironment variable support for loading and debugging development native builds - Exported keyboard parsing and matching functions:
parseKey,parseKittySequence,matchesLegacySequence, andmatchesKeyfor terminal input handling - Exported
KeyEventTypeenum andParsedKittyResulttype for Kitty keyboard protocol support - Added
parseKeyfunction to parse terminal input and return normalized key identifiers (e.g., "ctrl+c", "shift+tab") - Added
parseKittySequencefunction to parse Kitty keyboard protocol sequences with codepoint, modifier, and event type information - Added
matchesLegacySequencefunction to match legacy escape sequences for specific keys - Added
matchesKeyfunction to match input against key identifiers with support for modifiers and Kitty protocol
Changed
- Modified native binary build process to support both debug and release builds via
--devflag - Updated native binary search to prioritize platform-tagged builds and separate debug/release candidates
- Changed debug builds to output to
pi_natives.dev.nodeinstead of mixing with release artifacts - Improved native binary installation to use atomic rename operations and better fallback handling for Windows DLLs
- Reordered native binary search candidates to prioritize platform-tagged builds and avoid loading stale cross-compiled binaries
- Enhanced cross-compilation detection to prevent installing wrong-platform fallback binaries during cross-compilation builds
Fixed
- Fixed potential issue where cross-compiled binaries could overwrite platform-specific native builds with incorrect architecture binaries
[9.6.4] - 2026-02-01
Breaking Changes
- Changed callback signature for
find()andgrep()streaming callbacks to receive(error, match)instead of(match)for proper error handling
[9.6.2] - 2026-02-01
Breaking Changes
- Renamed
EllipsisKindenum toEllipsis - Changed
TextInputtype parameter tostringintruncateToWidth(),visibleWidth(),sliceWithWidth(), andextractSegments()functions—Uint8Array is no longer accepted - Removed
TextInputtype export from public API
Added
- Added
visibleWidth()function to measure the visible width of text, excluding ANSI codes
Changed
- Reordered native module search paths to prioritize repository build artifacts
- Improved JSDoc documentation for
truncateToWidth()with clearer parameter descriptions and behavior details - Added early return optimization in
truncateToWidth()to skip native call when text fits within maxWidth and padding is not requested - Added early return optimization in
sliceWithWidth()to return empty result when length is zero or negative
Removed
- Removed validation checks for
PhotonImageandSamplingFilternative exports - Removed early return optimization in
truncateToWidth()when text fits within maxWidth
[9.6.1] - 2026-02-01
Added
- Added
matchesKittySequencefunction to match Kitty protocol sequences for codepoint and modifier
Removed
- Removed
visibleWidthfunction from text utilities
[9.6.0] - 2026-02-01
Added
- Support for cross-compilation via
CARGO_BUILD_TARGETenvironment variable - Support for overriding platform and architecture detection via
TARGET_PLATFORMandTARGET_ARCHenvironment variables
Changed
- Native build script now searches for release artifacts in target-specific directories when cross-compiling
[9.5.0] - 2026-02-01
Added
- Added
sortByMtimeoption toFindOptionsto sort results by modification time (most recent first) before applying limit - Added streaming callback support to
grep()function via optionalonMatchparameter for real-time match notifications - Exported
RequestOptionstype for timeout and abort signal configuration across native APIs - Exported
fuzzyFindfunction for fuzzy file path search with gitignore support - Exported
FuzzyFindOptions,FuzzyFindMatch, andFuzzyFindResulttypes for fuzzy search API - Added
fuzzyFindexport for fuzzy file path search with gitignore support
Changed
- Changed
grep()andfuzzyFind()to support timeout and abort signal handling viaRequestOptions - Updated
GrepOptionsandFuzzyFindOptionsto extendRequestOptionsfor consistent timeout/cancellation support - Refactored
htmlToMarkdown()to support timeout and abort signal handling
Removed
- Removed
grepDirect()function (usegrep()instead) - Removed
grepPool()function (usegrep()instead) - Removed
terminate()export from grep module - Removed
terminateHtmlWorkerexport from html module
Fixed
- Fixed potential crashes when updating native binaries by using safe copy strategy that avoids overwriting in-memory binaries