chore: Bump alacritty_terminal to 0.25.1-rc1 (#38505)

Jakub Konka and Dave Waggoner created

Release Notes:

- N/A

---------

Co-authored-by: Dave Waggoner <waggoner.dave@gmail.com>

Change summary

Cargo.lock                                 |  41 +-
Cargo.toml                                 |   2 
crates/terminal/src/terminal.rs            |   2 
crates/terminal/src/terminal_hyperlinks.rs | 294 ++++++-----------------
tooling/workspace-hack/Cargo.toml          |  40 +-
5 files changed, 123 insertions(+), 256 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -498,8 +498,9 @@ dependencies = [
 
 [[package]]
 name = "alacritty_terminal"
-version = "0.25.1-dev"
-source = "git+https://github.com/zed-industries/alacritty.git?branch=add-hush-login-flag#828457c9ff1f7ea0a0469337cc8a37ee3a1b0590"
+version = "0.25.1-rc1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cb5f4f1ef69bdb8b2095ddd14b09dd74ee0303aae8bd5372667a54cff689a1b"
 dependencies = [
  "base64 0.22.1",
  "bitflags 2.9.0",
@@ -511,10 +512,11 @@ dependencies = [
  "piper",
  "polling",
  "regex-automata",
+ "rustix 1.0.7",
  "rustix-openpty",
  "serde",
  "signal-hook",
- "unicode-width 0.1.14",
+ "unicode-width 0.2.0",
  "vte",
  "windows-sys 0.59.0",
 ]
@@ -8221,12 +8223,6 @@ version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
 
-[[package]]
-name = "hermit-abi"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
-
 [[package]]
 name = "hermit-abi"
 version = "0.5.0"
@@ -12822,17 +12818,16 @@ dependencies = [
 
 [[package]]
 name = "polling"
-version = "3.7.4"
+version = "3.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
 dependencies = [
  "cfg-if",
  "concurrent-queue",
- "hermit-abi 0.4.0",
+ "hermit-abi 0.5.0",
  "pin-project-lite",
- "rustix 0.38.44",
- "tracing",
- "windows-sys 0.59.0",
+ "rustix 1.0.7",
+ "windows-sys 0.61.0",
 ]
 
 [[package]]
@@ -14679,7 +14674,6 @@ checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
 dependencies = [
  "bitflags 2.9.0",
  "errno 0.3.11",
- "itoa",
  "libc",
  "linux-raw-sys 0.4.15",
  "windows-sys 0.59.0",
@@ -14710,13 +14704,13 @@ dependencies = [
 
 [[package]]
 name = "rustix-openpty"
-version = "0.1.1"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a25c3aad9fc1424eb82c88087789a7d938e1829724f3e4043163baf0d13cfc12"
+checksum = "1de16c7c59892b870a6336f185dc10943517f1327447096bbb7bb32cd85e2393"
 dependencies = [
  "errno 0.3.11",
  "libc",
- "rustix 0.38.44",
+ "rustix 1.0.7",
 ]
 
 [[package]]
@@ -20039,6 +20033,15 @@ dependencies = [
  "windows-targets 0.53.2",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.61.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
+dependencies = [
+ "windows-link 0.2.0",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.42.2"

Cargo.toml 🔗

@@ -439,7 +439,7 @@ zlog_settings = { path = "crates/zlog_settings" }
 
 agent-client-protocol = { version = "0.4.0", features = ["unstable"] }
 aho-corasick = "1.1"
-alacritty_terminal = { git = "https://github.com/zed-industries/alacritty.git", branch = "add-hush-login-flag" }
+alacritty_terminal = "0.25.1-rc1"
 any_vec = "0.14"
 anyhow = "1.0.86"
 arrayvec = { version = "0.7.4", features = ["serde"] }

crates/terminal/src/terminal.rs 🔗

@@ -427,6 +427,8 @@ impl TerminalBuilder {
                 working_directory: working_directory.clone(),
                 drain_on_exit: true,
                 env: env.clone().into_iter().collect(),
+                #[cfg(windows)]
+                escape_args: false,
             }
         };
 

crates/terminal/src/terminal_hyperlinks.rs 🔗

@@ -79,8 +79,7 @@ pub(super) fn find_from_grid_point<T: EventListener>(
         Some((url, true, url_match))
     } else if let Some(url_match) = regex_match_at(term, point, &mut regex_searches.url_regex) {
         let url = term.bounds_to_string(*url_match.start(), *url_match.end());
-        let (sanitized_url, sanitized_match) = sanitize_url_punctuation(url, url_match, term);
-        Some((sanitized_url, true, sanitized_match))
+        Some((url, true, url_match))
     } else if let Some(python_match) =
         regex_match_at(term, point, &mut regex_searches.python_file_line_regex)
     {
@@ -165,63 +164,6 @@ pub(super) fn find_from_grid_point<T: EventListener>(
     })
 }
 
-fn sanitize_url_punctuation<T: EventListener>(
-    url: String,
-    url_match: Match,
-    term: &Term<T>,
-) -> (String, Match) {
-    let mut sanitized_url = url;
-    let mut chars_trimmed = 0;
-
-    // First, handle parentheses balancing using single traversal
-    let (open_parens, close_parens) =
-        sanitized_url
-            .chars()
-            .fold((0, 0), |(opens, closes), c| match c {
-                '(' => (opens + 1, closes),
-                ')' => (opens, closes + 1),
-                _ => (opens, closes),
-            });
-
-    // Trim unbalanced closing parentheses
-    if close_parens > open_parens {
-        let mut remaining_close = close_parens;
-        while sanitized_url.ends_with(')') && remaining_close > open_parens {
-            sanitized_url.pop();
-            chars_trimmed += 1;
-            remaining_close -= 1;
-        }
-    }
-
-    // Handle trailing periods
-    if sanitized_url.ends_with('.') {
-        let trailing_periods = sanitized_url
-            .chars()
-            .rev()
-            .take_while(|&c| c == '.')
-            .count();
-
-        if trailing_periods > 1 {
-            sanitized_url.truncate(sanitized_url.len() - trailing_periods);
-            chars_trimmed += trailing_periods;
-        } else if trailing_periods == 1
-            && let Some(second_last_char) = sanitized_url.chars().rev().nth(1)
-            && (second_last_char.is_alphanumeric() || second_last_char == '/')
-        {
-            sanitized_url.pop();
-            chars_trimmed += 1;
-        }
-    }
-
-    if chars_trimmed > 0 {
-        let new_end = url_match.end().sub(term, Boundary::Grid, chars_trimmed);
-        let sanitized_match = Match::new(*url_match.start(), new_end);
-        (sanitized_url, sanitized_match)
-    } else {
-        (sanitized_url, url_match)
-    }
-}
-
 fn is_path_surrounded_by_common_symbols(path: &str) -> bool {
     // Avoid detecting `[]` or `()` strings as paths, surrounded by common symbols
     path.len() > 2
@@ -261,8 +203,8 @@ mod tests {
     use super::*;
     use alacritty_terminal::{
         event::VoidListener,
-        index::{Boundary, Column, Line, Point as AlacPoint},
-        term::{Config, cell::Flags, search::Match, test::TermSize},
+        index::{Boundary, Point as AlacPoint},
+        term::{Config, cell::Flags, test::TermSize},
         vte::ansi::Handler,
     };
     use std::{cell::RefCell, ops::RangeInclusive, path::PathBuf};
@@ -291,91 +233,6 @@ mod tests {
         );
     }
 
-    #[test]
-    fn test_url_parentheses_sanitization() {
-        // Test our sanitize_url_parentheses function directly
-        let test_cases = vec![
-            // Cases that should be sanitized (unbalanced parentheses)
-            ("https://www.google.com/)", "https://www.google.com/"),
-            ("https://example.com/path)", "https://example.com/path"),
-            ("https://test.com/))", "https://test.com/"),
-            // Cases that should NOT be sanitized (balanced parentheses)
-            (
-                "https://en.wikipedia.org/wiki/Example_(disambiguation)",
-                "https://en.wikipedia.org/wiki/Example_(disambiguation)",
-            ),
-            ("https://test.com/(hello)", "https://test.com/(hello)"),
-            (
-                "https://example.com/path(1)(2)",
-                "https://example.com/path(1)(2)",
-            ),
-            // Edge cases
-            ("https://test.com/", "https://test.com/"),
-            ("https://example.com", "https://example.com"),
-        ];
-
-        for (input, expected) in test_cases {
-            // Create a minimal terminal for testing
-            let term = Term::new(Config::default(), &TermSize::new(80, 24), VoidListener);
-
-            // Create a dummy match that spans the entire input
-            let start_point = AlacPoint::new(Line(0), Column(0));
-            let end_point = AlacPoint::new(Line(0), Column(input.len()));
-            let dummy_match = Match::new(start_point, end_point);
-
-            let (result, _) = sanitize_url_punctuation(input.to_string(), dummy_match, &term);
-            assert_eq!(result, expected, "Failed for input: {}", input);
-        }
-    }
-
-    #[test]
-    fn test_url_periods_sanitization() {
-        // Test URLs with trailing periods (sentence punctuation)
-        let test_cases = vec![
-            // Cases that should be sanitized (trailing periods likely punctuation)
-            ("https://example.com.", "https://example.com"),
-            (
-                "https://github.com/zed-industries/zed.",
-                "https://github.com/zed-industries/zed",
-            ),
-            (
-                "https://example.com/path/file.html.",
-                "https://example.com/path/file.html",
-            ),
-            (
-                "https://example.com/file.pdf.",
-                "https://example.com/file.pdf",
-            ),
-            ("https://example.com:8080.", "https://example.com:8080"),
-            ("https://example.com..", "https://example.com"),
-            (
-                "https://en.wikipedia.org/wiki/C.E.O.",
-                "https://en.wikipedia.org/wiki/C.E.O",
-            ),
-            // Cases that should NOT be sanitized (periods are part of URL structure)
-            (
-                "https://example.com/v1.0/api",
-                "https://example.com/v1.0/api",
-            ),
-            ("https://192.168.1.1", "https://192.168.1.1"),
-            ("https://sub.domain.com", "https://sub.domain.com"),
-        ];
-
-        for (input, expected) in test_cases {
-            // Create a minimal terminal for testing
-            let term = Term::new(Config::default(), &TermSize::new(80, 24), VoidListener);
-
-            // Create a dummy match that spans the entire input
-            let start_point = AlacPoint::new(Line(0), Column(0));
-            let end_point = AlacPoint::new(Line(0), Column(input.len()));
-            let dummy_match = Match::new(start_point, end_point);
-
-            // This test should initially fail since we haven't implemented period sanitization yet
-            let (result, _) = sanitize_url_punctuation(input.to_string(), dummy_match, &term);
-            assert_eq!(result, expected, "Failed for input: {}", input);
-        }
-    }
-
     #[test]
     fn test_word_regex() {
         re_test(
@@ -468,17 +325,6 @@ mod tests {
             )
         } };
 
-        ($($columns:literal),+; $($lines:expr),+; $hyperlink_kind:ident) => { {
-            use crate::terminal_hyperlinks::tests::line_cells_count;
-
-            let test_lines = vec![$($lines),+];
-            let total_cells = test_lines.iter().copied().map(line_cells_count).sum();
-
-            test_hyperlink!(
-                [ $($columns),+ ]; total_cells; test_lines.iter().copied(); $hyperlink_kind
-            )
-        } };
-
         ([ $($columns:expr),+ ]; $total_cells:expr; $lines:expr; $hyperlink_kind:ident) => { {
             use crate::terminal_hyperlinks::tests::{ test_hyperlink, HyperlinkKind };
 
@@ -504,9 +350,6 @@ mod tests {
         ///
         macro_rules! test_path {
             ($($lines:literal),+) => { test_hyperlink!($($lines),+; Path) };
-            ($($columns:literal),+; $($lines:literal),+) => {
-                test_hyperlink!($($columns),+; $($lines),+; Path)
-            };
         }
 
         #[test]
@@ -572,39 +415,52 @@ mod tests {
             test_path!("‹«/test/co👉ol.rs»(«1»,«618»)›::");
         }
 
+        #[test]
+        fn quotes_and_brackets() {
+            test_path!("\"‹«/test/co👉ol.rs»:«4»›\"");
+            test_path!("'‹«/test/co👉ol.rs»:«4»›'");
+            test_path!("`‹«/test/co👉ol.rs»:«4»›`");
+
+            test_path!("[‹«/test/co👉ol.rs»:«4»›]");
+            test_path!("(‹«/test/co👉ol.rs»:«4»›)");
+            test_path!("{‹«/test/co👉ol.rs»:«4»›}");
+            test_path!("<‹«/test/co👉ol.rs»:«4»›>");
+
+            test_path!("[\"‹«/test/co👉ol.rs»:«4»›\"]");
+            test_path!("'(‹«/test/co👉ol.rs»:«4»›)'");
+        }
+
         #[test]
         fn word_wide_chars() {
             // Rust paths
-            test_path!(4, 6, 12; "‹«/👉例/cool.rs»›");
-            test_path!(4, 6, 12; "‹«/例👈/cool.rs»›");
-            test_path!(4, 8, 16; "‹«/例/cool.rs»:«👉4»›");
-            test_path!(4, 8, 16; "‹«/例/cool.rs»:«4»:«👉2»›");
+            test_path!("‹«/👉例/cool.rs»›");
+            test_path!("‹«/例👈/cool.rs»›");
+            test_path!("‹«/例/cool.rs»:«👉4»›");
+            test_path!("‹«/例/cool.rs»:«4»:«👉2»›");
 
             // Cargo output
-            test_path!(4, 27, 30; "    Compiling Cool (‹«/👉例/Cool»›)");
-            test_path!(4, 27, 30; "    Compiling Cool (‹«/例👈/Cool»›)");
+            test_path!("    Compiling Cool (‹«/👉例/Cool»›)");
+            test_path!("    Compiling Cool (‹«/例👈/Cool»›)");
 
             // Python
-            test_path!(4, 11; "‹«👉例wesome.py»›");
-            test_path!(4, 11; "‹«例👈wesome.py»›");
-            test_path!(6, 17, 40; "    ‹File \"«/👉例wesome.py»\", line «42»›: Wat?");
-            test_path!(6, 17, 40; "    ‹File \"«/例👈wesome.py»\", line «42»›: Wat?");
+            test_path!("‹«👉例wesome.py»›");
+            test_path!("‹«例👈wesome.py»›");
+            test_path!("    ‹File \"«/👉例wesome.py»\", line «42»›: Wat?");
+            test_path!("    ‹File \"«/例👈wesome.py»\", line «42»›: Wat?");
         }
 
         #[test]
         fn non_word_wide_chars() {
             // Mojo diagnostic message
-            test_path!(4, 18, 38; "    ‹File \"«/awe👉some.🔥»\", line «42»›: Wat?");
-            test_path!(4, 18, 38; "    ‹File \"«/awesome👉.🔥»\", line «42»›: Wat?");
-            test_path!(4, 18, 38; "    ‹File \"«/awesome.👉🔥»\", line «42»›: Wat?");
-            test_path!(4, 18, 38; "    ‹File \"«/awesome.🔥👈»\", line «42»›: Wat?");
+            test_path!("    ‹File \"«/awe👉some.🔥»\", line «42»›: Wat?");
+            test_path!("    ‹File \"«/awesome👉.🔥»\", line «42»›: Wat?");
+            test_path!("    ‹File \"«/awesome.👉🔥»\", line «42»›: Wat?");
+            test_path!("    ‹File \"«/awesome.🔥👈»\", line «42»›: Wat?");
         }
 
         /// These likely rise to the level of being worth fixing.
         mod issues {
             #[test]
-            #[cfg_attr(not(target_os = "windows"), should_panic(expected = "Path = «例»"))]
-            #[cfg_attr(target_os = "windows", should_panic(expected = r#"Path = «C:\\例»"#))]
             // <https://github.com/alacritty/alacritty/issues/8586>
             fn issue_alacritty_8586() {
                 // Rust paths
@@ -689,21 +545,13 @@ mod tests {
         /// Minor issues arguably not important enough to fix/workaround...
         mod nits {
             #[test]
-            #[cfg_attr(
-                not(target_os = "windows"),
-                should_panic(expected = "Path = «/test/cool.rs(4»")
-            )]
-            #[cfg_attr(
-                target_os = "windows",
-                should_panic(expected = r#"Path = «C:\\test\\cool.rs(4»"#)
-            )]
             fn alacritty_bugs_with_two_columns() {
-                test_path!(2; "‹«/👉test/cool.rs»(«4»)›");
-                test_path!(2; "‹«/test/cool.rs»(«👉4»)›");
-                test_path!(2; "‹«/test/cool.rs»(«4»,«👉2»)›");
+                test_path!("‹«/👉test/cool.rs»(«4»)›");
+                test_path!("‹«/test/cool.rs»(«👉4»)›");
+                test_path!("‹«/test/cool.rs»(«4»,«👉2»)›");
 
                 // Python
-                test_path!(2; "‹«awe👉some.py»›");
+                test_path!("‹«awe👉some.py»›");
             }
 
             #[test]
@@ -791,9 +639,6 @@ mod tests {
         ///
         macro_rules! test_file_iri {
             ($file_iri:literal) => { { test_hyperlink!(concat!("‹«👉", $file_iri, "»›"); FileIri) } };
-            ($($columns:literal),+; $file_iri:literal) => { {
-                test_hyperlink!($($columns),+; concat!("‹«👉", $file_iri, "»›"); FileIri)
-            } };
         }
 
         #[cfg(not(target_os = "windows"))]
@@ -865,9 +710,6 @@ mod tests {
         ///
         macro_rules! test_iri {
             ($iri:literal) => { { test_hyperlink!(concat!("‹«👉", $iri, "»›"); Iri) } };
-            ($($columns:literal),+; $iri:literal) => { {
-                test_hyperlink!($($columns),+; concat!("‹«👉", $iri, "»›"); Iri)
-            } };
         }
 
         #[test]
@@ -898,26 +740,26 @@ mod tests {
         #[test]
         fn wide_chars() {
             // In the order they appear in URL_REGEX, except 'file://' which is treated as a path
-            test_iri!(4, 20; "ipfs://例🏃🦀/cool.ipfs");
-            test_iri!(4, 20; "ipns://例🏃🦀/cool.ipns");
-            test_iri!(6, 20; "magnet://例🏃🦀/cool.git");
-            test_iri!(4, 20; "mailto:someone@somewhere.here");
-            test_iri!(4, 20; "gemini://somewhere.here");
-            test_iri!(4, 20; "gopher://somewhere.here");
-            test_iri!(4, 20; "http://例🏃🦀/cool/index.html");
-            test_iri!(4, 20; "http://10.10.10.10:1111/cool.html");
-            test_iri!(4, 20; "http://例🏃🦀/cool/index.html?amazing=1");
-            test_iri!(4, 20; "http://例🏃🦀/cool/index.html#right%20here");
-            test_iri!(4, 20; "http://例🏃🦀/cool/index.html?amazing=1#right%20here");
-            test_iri!(4, 20; "https://例🏃🦀/cool/index.html");
-            test_iri!(4, 20; "https://10.10.10.10:1111/cool.html");
-            test_iri!(4, 20; "https://例🏃🦀/cool/index.html?amazing=1");
-            test_iri!(4, 20; "https://例🏃🦀/cool/index.html#right%20here");
-            test_iri!(4, 20; "https://例🏃🦀/cool/index.html?amazing=1#right%20here");
-            test_iri!(4, 20; "news://例🏃🦀/cool.news");
-            test_iri!(5, 20; "git://例/cool.git");
-            test_iri!(5, 20; "ssh://user@somewhere.over.here:12345/例🏃🦀/cool.git");
-            test_iri!(7, 20; "ftp://例🏃🦀/cool.ftp");
+            test_iri!("ipfs://例🏃🦀/cool.ipfs");
+            test_iri!("ipns://例🏃🦀/cool.ipns");
+            test_iri!("magnet://例🏃🦀/cool.git");
+            test_iri!("mailto:someone@somewhere.here");
+            test_iri!("gemini://somewhere.here");
+            test_iri!("gopher://somewhere.here");
+            test_iri!("http://例🏃🦀/cool/index.html");
+            test_iri!("http://10.10.10.10:1111/cool.html");
+            test_iri!("http://例🏃🦀/cool/index.html?amazing=1");
+            test_iri!("http://例🏃🦀/cool/index.html#right%20here");
+            test_iri!("http://例🏃🦀/cool/index.html?amazing=1#right%20here");
+            test_iri!("https://例🏃🦀/cool/index.html");
+            test_iri!("https://10.10.10.10:1111/cool.html");
+            test_iri!("https://例🏃🦀/cool/index.html?amazing=1");
+            test_iri!("https://例🏃🦀/cool/index.html#right%20here");
+            test_iri!("https://例🏃🦀/cool/index.html?amazing=1#right%20here");
+            test_iri!("news://例🏃🦀/cool.news");
+            test_iri!("git://例/cool.git");
+            test_iri!("ssh://user@somewhere.over.here:12345/例🏃🦀/cool.git");
+            test_iri!("ftp://例🏃🦀/cool.ftp");
         }
 
         // There are likely more tests needed for IRI vs URI
@@ -1006,6 +848,22 @@ mod tests {
             point
         }
 
+        fn end_point_from_prev_input_point(
+            term: &Term<VoidListener>,
+            prev_input_point: AlacPoint,
+        ) -> AlacPoint {
+            if term
+                .grid()
+                .index(prev_input_point)
+                .flags
+                .contains(Flags::WIDE_CHAR)
+            {
+                prev_input_point.add(term, Boundary::Grid, 1)
+            } else {
+                prev_input_point
+            }
+        }
+
         let mut hovered_grid_point: Option<AlacPoint> = None;
         let mut hyperlink_match = AlacPoint::default()..=AlacPoint::default();
         let mut iri_or_path = String::default();
@@ -1040,7 +898,10 @@ mod tests {
                                 panic!("Should have been handled by char input")
                             }
                             CapturesState::Path(start_point) => {
-                                iri_or_path = term.bounds_to_string(start_point, prev_input_point);
+                                iri_or_path = term.bounds_to_string(
+                                    start_point,
+                                    end_point_from_prev_input_point(&term, prev_input_point),
+                                );
                                 CapturesState::RowScan
                             }
                             CapturesState::RowScan => CapturesState::Row(String::new()),
@@ -1065,7 +926,8 @@ mod tests {
                                 panic!("Should have been handled by char input")
                             }
                             MatchState::Match(start_point) => {
-                                hyperlink_match = start_point..=prev_input_point;
+                                hyperlink_match = start_point
+                                    ..=end_point_from_prev_input_point(&term, prev_input_point);
                                 MatchState::Done
                             }
                             MatchState::Done => {

tooling/workspace-hack/Cargo.toml 🔗

@@ -316,8 +316,8 @@ objc2-metal = { version = "0.3" }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "process"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "termios", "time"] }
 scopeguard = { version = "1" }
 security-framework = { version = "3", features = ["OSX_10_14"] }
 security-framework-sys = { version = "2", features = ["OSX_10_14"] }
@@ -347,8 +347,8 @@ object = { version = "0.36", default-features = false, features = ["archive", "r
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "process"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "termios", "time"] }
 scopeguard = { version = "1" }
 security-framework = { version = "3", features = ["OSX_10_14"] }
 security-framework-sys = { version = "2", features = ["OSX_10_14"] }
@@ -377,8 +377,8 @@ objc2-metal = { version = "0.3" }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "process"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "termios", "time"] }
 scopeguard = { version = "1" }
 security-framework = { version = "3", features = ["OSX_10_14"] }
 security-framework-sys = { version = "2", features = ["OSX_10_14"] }
@@ -408,8 +408,8 @@ object = { version = "0.36", default-features = false, features = ["archive", "r
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "process"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "termios", "time"] }
 scopeguard = { version = "1" }
 security-framework = { version = "3", features = ["OSX_10_14"] }
 security-framework-sys = { version = "2", features = ["OSX_10_14"] }
@@ -448,8 +448,8 @@ prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["pro
 quote = { version = "1" }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "shm", "system"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "pty", "stdio", "termios", "time"] }
 scopeguard = { version = "1" }
 syn-f595c2ba2a3f28df = { package = "syn", version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] }
 sync_wrapper = { version = "1", default-features = false, features = ["futures"] }
@@ -488,8 +488,8 @@ proc-macro2 = { version = "1", default-features = false, features = ["span-locat
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "shm", "system"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "pty", "stdio", "termios", "time"] }
 scopeguard = { version = "1" }
 sync_wrapper = { version = "1", default-features = false, features = ["futures"] }
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
@@ -528,8 +528,8 @@ prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["pro
 quote = { version = "1" }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "shm", "system"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "pty", "stdio", "termios", "time"] }
 scopeguard = { version = "1" }
 syn-f595c2ba2a3f28df = { package = "syn", version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] }
 sync_wrapper = { version = "1", default-features = false, features = ["futures"] }
@@ -568,8 +568,8 @@ proc-macro2 = { version = "1", default-features = false, features = ["span-locat
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "shm", "system"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "pty", "stdio", "termios", "time"] }
 scopeguard = { version = "1" }
 sync_wrapper = { version = "1", default-features = false, features = ["futures"] }
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
@@ -661,8 +661,8 @@ prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["pro
 quote = { version = "1" }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "shm", "system"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "pty", "stdio", "termios", "time"] }
 scopeguard = { version = "1" }
 syn-f595c2ba2a3f28df = { package = "syn", version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] }
 sync_wrapper = { version = "1", default-features = false, features = ["futures"] }
@@ -701,8 +701,8 @@ proc-macro2 = { version = "1", default-features = false, features = ["span-locat
 prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
-rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
-rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
+rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "shm", "system"] }
+rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["event", "pipe", "process", "pty", "stdio", "termios", "time"] }
 scopeguard = { version = "1" }
 sync_wrapper = { version = "1", default-features = false, features = ["futures"] }
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }