Commit Graph

1034 Commits

Author SHA1 Message Date
can1357 9bc810b36c style: cargo fmt for snapcompact zero-glyph regression assert 2026-08-19 01:48:19 +02:00
can1357 9200fb3426 Merge PR #8928: fix: skip non-UTF-8 host env entries instead of panicking at startup (@STRML) 2026-08-19 01:39:17 +02:00
can1357 b66166a43b Merge PR #8848: perf(pi-ast): cache parsed trees and prune subtrees that cannot hold a boundary (@alphastorm) 2026-08-19 01:36:59 +02:00
can1357 0d50c53d4c Merge PR #8715: fix(snapcompact): disambiguate digit zero from letter O in frame fonts (@roboomp) 2026-08-19 01:36:03 +02:00
Samuel Reed 46f31296a1 fix: skip non-UTF-8 host env entries instead of panicking at startup
std::env::vars() panics the moment a host env key or value is not valid
Unicode, before any command can run. A corrupt GHOSTTY_BIN_DIR (bytes 9d d9 50)
staged by cmux/Ghostty tripped both sinks:

- pi-shell's session env copy in create_session_for_run (also merged PATH)
- brush-core's get_host_env_vars, which process builtins (sleep, timeout,
  pgrep, ...) use to inherit the host env into the shells they build

Both now read via std::env::vars_os() and skip entries that cannot be decoded
as Unicode: a corrupt entry carries no usable meaning. PATH merge behavior is
unchanged. Regression tests inject a non-UTF-8 key and value and assert the
shell still starts and PATH survives.

Reported in issue #8925.
2026-08-18 16:18:59 -04:00
Sunil Srivatsa 9169ac5c52 perf(pi-ast): prune subtrees that cannot hold a block boundary
collect_boundaries walked every node in the file even though the answer is
bounded by the visible window, which cost roughly twice the parse: on an
81KB source the walk was 8.95ms against a 4.32ms parse, and on 1MB it was
138.8ms against 87.6ms.

A node contributes a boundary only when one of its own endpoint lines is
visible, and both of those lines lie inside its raw row span. Every
descendant's span is contained in its ancestor's, so a span holding no
visible line rules out that node and everything beneath it. Skip such
subtrees with a binary search over the merged visible ranges.

The test is the raw span, not endpoint visibility: a node whose span merely
straddles the window has both endpoints outside it yet can contain a child
that opens exactly on a visible line. The raw span is also conservative
relative to node_content_end_line, so the prune needs no reasoning about
that newline adjustment.

Equivalence is proven differentially rather than argued: the pre-prune walk
is retained under cfg(test) and compared for exact Option<Vec<u32>> equality
across 4827 .ts/.py/.rs files and 38,616 comparisons over eight window
shapes, including whole-file-visible, past-EOF, disjoint ranges, empty range
lists and files that fail to parse. Zero mismatches. root.has_error() is
still evaluated on the whole tree before the walk, so pruning cannot change
a None verdict.

Measured on the built addon with a mid-file 40-line window, medians of 20,
against the parse cache alone: 81KB 13.4ms -> 4.45ms cold and 9.04ms ->
0.149ms warm; 1.06MB 188.1ms -> 55.8ms cold and 131.7ms -> 0.440ms warm.
2026-08-17 12:57:59 -07:00
Sunil Srivatsa 010eda7834 perf(pi-ast): cache parsed trees by content and language
`enclosing_block_boundaries`, `block_range_at` and `summarize_code` each
re-parsed the whole file on every call. The results are not cacheable —
boundaries depend on the caller's visible ranges, which differ per call —
but the `tree_sitter::Tree` is, so cache that instead and hand out
`ts_tree_copy` clones.

Keyed on (xxh64 of the source, source length, language). The hash is a
bucket selector only: a hit re-verifies the stored source against the
request byte-for-byte before returning the tree, so a collision costs a
re-parse and can never yield a tree built from other content. Language is
in the key because the same bytes parsed as TypeScript and as Python are
different trees.

Bounded at 12 slots and 4 MiB of retained source with LRU eviction;
sources above 4 MiB are parsed but never retained. `Tree` is `Send` but
not `Sync`, so entries sit behind a `Mutex` that is held only for a map
probe, a byte compare and a refcount bump, never across a parse or walk.

Error trees are cached like any other: `has_error()` is a property of the
tree, so the callers' own checks reach an identical verdict from a cached
tree, and repeated "does this parse" probes get the speedup too.

