- Introduced `StreamWriter` with configurable block and line buffering policies across builtins.
- Updated pipeline stages and compound commands to execute concurrently as tasks.
- Replaced Linux splice and local stream wrapping with generic `Write` streams and explicit flushing.
- Added regression and streaming smoke tests to verify concurrent output and prevent deadlocks.
Addresses a broad audit of built-in shell utilities against their real counterparts: timeout gains signal delivery, -s/-k/--preserve-status/--foreground/-v, and GNU exit codes; diff defaults to normal format and gains -w/-b/-B/-i/-c/-x/-L/-s/--strip-trailing-cr and proper -r gating; find fixes -newerXY timestamp comparison direction, anchors -regex to whole paths, and gains BSD -perm +mode, -type lists, -size T/P suffixes, -E/-x/-s flags; date gains BSD -r epoch, -v adjustments, -j -f strptime, and non-greedy -I; tail/head accept obsolete -N/+N at any position with any file count; rg resolves case flags by last occurrence and gains --path-separator and clean -0 output; stat prints integer epochs for %X/%Y/%Z and gains BSD -s/-x/-t; cksum is registered as a builtin; truncate implements -o/--io-blocks and b/= size suffixes; sleep/timeout accept infinity; yes/errno/kill accept hyphen-prefixed operands; nohup -- cmd no longer runs --; which gains BSD -s.
- Replaced the `ctok` implementation with the `utok` universal tokenizer supporting multiple model families and UTF text encodings.
- Added tokenizer support and embedding data for Qwen3, DeepSeek V3, Kimi K2, and GLM-5 model variants.
- Added fixture generation scripts, vocabulary packers, and golden test suites for validating tokenization parity.
- Updated dependency requirements and Bazel workspace definitions for new crates and tools.
- Implemented the `ctok` Rust native tokenization engine with offline support for Claude V3, V47, V5, and V5Sonnet families.
- Replaced global token estimation with model-scoped `Tokenizer` instances and provider-anchored transcript accounting across packages.
- Added vocabulary generation scripts, test fixtures, and comprehensive unit tests for tokenizer routing and matching modes.
The default snapcompact frame fonts (X.org 8x13 for every provider, plus the selectable 6x12 and legacy 5x8) drew digit zero as a bare oval visually indistinguishable from letter O. Image-based compaction OCRs the frames back, so 0 and O were mixed up and compacted identifiers (e.g. Slack IDs) got corrupted.
Zero now carries a disambiguating interior mark the O lacks: an ascending slash in 8x13 and a center bar in 6x12/5x8. unscii-8 (8x8/6x6u shapes) already shipped a slashed zero and is unchanged.
Fixes#8713
- Added live tracking and stale status warnings for agent activity snapshots.
- Fixed text wrapping with ANSI escape sequences to defer style open sequences after whitespace.
- Added VirtualRenderScheduler for deterministic virtual-clock rendering tests.
- Kept ANSI sequences after visible content with the current wrap token so closing resets cannot migrate into discarded whitespace.
- Added a regression for a codespan ending exactly at the wrap width.
Fixes#8582
- Replaced the custom MuPDF-WASM PDF extraction and rendering pipeline with the new `pdfToMarkdown` native function from `@oh-my-pi/pi-natives`.
- Removed legacy MuPDF extraction modules, WASM embedding scripts, and PDF image extraction tools.
- Added OCR warnings and browser/text redirection for unsupported PDF image reads.
- Updated native package definitions, documentation, and test suites for the new PDF inspection capability.
-[DCDevice isSupported] synchronously opens an XPC connection to the per-user DeviceCheck metadata daemon, which exists only in an interactive GUI login session. From a session without graphic access (SSH, launchd LaunchDaemon, CI runner, service account, sandbox) the connection setup hits _xpc_api_misuse and aborts the process with SIGTRAP before any completion handler runs, so the promise never rejects and every openai-codex/* OAuth model becomes unusable.
Check the caller's security session for the sessionHasGraphicAccess attribute via SessionGetInfo before touching DeviceCheck; resolve { supported: false, error } when it is absent, mirroring the non-macOS stub and letting the caller send an error-coded attestation instead of dying.
Fixes#8353
The shipped win32-x64 pi_natives addon linked the dynamic MSVC CRT (/MD)
and imported VCRUNTIME140.dll from the Visual C++ Redistributable, which
is absent on a clean Windows install. LoadLibrary of the extracted .node
then failed with error 126 ("The specified module could not be found"),
so omp could not start after a fresh `irm install.ps1 | iex`.
Static-link the CRT for the win32 addon: +crt-static for rustc (crate
BUILD select) plus the static_link_msvcrt cc feature enabled for win32 in
the native_addon transition, so its C deps (opus/cmake, tree-sitter,
blake3, ring) compile /MT in lock-step. The rebuilt .node imports only
core Windows system DLLs -- no VCRUNTIME140.dll, no api-ms-win-crt-*.
Fixes#8439
- Add comprehensive Nix flake definitions, derivations, modules, and CI workflows.
- Update tests and executables to resolve binaries from PATH rather than absolute paths.
- Ensure byte reproducibility and zeroed timestamps in embedded dashboard archives.
- Add handling for Nix-managed installations in CLI update checks.
- zune-jpeg 0.5.15 (image 0.25's JPEG decoder) cannot compile with its
non-default log feature off: zune-core's no-log warn! stub is not
expression-safe. A feature-activation-only workspace dep on
zune-jpeg { features = ["log"] } fixes the cold build; log stays 0.4.33.
- model-registry-default-config's local ModelSnapshot type gains the optional
streamIdleTimeoutMs the Bedrock watchdog compat now emits.
- Tracked pointer and keyboard grants from the RemoteDesktop response.
- Drained asynchronous EIS announcements after the first resumed device.
- Covered GNOME's keyboard-before-pointer ordering with a regression test.
Fixes#7926
Follow-up head of the same PR, merged after the sweep landed cf5bd72877:
bounds the consent-denied portal close inline (a nested block_on would panic)
and removes the world-readable pre-#7884 RemoteDesktop restore token.
Pre-#7884 builds wrote a world-readable RemoteDesktop restore token under $XDG_STATE_HOME/omp/remote-desktop-token during read-only calls, and nothing on the fixed tree reads, rewrites, or removes it. WaylandBackend::new now unlinks it best-effort on construction so the stale credential does not survive the upgrade.
Fixes#7884
The SelectDevices/Start/ConnectToEIS failure arm closes the RemoteDesktop session from inside runtime.block_on, so it cannot use close_session (a nested block_on panics). Bounded it with an inline tokio::time::timeout(CLOSE_TIMEOUT, ...) so a frozen xdg-desktop-portal on the ordinary denied-consent path no longer hangs the worker thread.
Fixes#7884
Bounded the RemoteDesktop close in Libei::drop with CLOSE_TIMEOUT so an unresponsive xdg-desktop-portal cannot hang worker teardown past the surrounding close budget.
Closed the portal session when ei::Context::new fails after Start/ConnectToEIS, the one init path that previously dropped the session without revoking the grant.
Fixes#7884
Merged PR #7889 into the lazy Wayland input branch. Portal sessions retain the shared process runtime, the portal module remains available in shipped builds, and only PipeWire token helpers are feature-gated.
Kept the portal module available in shipped builds while feature-gating only PipeWire token storage. Libei portal sessions now retain the shared process runtime and still close explicitly on teardown.
capture.rs still constructed the PipeWire main loop and context via the
0.8 owning constructors (MainLoop::new / Context::new / connect_fd),
which pipewire 0.9.2 removed in favour of the Rc handle types. The
migration was partial — StreamBox::new was already 0.9 — so the
wayland-pipewire feature failed to compile with E0599.
Switch to MainLoopRc::new / ContextRc::new(&loop, None) / connect_fd_rc.
The downstream call sites are unchanged: MainLoopRc derefs to MainLoop
(run/quit/clone), ContextRc derefs to Context, and CoreRc derefs to
Core so StreamBox::new(&core, ...) still coerces.
Fixes#7885
Deferred libei and RemoteDesktop setup until the first native input operation. Read-only capability, window, display, and AX calls no longer request keyboard or pointer access.
Used non-persistent portal grants and retained the portal session so backend teardown closes it explicitly.
Fixes#7884
ashpd caches a process-global D-Bus connection whose I/O tasks bind to whichever runtime first creates it. Libei::portal_context() built a short-lived current_thread runtime and dropped it when Libei::new() returned, orphaning that connection; capture() then built its own runtime and reused the dead connection, so PipeWire capture never delivered a frame whenever libei input init ran first.
Route both portal_context() and capture() through a shared long-lived multi-thread runtime held in a LazyLock, keeping the cached connection's I/O alive for the process lifetime.
Fixes#7886
Configured Quartz event sources to permit local hardware events in both suppression states and replaced Enigo-backed global posting with the configured source.
Added a macOS regression test for the event-source suppression settings.
Fixes#7872