From d49b0c6c078e06520ef506a559281f816a6bc2d6 Mon Sep 17 00:00:00 2001 From: "factory-droid[bot]" <138933559+factory-droid[bot]@users.noreply.github.com> Date: Sat, 17 Oct 2026 16:45:41 +0000 Subject: [PATCH] Fix Linux build of the codexbar crate --- rust/src/agent_sessions/claude_desktop.rs | 7 +++++++ rust/src/agent_sessions/pi_family/roots.rs | 4 ++++ rust/src/agent_sessions/pi_family_tests.rs | 7 ++++++- rust/src/codex_cli.rs | 2 +- rust/src/codex_sessions.rs | 1 + rust/src/core/hooks/tests.rs | 12 ++++++++++-- rust/src/core/timezone.rs | 1 + rust/src/providers/codex/reset_observations.rs | 1 + rust/src/providers/jetbrains/ide.rs | 1 + rust/src/providers/muse/local_usage/cache.rs | 15 +++++++++++++++ rust/src/providers/muse/local_usage/mod.rs | 17 ----------------- 11 files changed, 47 insertions(+), 21 deletions(-) diff --git a/rust/src/agent_sessions/claude_desktop.rs b/rust/src/agent_sessions/claude_desktop.rs index 807b21880ea..c80eb6ac68c 100644 --- a/rust/src/agent_sessions/claude_desktop.rs +++ b/rust/src/agent_sessions/claude_desktop.rs @@ -5,6 +5,13 @@ //! walks only the two known session roots to a shallow fixed depth and returns //! nested `.claude/projects` directories. Every directory/type/path operation //! shares the caller's metadata scan budget. +#![cfg_attr( + not(windows), + allow( + dead_code, + reason = "the traversal stays platform-neutral so tests cover it, but only Windows calls it" + ) +)] use super::pi_family::DirectoryScanBudget; use std::collections::HashSet; diff --git a/rust/src/agent_sessions/pi_family/roots.rs b/rust/src/agent_sessions/pi_family/roots.rs index 017ba8047a3..0e4db35135a 100644 --- a/rust/src/agent_sessions/pi_family/roots.rs +++ b/rust/src/agent_sessions/pi_family/roots.rs @@ -180,6 +180,10 @@ impl DirectoryScanBudget { Some(canonicalize_for_scan(path)) } + #[cfg_attr( + not(windows), + allow(dead_code, reason = "only Windows Claude Desktop discovery reads it") + )] pub(crate) fn max_depth(&self) -> usize { self.max_depth } diff --git a/rust/src/agent_sessions/pi_family_tests.rs b/rust/src/agent_sessions/pi_family_tests.rs index 513a10926e8..c190ec0c941 100644 --- a/rust/src/agent_sessions/pi_family_tests.rs +++ b/rust/src/agent_sessions/pi_family_tests.rs @@ -334,6 +334,7 @@ mod pi_family_tests { assert_eq!(pi_family_dialect(records[6].command.as_deref().unwrap()), None); } + #[cfg(windows)] #[test] fn windows_shims_and_paths_are_normalized_for_dialect() { assert_eq!( @@ -682,7 +683,11 @@ mod pi_family_tests { fn config_dir_must_stay_within_home() { let home = tempfile::tempdir().expect("tempdir"); let cwd = home.path().to_path_buf(); - for bad in ["/abs/path", "..", "../escape", "~/x", "C:\\escape"] { + let mut bad_dirs = vec!["/abs/path", "..", "../escape", "~/x"]; + if cfg!(windows) { + bad_dirs.push("C:\\escape"); + } + for bad in bad_dirs { let env = env_map(&[("PI_CONFIG_DIR", bad)]); assert!( omp_default_profile_root(&env, &cwd, home.path()).is_none(), diff --git a/rust/src/codex_cli.rs b/rust/src/codex_cli.rs index a8a61cc8b31..f9e72a92e6b 100644 --- a/rust/src/codex_cli.rs +++ b/rust/src/codex_cli.rs @@ -4,7 +4,6 @@ //! TTY launching do not drift into separate path lists. use std::path::{Path, PathBuf}; -use std::process::Command; /// Locate the Codex CLI for shell integrations that need to reopen a session. pub fn locate_codex_binary() -> Option { @@ -81,6 +80,7 @@ fn versioned_binaries(root: &Path) -> Vec { #[cfg(windows)] fn desktop_package_binary() -> Option { use std::os::windows::process::CommandExt; + use std::process::Command; let powershell = PathBuf::from(std::env::var_os("WINDIR")?) .join("System32/WindowsPowerShell/v1.0/powershell.exe"); diff --git a/rust/src/codex_sessions.rs b/rust/src/codex_sessions.rs index 7f5b3f61ca5..d1bf0550f6a 100644 --- a/rust/src/codex_sessions.rs +++ b/rust/src/codex_sessions.rs @@ -109,6 +109,7 @@ fn push_unique_path(dirs: &mut Vec, seen: &mut HashSet, path: P mod tests { use super::*; + #[cfg(windows)] #[test] fn normalizes_codex_root_to_sessions_dir() { assert_eq!( diff --git a/rust/src/core/hooks/tests.rs b/rust/src/core/hooks/tests.rs index 3167c791ff8..6daab4e316d 100644 --- a/rust/src/core/hooks/tests.rs +++ b/rust/src/core/hooks/tests.rs @@ -159,7 +159,7 @@ fn config_matching_respects_enabled_flag() { events: vec![], provider: None, threshold: None, - executable: PathBuf::from("C:\\Windows\\System32\\cmd.exe"), + executable: absolute_executable("cmd.exe"), arguments: vec![], timeout_secs: 5, }; @@ -204,6 +204,14 @@ fn rate_limiter_key_is_stable() { let _ = Arc::new(a); } +fn absolute_executable(name: &str) -> PathBuf { + if cfg!(windows) { + PathBuf::from(r"C:\Tools").join(name) + } else { + PathBuf::from("/usr/local/bin").join(name) + } +} + fn rule_with(arguments: usize) -> HookRule { HookRule { enabled: true, @@ -211,7 +219,7 @@ fn rule_with(arguments: usize) -> HookRule { events: Vec::new(), provider: None, threshold: None, - executable: PathBuf::from(r"C:\Tools\notify.exe"), + executable: absolute_executable("notify.exe"), arguments: (0..arguments).map(|i| format!("--arg{i}")).collect(), timeout_secs: 10, } diff --git a/rust/src/core/timezone.rs b/rust/src/core/timezone.rs index 9af80f9df85..fbf5ec294c3 100644 --- a/rust/src/core/timezone.rs +++ b/rust/src/core/timezone.rs @@ -18,6 +18,7 @@ //! proceed, so no thread can reach `iana_time_zone` while pinning is still //! in progress. +#[cfg(windows)] use std::sync::LazyLock; /// Zone used when the OS timezone cannot be read safely. diff --git a/rust/src/providers/codex/reset_observations.rs b/rust/src/providers/codex/reset_observations.rs index 0902e25f1a5..bf4255212e1 100644 --- a/rust/src/providers/codex/reset_observations.rs +++ b/rust/src/providers/codex/reset_observations.rs @@ -312,6 +312,7 @@ mod tests { )); } + #[cfg(windows)] #[test] fn persisted_file_is_secure_wrapped() { let root = temp_root("secure"); diff --git a/rust/src/providers/jetbrains/ide.rs b/rust/src/providers/jetbrains/ide.rs index 7544d70592f..60b38cf17df 100644 --- a/rust/src/providers/jetbrains/ide.rs +++ b/rust/src/providers/jetbrains/ide.rs @@ -319,6 +319,7 @@ mod tests { assert!(log_path_for(&traversal, &roots).is_none()); } + #[cfg(windows)] #[test] fn log_path_match_ignores_trailing_separator_and_case() { let dir = tempfile::tempdir().expect("tempdir"); diff --git a/rust/src/providers/muse/local_usage/cache.rs b/rust/src/providers/muse/local_usage/cache.rs index 2b89dc6ea45..31e502786fa 100644 --- a/rust/src/providers/muse/local_usage/cache.rs +++ b/rust/src/providers/muse/local_usage/cache.rs @@ -37,6 +37,7 @@ pub(crate) fn file_stamp(path: &Path) -> Option { .as_millis(), }) } +#[cfg(windows)] pub(crate) fn platform_file_identity(path: &Path, _metadata: &fs::Metadata) -> Option { use std::os::windows::io::AsRawHandle; @@ -56,6 +57,20 @@ pub(crate) fn platform_file_identity(path: &Path, _metadata: &fs::Metadata) -> O let file_index = ((info.nFileIndexHigh as u64) << 32) | info.nFileIndexLow as u64; Some(format!("{}:{file_index}", info.dwVolumeSerialNumber)) } +#[cfg(unix)] +pub(crate) fn platform_file_identity(_path: &Path, metadata: &fs::Metadata) -> Option { + use std::os::unix::fs::MetadataExt; + + Some(format!("{}:{}", metadata.dev(), metadata.ino())) +} +#[cfg(not(any(unix, windows)))] +pub(crate) fn platform_file_identity(_path: &Path, metadata: &fs::Metadata) -> Option { + metadata + .created() + .ok() + .and_then(|value| value.duration_since(UNIX_EPOCH).ok()) + .map(|value| value.as_nanos().to_string()) +} pub(crate) fn digest_bytes( path: &Path, stamp: &FileStamp, diff --git a/rust/src/providers/muse/local_usage/mod.rs b/rust/src/providers/muse/local_usage/mod.rs index 3fff4d5290a..06b392eae31 100644 --- a/rust/src/providers/muse/local_usage/mod.rs +++ b/rust/src/providers/muse/local_usage/mod.rs @@ -165,23 +165,6 @@ fn day_window(days: u32) -> (String, String) { ) } -#[cfg(windows)] -#[cfg(unix)] -fn platform_file_identity(_path: &Path, metadata: &fs::Metadata) -> Option { - use std::os::unix::fs::MetadataExt; - - Some(format!("{}:{}", metadata.dev(), metadata.ino())) -} - -#[cfg(not(any(unix, windows)))] -fn platform_file_identity(_path: &Path, metadata: &fs::Metadata) -> Option { - metadata - .created() - .ok() - .and_then(|value| value.duration_since(UNIX_EPOCH).ok()) - .map(|value| value.as_nanos().to_string()) -} - fn discover(root: &Path, state: &mut ScanState) -> (Vec, bool) { let mut files = Vec::new(); let mut complete = true;