diff --git a/Cargo.toml b/Cargo.toml index 83ea874e61c..c9a855bdb5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -221,7 +221,7 @@ tempfile = "3" insta = "1.46.3" [features] -default = ["postgres", "libsql", "html-to-markdown"] +default = ["postgres", "libsql", "html-to-markdown", "tui"] postgres = [ "dep:deadpool-postgres", "dep:tokio-postgres", diff --git a/crates/ironclaw_tui/Cargo.toml b/crates/ironclaw_tui/Cargo.toml index 11d3e7b6211..d81bffa2211 100644 --- a/crates/ironclaw_tui/Cargo.toml +++ b/crates/ironclaw_tui/Cargo.toml @@ -9,8 +9,9 @@ license = "MIT OR Apache-2.0" homepage = "https://github.com/nearai/ironclaw" repository = "https://github.com/nearai/ironclaw" -[package.metadata.dist] -dist = false +[features] +default = ["clipboard"] +clipboard = ["dep:arboard", "dep:image"] [dependencies] ratatui = { version = "0.29", features = ["crossterm"] } @@ -23,8 +24,8 @@ unicode-width = "0.2" pulldown-cmark = { version = "0.12", default-features = false } thiserror = "2" tracing = "0.1" -arboard = "3" -image = { version = "0.25", default-features = false, features = ["png"] } +arboard = { version = "3", optional = true } +image = { version = "0.25", default-features = false, features = ["png"], optional = true } [dev-dependencies] tokio = { version = "1", features = ["full"] } diff --git a/crates/ironclaw_tui/src/app.rs b/crates/ironclaw_tui/src/app.rs index a71a4b507eb..969b6597838 100644 --- a/crates/ironclaw_tui/src/app.rs +++ b/crates/ironclaw_tui/src/app.rs @@ -1660,12 +1660,18 @@ fn copy_text_to_clipboard(text: &str) -> bool { true } - #[cfg(not(test))] + #[cfg(all(not(test), feature = "clipboard"))] { arboard::Clipboard::new() .and_then(|mut clipboard| clipboard.set_text(text.to_string())) .is_ok() } + + #[cfg(all(not(test), not(feature = "clipboard")))] + { + let _ = text; + false + } } async fn handle_mouse_click( @@ -2442,6 +2448,7 @@ fn capture_screen_snapshot(frame: &mut ratatui::Frame<'_>, state: &mut AppState) /// Try to read an image from the system clipboard and return it as a PNG-encoded /// [`TuiAttachment`]. Returns `None` if the clipboard has no image data or if /// encoding fails. +#[cfg(feature = "clipboard")] fn try_paste_clipboard_image(state: &AppState) -> Option { let mut clipboard = arboard::Clipboard::new().ok()?; let img_data = clipboard.get_image().ok()?; @@ -2460,8 +2467,14 @@ fn try_paste_clipboard_image(state: &AppState) -> Option { }) } +#[cfg(not(feature = "clipboard"))] +fn try_paste_clipboard_image(_state: &AppState) -> Option { + None +} + /// Encode raw RGBA pixel data to PNG. Returns `None` on invalid dimensions or /// encoding failure. +#[cfg(feature = "clipboard")] fn encode_rgba_to_png(rgba: &[u8], width: u32, height: u32) -> Option> { let expected_len = (width as usize) .checked_mul(height as usize)? @@ -2526,6 +2539,7 @@ mod tests { } } + #[cfg(feature = "clipboard")] #[test] fn encode_rgba_to_png_valid() { // 2x2 red image @@ -2540,6 +2554,7 @@ mod tests { assert_eq!(&bytes[..4], &[0x89, b'P', b'N', b'G']); } + #[cfg(feature = "clipboard")] #[test] fn encode_rgba_to_png_bad_dimensions() { let rgba = vec![0u8; 16]; // 4 pixels @@ -2548,6 +2563,7 @@ mod tests { assert!(png.is_none()); } + #[cfg(feature = "clipboard")] #[test] fn encode_rgba_to_png_zero_size() { // 0x0 image: the image crate rejects zero-dimension buffers