Measured (M4 Max, bazel-built .node, median of 20, 1-40 visible):
read.ts 81 KB 13.34 ms -> 8.86 ms on repeat; 1 MB synthetic 225.7 ms ->
138.3 ms. Parser::new + set_language measured at 0.30 us against a
3.91 ms parse, so no parser pooling.
2026-08-17 12:39:22 -07:00
can1357 0a912cc467 chore: bump version to 17.3.7 2026-08-17 22:29:25 +03:00
can1357 54e1a8c900 chore: bump version to 17.3.6 2026-08-17 17:16:40 +03:00
roboomp 70af5c300b fix(snapcompact): disambiguate digit zero from letter O in frame fonts
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
2026-08-16 10:34:48 +00:00
can1357 37eee71978 chore: bump version to 17.3.5 2026-08-16 10:21:05 +03:00
can1357 02cd22dc9b feat: added live tracking and stale status warnings for agent activity snapshots
- 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.
2026-08-16 10:18:56 +03:00
can1357 4f23c19928 Merge PR #8586: fix(tui): stop inline code color bleed at soft wraps (@roboomp) 2026-08-16 02:43:32 +02:00
roboomp 7f5590258e fix(builtins): handled empty xargs replace input
- Prevented replace mode from executing without a stdin argument.

- Covered the GNU-compatible empty-input no-op contract.

Fixes #8595
2026-08-15 00:24:29 +00:00
roboomp e4b5b3f795 fix(tui): stopped inline code color bleed at soft wraps
- 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
2026-08-14 21:18:40 +00:00
can1357 ffd53ff92a chore: bump version to 17.3.4 2026-08-14 14:38:16 +02:00
can1357 42d5ca5128 fix(pi-natives): backticked DeviceCheck in doc comment for clippy doc-markdown 2026-08-14 14:13:54 +02:00
can1357 c0ad44b6fc Merge PR #8533: fix(pi-natives): guard DeviceCheck token generation on GUI session (@roboomp) 2026-08-14 14:11:51 +02:00
can1357 04fab5ecb4 feat: replaced custom mupdf wasm pipeline with native function
- 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.
2026-08-14 14:08:28 +02:00
roboomp 988ccc8268 fix(pi-natives): guard DeviceCheck token generation on GUI session
-[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
2026-08-14 08:49:26 +00:00
can1357 039728ad80 chore: bump version to 17.3.3 2026-08-14 05:44:05 +02:00
can1357 ae2d3d6ea1 chore: bump version to 17.3.2 2026-08-14 00:28:43 +02:00
can1357 0bc2c342f4 chore: bump version to 17.3.1 2026-08-13 19:39:21 +02:00
roboomp 246dda7f1c fix(natives): static-link win32 MSVC CRT so addon needs no VC++ redist
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
2026-08-13 16:00:33 +00:00
can1357 8b0f400d3c chore: bump version to 17.3.0 2026-08-13 08:28:43 +02:00
can1357 b60bef961c feat: introduced nix packaging and path-based binary resolution
- 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.
2026-08-13 03:52:47 +02:00
can1357 d97e53cd51 fix(bash): normalize msys pidfile paths 2026-08-13 01:14:55 +02:00
can1357 f1057bf96f Merge PR #8356: fix(bash): resolve msys drive paths in utility builtins (@roboomp) 2026-08-13 01:14:54 +02:00
roboomp 41684f1785 fix(bash): normalized msys paths in sed file operands
Routed sed -f script files and the in-script r/w/s///w file paths through brush-core's shell path normalizer, so /c and /mnt/c aliases open the live Windows drive instead of a phantom current-drive path. Added a Windows -f regression.

Fixes #8355
2026-08-12 19:34:09 +00:00
roboomp a90dfe0dca fix(bash): preserved unicode in drive-alias translation
Translated the /c and /mnt/c tail per char over the valid UTF-8 suffix instead of copying raw bytes as chars, so non-ASCII path components no longer mojibake. Removed the now-unused byte separator helper and added a non-ASCII regression.

Fixes #8355
2026-08-12 19:26:59 +00:00
roboomp 87a4cd739c fix(bash): normalized msys paths in ls runtime
Applied brush-core's shell path normalizer in LsRuntime and added an end-to-end Windows regression for listing an MSYS drive alias.

Fixes #8355
2026-08-12 19:20:55 +00:00
roboomp d1b9c55495 fix(bash): resolved msys drive paths in utility builtins
Normalized utility operands through brush-core's shared shell path resolver so /c and /mnt/c aliases address the live Windows drive. Added Windows-only regression coverage at the Host boundary.

Fixes #8355
2026-08-12 19:15:20 +00:00
roboomp 67f9d510e4 test(natives): waited past background delay in leak check
The leak regression waited only 100ms while the leaked job could not write its marker until a 1s sleep elapsed, so the pre-fix path passed vacuously. Wait past the delay; verified the test fails when the drop-time abort is neutralized.

Fixes #8341
2026-08-12 15:21:56 +00:00
roboomp 110f3aac9d fix(natives): stopped detached internal shell jobs
Abort shell-internal background tasks when their owning session is dropped, and propagate task abortion into blocking utility cancellation so infinite writers stop.

Fixes #8341
2026-08-12 15:13:28 +00:00
can1357 5481d8b9b0 chore: bump version to 17.2.15 2026-08-12 03:26:12 +02:00
can1357 e5ebb2aee0 chore: bump version to 17.2.14 2026-08-11 20:43:02 +02:00
can1357 2157becbe9 chore: bump version to 17.2.13 2026-08-11 16:03:05 +02:00
can1357 311c32eaf5 fix(natives): repaired win32 build and bazel feature drift
- Synced pi-builtins bazel crate_features with cargo's resolved default
  set: bazel features are literal, so the meta-features never expanded
  and the procs/rg cluster (nohup, pgrep, pidwait, pkill, proc-match,
  ps, rg, sleep, timeout, top) was silently compiled out, leaving the
  process builtins unregistered under bazel and failing pi-shell tests.
- Repaired windows compilation of pi-builtins: cfg-gated the
  uucore::mode import in mkdir, imported std::env in sort's non-unix
  locale probe, mapped ProcInfo::pid through a closure in kill, brought
  MetadataExt into scope in wc, and replaced stat's unstable
  windows_by_handle metadata with a stable GetFileInformationByHandle
  query (volume serial, link count, file index, no-dereference aware).
- Imported HashSet for pi-shell's windows-only PATH merge.
- Added a clippy-ported bazel config + CI bucket so pi-builtins keeps
  its manifest-declared clippy allows under the bazel aspect while rustc
  warnings stay denied, and zeroed the remaining windows-target rustc
  warnings (unused params/imports in find, mv, rm, proc_match, ps).
2026-08-09 03:17:34 +02:00
can1357 896bf5f33e fix(natives): repaired linux pi-builtins release build
- Added util.procs to the bazel crate_features: cargo resolves the
  builtin.kill -> util.procs implication automatically, but bazel
  crate_features are literal, so kill.rs failed with E0432 on
  proc_snapshot once HostProcesses became unconditional.
- Imported std::os::fd::AsFd in the linux/android splice path of the wc
  builtin (E0405); the import is target-gated like its callers.
- Verified with cargo check -p pi-builtins --no-default-features using
  the exact bazel feature list on both the host and (via zig cc)
  x86_64-unknown-linux-gnu targets.
2026-08-08 21:06:10 +02:00
can1357 6fb07028fd chore: bump version to 17.2.12 2026-08-08 20:57:55 +02:00
can1357 731c051733 feat(pi-shell/minimizer): implemented length threshold and empty preservation
- Add minimum character threshold to bypass minimization for short outputs.
- Add preserve-if-empty configuration and pipeline support for filters.
- Update test fixtures and integration tests to meet length thresholds.
2026-08-08 16:27:03 +02:00
can1357 d1eafe7a62 feat(pi-builtins): prevented kill builtin from targeting ancestor processes
- Added `HostProcesses` snapshot and `ChainNode` validation to track ancestry and prevent pid recycling.
- Updated process matching and signal handling to refuse signalling the shell or its ancestor processes.
- Added regression tests verifying that kill builtins safely block ancestor targeting while permitting unrelated processes.
- Added the `smallvec` dependency to support efficient process snapshot tracking.
2026-08-08 10:42:55 +02:00
can1357 2ee9943563 refactor: unify builtins in one place 2026-08-08 10:19:25 +02:00
can1357 4dc97f89ab fix(natives): backticked RemoteDesktop in portal doc comments
clippy-strict doc_markdown (-D warnings) rejects the bare identifier;
these two docs were the remaining rust_validate errors on main.
2026-08-07 23:51:43 +02:00
can1357 81e0c3f6bf fix(voice): dropped redundant pub(crate) in private device module
clippy-strict (nursery redundant_pub_crate, -D warnings) rejects pub(crate)
items inside the crate-private device module; plain pub is equivalent there.
Applied across all platform backends since CI only lints the linux cfg.
2026-08-07 23:46:48 +02:00
can1357 055a5d4f26 chore: bump version to 17.2.11 2026-08-07 23:38:40 +02:00
can1357 7cae7ef3f5 feat(voice): replaced miniaudio with native platform audio backends
- Replaced the miniaudio dependency with custom OS audio device abstractions and backends.
- Implemented platform-specific audio playback and capture for macOS (Audio Queue), Windows (WASAPI), and Linux (PulseAudio/ALSA).
- Added a fallback stub backend returning errors for unsupported platforms.
- Updated audio stream handling with reliable fill guard wakeups and streamlined rate validation.
2026-08-07 23:38:27 +02:00
can1357 bc5eee4e24 fix(build): activated zune-jpeg log feature and widened test compat type
- 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.
2026-08-07 23:38:27 +02:00
roboomp 216fc3ca2d fix(computer): waited for all granted libei devices
- 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
2026-08-07 23:38:25 +02:00
can1357 084fbb683f Merge PR #7890: fix(computer): lazily request wayland input permission (@roboomp)
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.
2026-08-07 14:52:56 +02:00