Merge PR #7469: fix(grep): disable pcre2 jit on macos (@roboomp)

This commit is contained in:
can1357
2026-08-03 15:12:03 +02:00
4 changed files with 78 additions and 3 deletions
+27 -1
View File
@@ -35,6 +35,7 @@ use smallvec::SmallVec;
use crate::{glob_util, iofs, task};
const MAX_FILE_BYTES: u64 = 4 * 1024 * 1024;
const PCRE2_JIT_ENABLED: bool = !cfg!(target_os = "macos");
/// Output mode for [`search`] and [`grep`] (string values match JS callers).
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -1015,7 +1016,7 @@ fn build_pcre_matcher(
.multi_line(multiline)
.utf(true)
.ucp(true)
.jit_if_available(true);
.jit_if_available(PCRE2_JIT_ENABLED);
builder.build(pattern)
}
@@ -2411,10 +2412,16 @@ mod tests {
let root = TempDirGuard::new();
write_file(&root.path().join("lookahead.txt"), "foobar\nfoobaz\n");
write_file(&root.path().join("backreference.txt"), "same same\nsame other\n");
write_file(&root.path().join("models.txt"), "dim_customers_status_accepted_values\n");
for (pattern, path, line) in [
(r"foo(?=bar)", "lookahead.txt", "foobar"),
(r"\b(\w+)\s+\1\b", "backreference.txt", "same same"),
(
r"(final_incremental_account_id_relationships|dim_customers_status_accepted_values|stg_orders_customer_id_relationships)(?!_[0-9a-f]{32})",
"models.txt",
"dim_customers_status_accepted_values",
),
] {
let mut config = base_grep_config(root.path());
config.pattern = pattern.to_string();
@@ -2428,6 +2435,25 @@ mod tests {
assert_eq!(result.matches[0].line, line);
}
}
#[cfg(unix)]
#[test]
fn grep_supports_multiline_pcre2_backreferences_and_lookahead() {
let root = TempDirGuard::new();
write_file(&root.path().join("schema.yml"), " - not_null:\n severity: warn\n");
let mut config = base_grep_config(root.path());
config.pattern = r"^(\s+)- (not_null|unique|accepted_values|relationships|expression_is_true|[a-z_]+):\s*$\n(?!\1 (arguments|config|description|name):)".to_string();
config.multiline = Some(true);
let result = grep_sync(config, None, task::CancelToken::default())
.expect("multiline PCRE2 pattern should search without terminating the process");
assert_eq!(result.total_matches, 1);
assert_eq!(result.matches.len(), 1);
assert_eq!(result.matches[0].path, "schema.yml");
assert_eq!(result.matches[0].line_number, 1);
}
#[cfg(unix)]
#[test]
fn grep_directory_skips_fifo_entries() {
+11 -1
View File
@@ -29,6 +29,7 @@ use grep_searcher::{
BinaryDetection, Searcher, SearcherBuilder, Sink, SinkContext, SinkFinish, SinkMatch,
};
pub use rg::run as run_rg;
const PCRE2_JIT_ENABLED: bool = !cfg!(target_os = "macos");
#[derive(Parser, Debug)]
#[command(
@@ -689,7 +690,7 @@ fn build_matcher(
.whole_line(cli.line_regexp)
.utf(true)
.ucp(true)
.jit_if_available(true);
.jit_if_available(PCRE2_JIT_ENABLED);
return builder
.build_many(patterns)
.map(CompiledMatcher::Pcre)
@@ -1615,6 +1616,15 @@ mod tests {
assert_eq!(stdout, "foobar\n");
}
#[test]
fn perl_mode_compiles_the_native_grep_crash_pattern() {
let pattern = r"(final_incremental_account_id_relationships|dim_customers_status_accepted_values|stg_orders_customer_id_relationships)(?!_[0-9a-f]{32})";
let (code, stdout, stderr) =
run_grep(&["-P", pattern], "dim_customers_status_accepted_values\n");
assert_eq!(code, 0, "{stderr}");
assert_eq!(stdout, "dim_customers_status_accepted_values\n");
}
#[test]
fn byte_offsets_labels_and_nul_filename_separators_are_rendered() {
let (code, stdout, stderr) = run_grep(&["-bn", "hit"], "no\nhit\n");
+10 -1
View File
@@ -864,7 +864,7 @@ fn build_pcre_matcher(patterns: &[String], cli: &RgCli) -> Result<PcreMatcher, S
.crlf(cli.crlf && !cli.no_crlf && !cli.null_data)
.utf(unicode)
.ucp(unicode)
.jit_if_available(true);
.jit_if_available(crate::PCRE2_JIT_ENABLED);
builder
.build_many(patterns)
.map_err(|error| error.to_string())
@@ -1869,6 +1869,15 @@ mod tests {
assert_eq!(stdout, "foobar\n");
}
#[test]
fn pcre2_compiles_the_multiline_native_grep_crash_pattern() {
let pattern = r"^(\s+)- (not_null|unique|accepted_values|relationships|expression_is_true|[a-z_]+):\s*$\n(?!\1 (arguments|config|description|name):)";
let (code, stdout, stderr) =
run_rg(&["--pcre2", "--multiline", pattern], " - not_null:\n severity: warn\n");
assert_eq!(code, 0, "{stderr}");
assert_eq!(stdout, " - not_null:\n");
}
#[test]
fn auto_engine_promotes_patterns_that_need_pcre2() {
let (code, stdout, stderr) = run_rg(&["--engine=auto", "(?<=foo)bar"], "foobar\nbar\n");
+30
View File
@@ -9,6 +9,7 @@
- Fixed floating rejections from cmux browser guest JavaScript terminating the main process and every active session; attributable rejections now fail the browser run as tool errors while unrelated process rejections retain the fatal path ([#7365](https://github.com/can1357/oh-my-pi/issues/7365)).
- Fixed the Windows bash tool silently taking down the whole omp process when a command blocked until its timeout: cancelling a timed-out run walked the spawned child's descendant tree from raw `th32ParentProcessID` links, and a recycled pid matching the harness's stale recorded parent pid could enumerate omp as a false descendant and `TerminateProcess` it, killing the session with no `session_exit` record. Run-cancellation sweeps now refuse to signal the harness or any process collected beneath it, while still reaping the timed-out target when it owns a recycled ancestor pid ([#7452](https://github.com/can1357/oh-my-pi/issues/7452)).
- Fixed a supervised process reaching a terminal state without telling the session that launched it. The broker recorded the final snapshot for `hub ps` to read but emitted no event, so an idle owner only learned that a process had exited by polling. The broker now sends one `daemon-completed` notification per terminal exit to the owner socket recorded at launch, and the session turns it into a model-visible message. Restart transitions stay live, and a stale or disposed session drops the notification without changing explicit `hub wait` or persistence behavior.
- Fixed PCRE2-only grep patterns terminating Bun on macOS by using the interpreted PCRE2 engine instead of its unsafe same-process JIT in native grep, embedded `grep -P`, and embedded `rg --pcre2`/`--engine=auto` ([#7399](https://github.com/can1357/oh-my-pi/issues/7399)).
## [17.2.5] - 2026-08-03
@@ -60,6 +61,35 @@
- Fixed heavily branched conversation trees shifting linear continuations into disconnected columns.
- Fixed plugin installation validation failures for legacy compatibility shims.
- Removed hard-coded references to disabled or absent agents in system and tool prompts.
- Fixed template argument substitution (`substituteArgs`) executing recursive placeholder expansion when positional argument values contain literal `$@` or `$ARGUMENTS` tokens.
- Fixed focused-agent status bar dimming darkening Powerline end caps.
- Fixed the browser relay creating duplicate "omp" tab groups: the bridge now keeps at most one group RPC in flight (a queued drain replaces fire-and-forget per-tab requests), so concurrent requests can no longer race the extension's non-atomic query→create→set-title sequence in the same window. Also fixed an extension reconnect (relay daemon restart, service-worker recycle) being misread as the user dragging every tab out of the omp group — grouping state is reset when the extension socket closes, so tabs regroup on the next hello instead of being permanently opted out.
- Fixed retained computer `Win` and `El` handles carrying a completed run's abort signal and permissions into later runs; handles now obey the current run while leaked async continuations remain denied.
- Fixed computer-tool `win.ref("eN")` fabricating an element with empty role/title metadata; it now resolves the ref through the accessibility registry, returning a populated element and throwing `StaleRef` for expired refs.
- Fixed macOS background keyboard input silently reaching a different window in the same application; ambiguous multi-window delivery now fails with `BackgroundUnavailable`, and foreground retries establish the addressed window as the app's main/focused window before typing.
- Fixed macOS Chrome accessibility snapshots exposing only browser chrome by activating Chromium's renderer accessibility tree before resolving a window.
- Fixed unnamed macOS accessibility controls such as Chrome's Back, Forward, and Reload buttons by using `AXDescription` when `AXTitle` is empty in snapshots and title queries.
- Fixed shake re-eliding artifact recovery reads into a new artifact indefinitely.
- Fixed Esc during a streaming `/loop` iteration pausing the loop instead of only aborting the current turn ([#7329](https://github.com/can1357/oh-my-pi/issues/7329)).
- Fixed heavily branched conversation trees shifting linear continuations into disconnected gutter columns and accumulating unnecessary indentation ([#7332](https://github.com/can1357/oh-my-pi/issues/7332)).
- Fixed the vibe pre-init-kill test racing `registry.kill()` against the worker's job-body dispatch (the mock only registered its AgentRef after the abort signal landed, so a loaded runner could observe no registration); the test now waits for the worker to be mid-initialization before killing.
- Removed hard-coded `scout` references from agent, system, and tool prompts that leaked into the model even when the scout agent was disabled (`task.disabledAgents`) or absent from the spawn list: the init agent prompt, task tool description, delegation gates, plan-mode and workflowz notices, and glob/grep/ast-grep guidance no longer recommend an unavailable agent, including after live settings changes ([#7313](https://github.com/can1357/oh-my-pi/issues/7313)).
- Fixed compiled Windows launches misclassifying ConPTY-backed terminals as console-less when `GetConsoleWindow()` returned no HWND, which spawned Python eval kernels with `CREATE_NO_WINDOW` and could deadlock imports of NumPy-backed packages such as Matplotlib ([#7343](https://github.com/can1357/oh-my-pi/issues/7343)).
- Fixed headless print-mode teardown exceeding its Mnemopi consolidation budget when final retention blocks on a locked SQLite writer, leaving the parent process, embed worker, and MCP children alive after the turn completed ([#7351](https://github.com/can1357/oh-my-pi/issues/7351)).
- Fixed headless `-p` / `--mode json` runs with `memory.backend: mnemopi` hanging after a completed turn and leaving `__omp_worker_mnemopi_embed` unreaped when the embed worker's fastembed/onnxruntime runtime wedged. Steady-state embed requests were unbounded, so a stuck native runtime blocked the turn's memory recall or shutdown consolidation forever; embeds are now bounded and the wedged worker is reaped on timeout so the next call respawns a fresh child, while initialization remains unbounded so first-time runtime installation and model bootstrap are not killed mid-install (regression of [#5753](https://github.com/can1357/oh-my-pi/issues/5753); [#7352](https://github.com/can1357/oh-my-pi/issues/7352)).
- Fixed a literal API key configured via `/login` (e.g. OpenCode Zen's free `public` key) being hijacked on Windows by a case-differing system environment variable, causing 401s. `process.env`/`Bun.env` reads are case-insensitive on Windows, so the config-value resolvers' "env var name, else literal" fallback resolved `public` to the built-in `PUBLIC=C:\Users\Public`. Resolution now requires an exact-case env entry (via the new `$envExact` helper) before treating a value as an env-var reference ([#7361](https://github.com/can1357/oh-my-pi/issues/7361)).
- Fixed redirected stdin being ignored when Bun reports a pipe with an undefined `isTTY`, so JSON/print sessions now process piped prompts and persist them under `--session-dir` or `PI_CODING_AGENT_SESSION_DIR` as requested ([#7378](https://github.com/can1357/oh-my-pi/issues/7378)).
- Fixed Chromium-backed tests failing during suite registration when the shared availability probe was still initializing ([#7384](https://github.com/can1357/oh-my-pi/pull/7384) by [@paralin](https://github.com/paralin)).
- Fixed the terminal-tab title dropping to idle (`>`) while an unsuppressed async job was still running — a `/vibe` worker turn or a bash `async` job that re-wakes the director after it settles. `EventController.#handleAgentEnd` now skips the idle/loader teardown on a non-terminal `agent_end` (`isTerminal: false`) and only tears down at the true terminal settle ([#7386](https://github.com/can1357/oh-my-pi/issues/7386)).
- Fixed `omp setup python` to validate the same configured or discovered interpreter used by the Python eval runtime.
- Fixed self-update misclassifying glibc Linux hosts with an installed musl loader as musl hosts, which could download an unusable musl binary instead of the glibc release.
- Fixed a crash where opening the Agent Hub after a resume and moving the selection triggered an unbounded `ExtensionExitError` unhandled-rejection storm and exit 129. The postmortem module bound the native hard-exit at first evaluation; when the bundler deferred that evaluation into a `withHostGuard` window it froze the guard's throwing replacement, poisoning every later signal/fatal exit. The native exit is now resolved per call, and the guard stamps its replacement with the native primitive it shadows so mid-guard signals still exit ([#7393](https://github.com/can1357/oh-my-pi/issues/7393)).
- Fixed project-scoped session directories using leading-hyphen names and collapsing distinct paths such as `~/project/hail-mary` and `~/project-hail-mary` into one bucket; directory names now use a portable readable prefix plus the canonical cwd hash, and colliding legacy buckets are split by their recorded session cwd during migration ([#7396](https://github.com/can1357/oh-my-pi/issues/7396)).
- Fixed manual `/shake` leaving the context budget and next pre-turn compaction decision anchored to the stale pre-shake provider token count until another model response arrived.
- Fixed Mnemopi scoped recall reporting "No relevant memories found" when every scoped target failed internally; target failures now warn, and total recall failure preserves the underlying engine error while healthy targets remain available ([#7364](https://github.com/can1357/oh-my-pi/issues/7364)).
- Fixed `skill://` resolution ignoring explicitly configured `skills.customDirectories` entries when a same-named skill existed in a default discovery path: the custom-directory skill now wins as the higher-priority source ([#7190](https://github.com/can1357/oh-my-pi/issues/7190)).
- Fixed image paste failing on Wayland-only Linux sessions by reading PNG clipboard payloads through `wl-paste` before falling back to the native bridge ([#7316](https://github.com/can1357/oh-my-pi/issues/7316)).
- Fixed prewalk switching to the fast model during read-only investigation: `xd://` devices are dispatched through the `write` tool, so a read-only call such as an `lsp` navigation counted as the first edit/write and armed the one-way hand-off mid-planning. Device dispatches now carry the wrapped tool's approval tier and only trigger the switch at a `write`/`exec` tier — read-only `lsp`, `debug` inspection, and internal-URL `ast_edit` calls no longer downgrade the model ([#7312](https://github.com/can1357/oh-my-pi/issues/7312)).
## [17.2.4] - 2026-08-01