diff --git a/Cargo.lock b/Cargo.lock index e9ec09a7..9de22130 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1613,6 +1613,7 @@ dependencies = [ "aws-credential-types", "aws-sigv4", "aws-smithy-async", + "aws-smithy-eventstream", "aws-smithy-http", "aws-smithy-runtime", "aws-smithy-runtime-api", @@ -1629,6 +1630,34 @@ dependencies = [ "uuid", ] +[[package]] +name = "aws-sdk-bedrockruntime" +version = "1.135.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74b780f2f36912bae71b4f4f8ed9a0a88832b4681a1add3caf5ca25dbc8ab2d" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand 2.4.1", + "http 0.2.12", + "http 1.4.2", + "http-body-util", + "regex-lite", + "tracing", +] + [[package]] name = "aws-sdk-signin" version = "1.14.0" @@ -1737,6 +1766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bae38512beae0ffee7010fc24e7a8a123c53efdfef42a61e80fda4882418dc71" dependencies = [ "aws-credential-types", + "aws-smithy-eventstream", "aws-smithy-http", "aws-smithy-runtime-api", "aws-smithy-types", @@ -1763,12 +1793,24 @@ dependencies = [ "tokio", ] +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d8391e65fcea47c586a22e1a41f173b38615b112b2c6b7a44e80cec3e6b706" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + [[package]] name = "aws-smithy-http" version = "0.63.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" dependencies = [ + "aws-smithy-eventstream", "aws-smithy-runtime-api", "aws-smithy-types", "bytes", @@ -5635,7 +5677,9 @@ dependencies = [ "async-trait", "aws-config", "aws-credential-types", + "aws-sdk-bedrockruntime", "aws-sdk-sts", + "aws-smithy-types", "aws-types", "axum", "base64 0.22.1", @@ -5952,6 +5996,7 @@ dependencies = [ "galaxy_core", "galaxy_js", "galaxy_util", + "galaxyui", "galaxyui_core", "getset", "instant", @@ -9006,6 +9051,7 @@ dependencies = [ "directories", "env_logger", "hf-hub", + "instant", "log", "serde", "serde_json", @@ -9137,6 +9183,7 @@ dependencies = [ "futures", "galaxy_core", "galaxy_util", + "galaxyui", "galaxyui_core", "globset", "http_client", diff --git a/app/Cargo.toml b/app/Cargo.toml index cc07eae1..688b0498 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -333,7 +333,9 @@ tracing-subscriber.workspace = true # AWS SDK (loading credentials for BYO LLM) aws-config = { version = "1.8.16", features = ["credentials-login"] } aws-credential-types = "1" +aws-sdk-bedrockruntime = { version = "1", default-features = false, features = ["default-https-client", "rt-tokio"] } aws-sdk-sts = { version = "1", default-features = false, features = ["default-https-client", "rt-tokio"] } +aws-smithy-types = "1" aws-types = "1" notify-debouncer-full.workspace = true diff --git a/app/src/ai/agent/api.rs b/app/src/ai/agent/api.rs index 1cd4ab33..4372d3f9 100644 --- a/app/src/ai/agent/api.rs +++ b/app/src/ai/agent/api.rs @@ -14,14 +14,14 @@ pub use convert_from::{ MaybeAIAgentOutputMessage, MessageToAIAgentOutputMessageError, }; use futures_lite::Stream; -use mcp::TemplatableMCPServerInfo; -pub use r#impl::generate_multi_agent_output; -use serde::Serialize; use galaxy_core::channel::ChannelState; use galaxy_core::execution_mode::AppExecutionMode; use galaxy_core::features::FeatureFlag; use galaxy_core::user_preferences::GetUserPreferences; use galaxyui::{AppContext, EntityId, SingletonEntity as _}; +use mcp::TemplatableMCPServerInfo; +pub use r#impl::generate_multi_agent_output; +use serde::Serialize; use super::{AIAgentInput, MCPContext, MCPServer, RequestMetadata, Suggestions}; use crate::ai::agent::conversation::AIConversationId; @@ -211,6 +211,11 @@ impl RequestParams { supported_tools_override: None, parent_agent_id: None, agent_name: None, + root_task_id: None, + bedrock_message_history: vec![], + bedrock_progressive_summary: None, + bedrock_tool_result_archive: vec![], + bedrock_messages_sent: std::sync::Arc::new(std::sync::Mutex::new(vec![])), } } @@ -303,7 +308,7 @@ impl RequestParams { let geap_binding: Option<::ai::api_keys::GeapMintBinding> = None; let api_keys = api_key_manager.api_keys_for_request( is_byo_enabled, - user_workspaces.is_aws_bedrock_credentials_enabled(app), + user_workspaces.is_bedrock_enabled(app), geap_binding, ); let is_custom_inference_enabled = user_workspaces.is_custom_inference_enabled(app); diff --git a/app/src/ai/agent/api/convert_conversation.rs b/app/src/ai/agent/api/convert_conversation.rs index ddb785cd..4f3cac88 100644 --- a/app/src/ai/agent/api/convert_conversation.rs +++ b/app/src/ai/agent/api/convert_conversation.rs @@ -14,8 +14,8 @@ use ai::agent::action_result::{ }; use ai::skills::{ParsedSkill, SkillPathOrigin}; use chrono::{DateTime, Local, TimeZone}; -use persistence::model::AgentConversationData; use galaxy_core::command::ExitCode; +use persistence::model::AgentConversationData; use warp_multi_agent_api as api; use warp_multi_agent_api::ask_user_question_result::answer_item::Answer as AskUserQuestionAnswer; @@ -89,6 +89,8 @@ pub fn convert_conversation_data_to_ai_conversation( autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }, RestorationMode::Continue => AgentConversationData { server_conversation_token: Some( @@ -110,6 +112,8 @@ pub fn convert_conversation_data_to_ai_conversation( autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }, }; diff --git a/app/src/ai/agent/api/convert_conversation_tests.rs b/app/src/ai/agent/api/convert_conversation_tests.rs index f12f809c..344815ca 100644 --- a/app/src/ai/agent/api/convert_conversation_tests.rs +++ b/app/src/ai/agent/api/convert_conversation_tests.rs @@ -31,6 +31,7 @@ fn test_server_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: ServerMetadata { uid: ServerId::default(), diff --git a/app/src/ai/agent/api/impl.rs b/app/src/ai/agent/api/impl.rs index 12bb411c..e5b1cb8e 100644 --- a/app/src/ai/agent/api/impl.rs +++ b/app/src/ai/agent/api/impl.rs @@ -8,11 +8,15 @@ use warp_multi_agent_api as api; use super::convert_to::convert_input; use super::{ConvertToAPITypeError, RequestParams, ResponseStream}; use crate::ai::agent::redaction; -use crate::server::server_api::{AIApiError, ServerApi}; +use crate::ai::openai::translator as openai_translator; +use crate::ai::provider::ProviderConfig; +use crate::server::server_api::ai::AIClient; +use crate::server::server_api::AIApiError; use crate::terminal::model::session::SessionType; pub async fn generate_multi_agent_output( provider_config: ProviderConfig, + server_api: Arc, mut params: RequestParams, cancellation_rx: futures::channel::oneshot::Receiver<()>, ) -> Result { @@ -65,9 +69,9 @@ pub async fn generate_multi_agent_output( input: Some(convert_input(params.input)?), settings: Some(api::request::Settings { model_config: Some(api::request::settings::ModelConfig { - base: params.model.into(), - cli_agent: params.cli_agent_model.into(), - computer_use_agent: params.computer_use_model.into(), + base: params.model.clone().into(), + cli_agent: params.cli_agent_model.clone().into(), + computer_use_agent: params.computer_use_model.clone().into(), base_model_context_window_limit: params.context_window_limit.unwrap_or(0), ..Default::default() }), @@ -136,24 +140,11 @@ pub async fn generate_multi_agent_output( mcp_context: params.mcp_context.map(Into::into), }; - let response_stream = - warp_multi_agent_client::generate_multi_agent_output(server_api.as_ref(), &request).await; - match response_stream { - Ok(stream) => { - let output_stream = stream - .then(|result| async { - match result { - Ok(event) => Ok(event), - Err(error) => Err(convert_multi_agent_client_error(error).await), - } - }) - .take_until(cancellation_rx); - Ok(Box::pin(output_stream)) - } + match provider_config { ProviderConfig::OpenAI(config) => { let translator_request = openai_translator::TranslatorRequest { config, - model_id, + model_id: params.model.as_str().to_string(), root_task_id: params.root_task_id.clone(), message_history: params.bedrock_message_history.clone(), tool_result_archive: params.bedrock_tool_result_archive.clone(), @@ -178,19 +169,60 @@ pub async fn generate_multi_agent_output( } } } + ProviderConfig::Bedrock(config) => { + let translator_request = crate::ai::bedrock::translator::TranslatorRequest { + config, + model_id: params.model.as_str().to_string(), + root_task_id: params.root_task_id.clone(), + bedrock_message_history: params.bedrock_message_history.clone(), + bedrock_tool_result_archive: params.bedrock_tool_result_archive.clone(), + bedrock_progressive_summary: params.bedrock_progressive_summary.clone(), + bedrock_messages_sent: params.bedrock_messages_sent.clone(), + }; + + match crate::ai::bedrock::translator::execute(translator_request, &mut request).await { + Ok(stream) => { + let output_stream = stream.take_until(cancellation_rx); + Ok(Box::pin(output_stream)) + } + Err(e) => { + log::error!("[bedrock] Translator error: {e}"); + let err = Arc::new(crate::server::server_api::AIApiError::Stream { + stream_type: "bedrock", + source: anyhow::anyhow!("{e}"), + }); + let (tx, rx) = async_channel::unbounded(); + let _ = tx.send(Err(err)).await; + Ok(Box::pin(rx)) + } + } + } ProviderConfig::None => { - log::error!("No AI provider configured. Cannot process request."); - let err = Arc::new(crate::server::server_api::AIApiError::Stream { - stream_type: "provider_dispatch", - source: anyhow::anyhow!( - "No AI backend available. Please configure a provider in Settings > AI." - ), - }); - let (tx, rx) = async_channel::unbounded(); - let _ = tx - .send(Err(convert_multi_agent_client_error(e).await)) - .await; - Ok(Box::pin(rx)) + let response_stream = warp_multi_agent_client::generate_multi_agent_output( + server_api.base_client().as_ref(), + &request, + ) + .await; + match response_stream { + Ok(stream) => { + let output_stream = stream + .then(|result| async { + match result { + Ok(event) => Ok(event), + Err(error) => Err(convert_multi_agent_client_error(error).await), + } + }) + .take_until(cancellation_rx); + Ok(Box::pin(output_stream)) + } + Err(e) => { + let (tx, rx) = async_channel::unbounded(); + let _ = tx + .send(Err(convert_multi_agent_client_error(e).await)) + .await; + Ok(Box::pin(rx)) + } + } } } } diff --git a/app/src/ai/agent/conversation.rs b/app/src/ai/agent/conversation.rs index b81edea7..2643a29a 100644 --- a/app/src/ai/agent/conversation.rs +++ b/app/src/ai/agent/conversation.rs @@ -5,10 +5,6 @@ use ai::agent::orchestration_config::{OrchestrationConfig, OrchestrationConfigSt use ai::document::AIDocumentId; use ai::skills::SkillPathOrigin; use chrono::{DateTime, Local, TimeZone}; -use itertools::Itertools as _; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; -use vec1::{Size0Error, Vec1}; use galaxy_cli::agent::Harness; use galaxy_core::command::ExitCode; use galaxy_core::execution_mode::AppExecutionMode; @@ -16,12 +12,16 @@ use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; +use galaxyui::color::ColorU; +use galaxyui::{AppContext, EntityId, ModelContext, SingletonEntity}; +use itertools::Itertools as _; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; +use vec1::{Size0Error, Vec1}; use warp_multi_agent_api::response_event::stream_finished; use warp_multi_agent_api::response_event::stream_finished::TokenUsage; use warp_multi_agent_api::{self as api}; -use galaxyui::color::ColorU; -use galaxyui::{AppContext, EntityId, ModelContext, SingletonEntity}; use super::api::ServerConversationToken; use super::task::helper::*; @@ -327,6 +327,12 @@ pub struct AIConversation { /// Whether the user has pinned this child agent in the orchestration /// pill bar. Persisted via `AgentConversationData.pinned`. pinned: bool, + bedrock_message_history: Vec, + tool_result_archive: Vec, + progressive_summary: Option, + messages_summarized_up_to: usize, + current_context_tokens: u32, + has_pending_progressive_summary: bool, } pub(crate) fn artifact_from_fork_proto( @@ -382,6 +388,12 @@ impl AIConversation { last_event_sequence: None, orchestration_configs: HashMap::new(), pinned: false, + bedrock_message_history: Vec::new(), + tool_result_archive: Vec::new(), + progressive_summary: None, + messages_summarized_up_to: 0, + current_context_tokens: 0, + has_pending_progressive_summary: false, } } @@ -413,6 +425,12 @@ impl AIConversation { tasks: Vec, conversation_data: Option, ) -> Result { + let bedrock_message_history: Vec = tasks + .iter() + .flat_map(|task| task.messages.iter()) + .filter_map(crate::ai::bedrock::request_translator::convert_proto_message) + .collect(); + let (task_store, todo_lists, status) = if tasks.is_empty() { // Bypass `derive_status_from_root_task`: it would return `Success` // for a root with no exchanges, silently misclassifying a restored @@ -518,6 +536,8 @@ impl AIConversation { autoexecute_override, last_event_sequence, pinned, + progressive_summary, + messages_summarized_up_to, ) = if let Some(data) = conversation_data { let server_conversation_token = data .server_conversation_token @@ -565,6 +585,8 @@ impl AIConversation { autoexecute_override, data.last_event_sequence, data.pinned, + data.progressive_summary.clone(), + data.messages_summarized_up_to, ) } else { ( @@ -582,9 +604,33 @@ impl AIConversation { AIConversationAutoexecuteMode::default(), None, false, + None, + 0, ) }; + let restored_token_usage = { + let mut map = HashMap::new(); + let cache_read = conversation_usage_metadata.total_cache_read_tokens; + let cache_write = conversation_usage_metadata.total_cache_write_tokens; + let cache_miss = conversation_usage_metadata.total_cache_miss_tokens; + let cost = conversation_usage_metadata.total_cost_cents; + if cache_read > 0 || cache_write > 0 || cache_miss > 0 || cost > 0.0 { + map.insert( + "restored".to_string(), + TokenUsage { + model_id: "restored".to_string(), + total_input: cache_miss, + output: 0, + input_cache_read: cache_read, + input_cache_write: cache_write, + cost_in_cents: cost, + }, + ); + } + map + }; + Ok(Self { id, is_viewing_shared_session: false, @@ -622,6 +668,12 @@ impl AIConversation { last_event_sequence, orchestration_configs: HashMap::new(), pinned, + bedrock_message_history, + tool_result_archive: Vec::new(), + progressive_summary, + messages_summarized_up_to, + current_context_tokens: 0, + has_pending_progressive_summary: false, }) } @@ -629,6 +681,22 @@ impl AIConversation { self.id } + pub fn current_context_tokens(&self) -> u32 { + self.current_context_tokens + } + + pub fn set_current_context_tokens(&mut self, val: u32) { + self.current_context_tokens = val; + } + + pub fn has_pending_progressive_summary(&self) -> bool { + self.has_pending_progressive_summary + } + + pub fn set_has_pending_progressive_summary(&mut self, val: bool) { + self.has_pending_progressive_summary = val; + } + pub fn bedrock_message_history(&self) -> &[crate::ai::bedrock::convert::ConversationMessage] { &self.bedrock_message_history } @@ -765,6 +833,10 @@ impl AIConversation { self.conversation_usage_metadata.context_window_usage } + pub fn set_context_window_usage(&mut self, val: f32) { + self.conversation_usage_metadata.context_window_usage = val; + } + /// The per-segment breakdown of the context window (e.g. system prompt, /// tool definitions, conversation history). Scaled so the segments sum to /// `context_window_usage`. Empty when the server did not emit segments. @@ -963,7 +1035,7 @@ impl AIConversation { // Sanity check: reject durations that are clearly wrong (> 24 hours // likely means start_time defaulted to epoch during session restore). - if ms < 0 || ms > 86_400_000 { + if !(0..=86_400_000).contains(&ms) { return None; } Some(ms) @@ -2447,7 +2519,7 @@ impl AIConversation { let is_hidden = self.is_exchange_hidden(exchange_id); ctx.emit(BlocklistAIHistoryEvent::UpdatedStreamingExchange { exchange_id, - terminal_view_id, + terminal_surface_id: terminal_view_id, conversation_id: self.id, is_hidden, }); @@ -3278,7 +3350,7 @@ impl AIConversation { response_stream_id: Some(response_stream_id.clone()), exchange_id, task_id: task_id.clone(), - terminal_view_id, + terminal_surface_id, conversation_id: self.id, is_hidden, }); @@ -3465,7 +3537,7 @@ impl AIConversation { &mut self, block_id: &BlockId, ) -> TaskId { - let new_task = Task::new_optimistic_cli_agent_subtask(block_id.clone()); + let new_task = Task::new_optimistic_cli_agent_subtask(block_id.clone(), None); let new_task_id = new_task.id().clone(); self.optimistic_cli_subagent_subtask_id = Some(new_task_id.clone()); self.task_store.insert(new_task); @@ -3670,6 +3742,8 @@ impl AIConversation { autoexecute_override: Some(self.autoexecute_override.into()), last_event_sequence: self.last_event_sequence, pinned: self.pinned, + progressive_summary: self.progressive_summary.clone(), + messages_summarized_up_to: self.messages_summarized_up_to, }, }; ctx.spawn( @@ -4784,7 +4858,7 @@ impl ConversationStatus { pub fn status_icon_and_color( &self, - theme: &WarpTheme, + theme: &GalaxyTheme, color_style: StatusColorStyle, ) -> (Icon, ColorU) { match self { diff --git a/app/src/ai/agent/mod.rs b/app/src/ai/agent/mod.rs index 342035d8..435c6489 100644 --- a/app/src/ai/agent/mod.rs +++ b/app/src/ai/agent/mod.rs @@ -27,6 +27,8 @@ use ai::skills::ParsedSkill; use chrono::{DateTime, Local, TimeDelta}; use comment::ReviewComment; use derivative::Derivative; +use galaxy_core::channel::ChannelState; +use galaxy_core::features::FeatureFlag; use markdown_parser::{parse_markdown, FormattedTable, FormattedText, FormattedTextInline}; use parking_lot::RwLock; use serde::{Deserialize, Serialize}; @@ -34,8 +36,6 @@ use session_sharing_protocol::common::ParticipantId; use task::TaskId; pub use telemetry::AIIdentifiers; use uuid::Uuid; -use galaxy_core::channel::ChannelState; -use galaxy_core::features::FeatureFlag; use warp_editor::render::model::LineCount; use warp_multi_agent_api::{diff_hunk as diff_hunk_api, AgentEvent, AgentType}; diff --git a/app/src/ai/agent/task.rs b/app/src/ai/agent/task.rs index bd14622c..5ce6cb48 100644 --- a/app/src/ai/agent/task.rs +++ b/app/src/ai/agent/task.rs @@ -119,6 +119,7 @@ struct ServerTask { } mod optimistic { + use crate::terminal::model::block::BlockId; #[derive(Debug, Clone)] pub(super) struct CLIAgentSubtask { @@ -211,7 +212,7 @@ impl Task { subagent_params: Some(SubagentParams { tool_call_id: String::new(), call: api::message::tool_call::Subagent { - task_id: task_id, + task_id, payload: String::new(), metadata: Some(Metadata::Cli( api::message::tool_call::subagent::CliSubagent { @@ -815,13 +816,7 @@ impl Task { "[bedrock] append_to_message_content: message_id={} not found, treating as implicit add", message.id ); - self.add_messages( - vec![message], - exchange_id, - current_todo_list, - current_comments, - false, - )?; + self.add_messages(vec![message], exchange_id, message_context, false)?; return self .try_get_source()? .messages diff --git a/app/src/ai/agent/task_store_tests.rs b/app/src/ai/agent/task_store_tests.rs index 368617f6..af4ea066 100644 --- a/app/src/ai/agent/task_store_tests.rs +++ b/app/src/ai/agent/task_store_tests.rs @@ -11,6 +11,7 @@ use crate::ai::agent::{ SubagentCall, }; use crate::ai::llms::LLMId; +use crate::terminal::model::block::BlockId; fn create_test_exchange() -> AIAgentExchange { AIAgentExchange { @@ -40,7 +41,6 @@ fn create_test_task_with_exchanges(exchange_count: usize) -> Task { } fn create_test_subtask_with_exchanges(exchange_count: usize) -> Task { - use crate::terminal::model::block::BlockId; let mut task = Task::new_optimistic_cli_agent_subtask(BlockId::new(), None); for _ in 0..exchange_count { task.append_exchange(create_test_exchange()); diff --git a/app/src/ai/agent/todos/popup.rs b/app/src/ai/agent/todos/popup.rs index 91dd5d9a..78ee5fae 100644 --- a/app/src/ai/agent/todos/popup.rs +++ b/app/src/ai/agent/todos/popup.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -12,6 +11,7 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use pathfinder_color::ColorU; use crate::ai::agent::icons::{in_progress_icon, pending_icon, succeeded_icon}; use crate::ai::agent::todos::AIAgentTodoList; diff --git a/app/src/ai/agent_conversations_model.rs b/app/src/ai/agent_conversations_model.rs index 6d4aa227..ee124116 100644 --- a/app/src/ai/agent_conversations_model.rs +++ b/app/src/ai/agent_conversations_model.rs @@ -11,15 +11,15 @@ pub use entry::{ AgentConversationProvenance, }; use futures::stream::AbortHandle; -use instant::Instant; -use itertools::Itertools; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use warp_cli::agent::Harness; use galaxy_core::execution_mode::AppExecutionMode; use galaxy_core::features::FeatureFlag; use galaxy_core::report_error; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; +use instant::Instant; +use itertools::Itertools; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use warp_cli::agent::Harness; use warpui::color::ColorU; use warpui::r#async::Timer; use warpui::windowing::{StateEvent, WindowManager}; @@ -1921,8 +1921,8 @@ impl AgentConversationsModel { }); // Sort each by updated_at (newest first), truncate - personal.sort_by(|a, b| b.1.updated_at.cmp(&a.1.updated_at)); - team.sort_by(|a, b| b.1.updated_at.cmp(&a.1.updated_at)); + personal.sort_by_key(|b| std::cmp::Reverse(b.1.updated_at)); + team.sort_by_key(|b| std::cmp::Reverse(b.1.updated_at)); personal.truncate(MAX_PERSONAL_TASKS); team.truncate(MAX_TEAM_TASKS); diff --git a/app/src/ai/agent_conversations_model/entry.rs b/app/src/ai/agent_conversations_model/entry.rs index bcc982b4..89d69a19 100644 --- a/app/src/ai/agent_conversations_model/entry.rs +++ b/app/src/ai/agent_conversations_model/entry.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, Utc}; +use galaxy_core::features::FeatureFlag; use session_sharing_protocol::common::SessionId; use warp_cli::agent::Harness; -use galaxy_core::features::FeatureFlag; use warpui::{AppContext, SingletonEntity}; use super::{ diff --git a/app/src/ai/agent_conversations_model_tests.rs b/app/src/ai/agent_conversations_model_tests.rs index 5576a1c0..bbaba991 100644 --- a/app/src/ai/agent_conversations_model_tests.rs +++ b/app/src/ai/agent_conversations_model_tests.rs @@ -3,13 +3,12 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use chrono::{DateTime, Duration, Utc}; +use galaxy_cli::agent::Harness; use galaxy_core::features::FeatureFlag; -use galaxyui::{App, EntityId}; +use galaxyui::{App, EntityId, ModelHandle, SingletonEntity}; use instant::Instant; use parking_lot::Mutex; use persistence::model::{AgentConversationData, ConversationUsageMetadata}; -use galaxy_cli::agent::Harness; -use galaxyui::{App, EntityId, ModelHandle, SingletonEntity}; use super::entry::{ AgentConversationEntryId, AgentConversationNavigationSubject, AgentConversationProvenance, @@ -238,6 +237,7 @@ fn test_title_update_refreshes_shadowing_task_title() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -344,6 +344,7 @@ fn test_display_status_uses_matching_conversation_for_in_progress_task() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -400,6 +401,7 @@ fn test_display_status_uses_active_execution_over_previous_conversation_status() autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -463,6 +465,7 @@ fn test_display_status_updates_when_blocked_conversation_resumes() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -542,6 +545,7 @@ fn test_display_status_terminal_task_state_overrides_matching_conversation() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -597,6 +601,7 @@ fn test_status_filter_uses_display_status_for_task_backed_conversations() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -792,6 +797,7 @@ fn create_server_conversation_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: mock_server_metadata(), creator: None, @@ -928,6 +934,7 @@ fn test_get_entries_merges_task_and_local_conversation_by_run_id() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -983,6 +990,7 @@ fn test_get_entries_merges_task_and_local_conversation_by_server_token() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -1191,6 +1199,7 @@ fn test_resolve_open_action_returns_none_for_active_unattachable_session() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -1477,6 +1486,7 @@ fn test_server_token_assignment_updates_copy_link_resolution() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -1639,6 +1649,7 @@ fn test_resolve_copy_link_uses_attached_synced_conversation_for_task_without_tok autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -1966,6 +1977,7 @@ fn test_get_entries_prefers_task_when_task_id_matches_conversation_run_id() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -2027,6 +2039,7 @@ fn test_get_entries_prefers_task_when_server_token_matches() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); diff --git a/app/src/ai/agent_events/driver.rs b/app/src/ai/agent_events/driver.rs index bcf7dbd2..0301e8e1 100644 --- a/app/src/ai/agent_events/driver.rs +++ b/app/src/ai/agent_events/driver.rs @@ -5,9 +5,9 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use futures::future::Either; use futures::StreamExt; +use galaxy_core::errors::AnyhowErrorExt as _; use galaxyui::r#async::Timer; use instant::Instant; -use galaxy_core::errors::AnyhowErrorExt as _; use crate::server::retry_strategies::is_transient_http_error; use crate::server::server_api::ai::AgentRunEvent; diff --git a/app/src/ai/agent_events/message_hydrator.rs b/app/src/ai/agent_events/message_hydrator.rs index 4afea8c4..abcac36d 100644 --- a/app/src/ai/agent_events/message_hydrator.rs +++ b/app/src/ai/agent_events/message_hydrator.rs @@ -5,11 +5,11 @@ use anyhow::{anyhow, Context, Result}; #[cfg(not(target_family = "wasm"))] use futures::future::Either; #[cfg(not(target_family = "wasm"))] +use galaxyui::r#async::Timer; +#[cfg(not(target_family = "wasm"))] use instant::Instant; #[cfg(not(target_family = "wasm"))] use reqwest::Error as ReqwestError; -#[cfg(not(target_family = "wasm"))] -use galaxyui::r#async::Timer; use crate::ai::agent::ReceivedMessageInput; use crate::ai::ambient_agents::AmbientAgentTaskId; diff --git a/app/src/ai/agent_management/agent_management_model_tests.rs b/app/src/ai/agent_management/agent_management_model_tests.rs index eefaafff..f2de3f1f 100644 --- a/app/src/ai/agent_management/agent_management_model_tests.rs +++ b/app/src/ai/agent_management/agent_management_model_tests.rs @@ -1,6 +1,6 @@ -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxyui::{App, EntityId, ModelHandle, SingletonEntity}; +use settings::Setting as _; use super::AgentNotificationsModel; use crate::ai::active_agent_views_model::ActiveAgentViewsModel; diff --git a/app/src/ai/agent_management/agent_type_selector.rs b/app/src/ai/agent_management/agent_type_selector.rs index 10891c2d..71504d04 100644 --- a/app/src/ai/agent_management/agent_type_selector.rs +++ b/app/src/ai/agent_management/agent_type_selector.rs @@ -3,8 +3,6 @@ //! This modal is displayed when users click "New agent" to choose between //! cloud and local agent modes. -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ @@ -17,6 +15,8 @@ use galaxyui::keymap::{FixedBinding, Keystroke}; use galaxyui::platform::Cursor; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/ai/agent_management/cloud_setup_guide_view.rs b/app/src/ai/agent_management/cloud_setup_guide_view.rs index 8975c4ac..61aea084 100644 --- a/app/src/ai/agent_management/cloud_setup_guide_view.rs +++ b/app/src/ai/agent_management/cloud_setup_guide_view.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; +use galaxy_core::report_error; +use galaxy_core::ui::theme::{AnsiColorIdentifier, AnsiColors}; use serde::Serialize; use string_offset::CharCounter; use warp_completer::signatures::CommandRegistry; use warp_completer::util::parse_current_commands_and_tokens; use warp_completer::ParsedTokensSnapshot; -use galaxy_core::report_error; -use galaxy_core::ui::theme::{AnsiColorIdentifier, AnsiColors}; use warpui::clipboard::ClipboardContent; use warpui::elements::new_scrollable::{ClippedAxisConfiguration, DualAxisConfig, NewScrollable}; use warpui::elements::{ diff --git a/app/src/ai/agent_management/notifications/item_rendering.rs b/app/src/ai/agent_management/notifications/item_rendering.rs index 2d4889e3..64266ef4 100644 --- a/app/src/ai/agent_management/notifications/item_rendering.rs +++ b/app/src/ai/agent_management/notifications/item_rendering.rs @@ -1,10 +1,9 @@ use std::sync::Arc; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance as CoreAppearance; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme, WarpTheme}; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, @@ -14,6 +13,7 @@ use galaxyui::elements::{ use galaxyui::fonts::Weight; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{View, ViewContext, ViewHandle}; +use pathfinder_color::ColorU; use crate::ai::agent::conversation::ConversationStatus; use crate::ai::agent_management::notifications::item::NotificationSourceAgent; diff --git a/app/src/ai/agent_management/view.rs b/app/src/ai/agent_management/view.rs index f137a95b..8a534339 100644 --- a/app/src/ai/agent_management/view.rs +++ b/app/src/ai/agent_management/view.rs @@ -4,13 +4,6 @@ use std::sync::Arc; use fuzzy_match::match_indices_case_insensitive; use galaxy_core::features::FeatureFlag; -use galaxyui::scene::DropShadow; -use galaxyui::ui_components::button::ButtonVariant; -use lazy_static::lazy_static; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use settings::Setting; -use siphasher::sip::SipHasher; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; @@ -28,11 +21,18 @@ use galaxyui::elements::{ use galaxyui::fonts::{Properties, Weight}; use galaxyui::keymap::FixedBinding; use galaxyui::platform::Cursor; +use galaxyui::scene::DropShadow; +use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use lazy_static::lazy_static; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use settings::Setting; +use siphasher::sip::SipHasher; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent_conversations_model::{ diff --git a/app/src/ai/agent_sdk/admin.rs b/app/src/ai/agent_sdk/admin.rs index d580eab7..6e2bc4ad 100644 --- a/app/src/ai/agent_sdk/admin.rs +++ b/app/src/ai/agent_sdk/admin.rs @@ -2,10 +2,9 @@ use anyhow::{Context, Result}; use galaxy_cli::agent::OutputFormat; -use galaxyui::{platform::TerminationMode, AppContext, SingletonEntity}; -use serde::Serialize; use galaxyui::platform::TerminationMode; use galaxyui::{AppContext, SingletonEntity}; +use serde::Serialize; use crate::auth::auth_manager::{AuthManager, AuthManagerEvent}; use crate::auth::user::PrincipalType; diff --git a/app/src/ai/agent_sdk/ambient.rs b/app/src/ai/agent_sdk/ambient.rs index d324e7da..09aea8a0 100644 --- a/app/src/ai/agent_sdk/ambient.rs +++ b/app/src/ai/agent_sdk/ambient.rs @@ -6,6 +6,8 @@ use std::time::Duration; use anyhow::{anyhow, Context as _}; use comfy_table::Cell; use futures::{future, StreamExt}; +use galaxy_core::channel::ChannelState; +use galaxy_core::features::FeatureFlag; use serde::Serialize; use warp_cli::agent::{Harness, OutputFormat, Prompt, RunCloudArgs}; use warp_cli::json_filter::JsonOutput; @@ -15,8 +17,6 @@ use warp_cli::task::{ RunSourceArg, RunStateArg, TaskGetArgs, }; use warp_cli::{GlobalOptions, SortOrderArg}; -use galaxy_core::channel::ChannelState; -use galaxy_core::features::FeatureFlag; use warpui::platform::TerminationMode; use warpui::r#async::{Spawnable, Timer}; use warpui::{AppContext, ModelContext, SingletonEntity}; diff --git a/app/src/ai/agent_sdk/artifact_tests.rs b/app/src/ai/agent_sdk/artifact_tests.rs index 4216b29c..0afcfb2a 100644 --- a/app/src/ai/agent_sdk/artifact_tests.rs +++ b/app/src/ai/agent_sdk/artifact_tests.rs @@ -1,6 +1,6 @@ -use galaxy_cli::agent::OutputFormat; use std::path::PathBuf; +use galaxy_cli::agent::OutputFormat; use super::*; diff --git a/app/src/ai/agent_sdk/artifact_upload_tests.rs b/app/src/ai/agent_sdk/artifact_upload_tests.rs index e4bc4b83..a8de330f 100644 --- a/app/src/ai/agent_sdk/artifact_upload_tests.rs +++ b/app/src/ai/agent_sdk/artifact_upload_tests.rs @@ -43,6 +43,7 @@ fn create_conversation_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: create_mock_server_metadata(), creator: None, diff --git a/app/src/ai/agent_sdk/driver.rs b/app/src/ai/agent_sdk/driver.rs index 95b10068..a6f5ef38 100644 --- a/app/src/ai/agent_sdk/driver.rs +++ b/app/src/ai/agent_sdk/driver.rs @@ -15,6 +15,8 @@ use anyhow::{anyhow, Context as _}; use futures::channel::oneshot; use futures::future::{self, join_all, Either}; use futures::FutureExt as _; +use galaxy_core::features::FeatureFlag; +use galaxy_core::{report_error, report_if_error, safe_debug, safe_error, safe_info}; use handlebars::get_arguments; use itertools::Itertools as _; use oneshot::{Canceled, Receiver}; @@ -26,8 +28,6 @@ use warp_cli::agent::{Harness, OutputFormat}; use warp_cli::mcp::MCPSpec; use warp_cli::share::ShareRequest; use warp_cli::skill::SkillSpec; -use galaxy_core::features::FeatureFlag; -use galaxy_core::{report_error, report_if_error, safe_debug, safe_error, safe_info}; use warp_graphql::ai::AgentTaskState; use warp_managed_secrets::ManagedSecretValue; use warp_util::local_or_remote_path::LocalOrRemotePath; diff --git a/app/src/ai/agent_sdk/driver/environment.rs b/app/src/ai/agent_sdk/driver/environment.rs index e328ff40..66c7839d 100644 --- a/app/src/ai/agent_sdk/driver/environment.rs +++ b/app/src/ai/agent_sdk/driver/environment.rs @@ -9,13 +9,13 @@ use ai::index::full_source_code_embedding::manager::{ }; use futures::channel::oneshot; use futures::future::join_all; -use repo_metadata::repositories::{DetectedRepositories, RepoDetectionSource}; use galaxy_cli::agent::Harness; use galaxy_completer::completer::CommandExitStatus; use galaxy_core::command::ExitCode; use galaxy_core::{safe_info, safe_warn}; use galaxyui::r#async::FutureExt; use galaxyui::{ModelContext, ModelSpawner, SingletonEntity}; +use repo_metadata::repositories::{DetectedRepositories, RepoDetectionSource}; use super::terminal::TerminalDriver; use super::AgentDriverError; diff --git a/app/src/ai/agent_sdk/driver/harness/claude_code.rs b/app/src/ai/agent_sdk/driver/harness/claude_code.rs index c5b6da7e..0a2463a4 100644 --- a/app/src/ai/agent_sdk/driver/harness/claude_code.rs +++ b/app/src/ai/agent_sdk/driver/harness/claude_code.rs @@ -7,13 +7,13 @@ use std::sync::Arc; use anyhow::{Context, Result}; use async_trait::async_trait; use galaxy_cli::agent::Harness; +use galaxy_managed_secrets::ManagedSecretValue; use galaxyui::{ModelHandle, ModelSpawner}; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use tempfile::NamedTempFile; use uuid::Uuid; -use galaxy_managed_secrets::ManagedSecretValue; use super::super::terminal::{CommandHandle, TerminalDriver}; use super::super::{AgentDriver, AgentDriverError}; diff --git a/app/src/ai/agent_sdk/driver/harness/codex.rs b/app/src/ai/agent_sdk/driver/harness/codex.rs index 83da2863..0e0426e9 100644 --- a/app/src/ai/agent_sdk/driver/harness/codex.rs +++ b/app/src/ai/agent_sdk/driver/harness/codex.rs @@ -6,13 +6,13 @@ use std::sync::{Arc, OnceLock}; use anyhow::{Context, Result}; use async_trait::async_trait; +use galaxy_core::features::FeatureFlag; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use tempfile::NamedTempFile; use uuid::Uuid; use warp_cli::agent::Harness; -use galaxy_core::features::FeatureFlag; use warp_managed_secrets::ManagedSecretValue; use warpui::{ModelHandle, ModelSpawner, SingletonEntity}; diff --git a/app/src/ai/agent_sdk/driver/harness/mod.rs b/app/src/ai/agent_sdk/driver/harness/mod.rs index 8457792d..95a59b48 100644 --- a/app/src/ai/agent_sdk/driver/harness/mod.rs +++ b/app/src/ai/agent_sdk/driver/harness/mod.rs @@ -9,14 +9,14 @@ use std::sync::Arc; use anyhow::{Context, Result}; use async_trait::async_trait; use galaxy_cli::agent::Harness; -use galaxy_managed_secrets::ManagedSecretValue; -use galaxyui::{ModelHandle, ModelSpawner, SingletonEntity}; -use tempfile::NamedTempFile; use galaxy_cli::{ OZ_CLI_ENV, OZ_HARNESS_ENV, OZ_PARENT_RUN_ID_ENV, OZ_RUN_ID_ENV, SERVER_ROOT_URL_OVERRIDE_ENV, SESSION_SHARING_SERVER_URL_OVERRIDE_ENV, WS_SERVER_URL_OVERRIDE_ENV, }; use galaxy_core::channel::ChannelState; +use galaxy_managed_secrets::ManagedSecretValue; +use galaxyui::{ModelHandle, ModelSpawner, SingletonEntity}; +use tempfile::NamedTempFile; use super::terminal::{CommandHandle, TerminalDriver}; use super::{ diff --git a/app/src/ai/agent_sdk/driver/harness/mod_tests.rs b/app/src/ai/agent_sdk/driver/harness/mod_tests.rs index 8749f096..bf82fc2b 100644 --- a/app/src/ai/agent_sdk/driver/harness/mod_tests.rs +++ b/app/src/ai/agent_sdk/driver/harness/mod_tests.rs @@ -1,6 +1,6 @@ use warp_cli::agent::Harness; -use super::{auth_check_command_for, validate_cli_installed}; +use super::{auth_check_command_for, validate_cli_installed, ThirdPartyHarness}; use crate::ai::agent_sdk::driver::AgentDriverError; fn assert_harness_setup_failed(err: &AgentDriverError) -> (&str, &str) { diff --git a/app/src/ai/agent_sdk/driver/harness/telemetry.rs b/app/src/ai/agent_sdk/driver/harness/telemetry.rs index b861141f..d7ffa383 100644 --- a/app/src/ai/agent_sdk/driver/harness/telemetry.rs +++ b/app/src/ai/agent_sdk/driver/harness/telemetry.rs @@ -1,6 +1,6 @@ +use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; use serde_json::{json, Value}; use strum_macros::{EnumDiscriminants, EnumIter}; -use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; /// Telemetry events emitted by the third-party harness runtime layer. #[derive(Debug, EnumDiscriminants)] diff --git a/app/src/ai/agent_sdk/driver/output.rs b/app/src/ai/agent_sdk/driver/output.rs index bb4c8ca2..5040ce90 100644 --- a/app/src/ai/agent_sdk/driver/output.rs +++ b/app/src/ai/agent_sdk/driver/output.rs @@ -564,17 +564,19 @@ pub mod text { pub mod json { use std::borrow::Cow; + use std::io::{self, Write}; use std::ops::Range; use serde::Serialize; use crate::ai::agent::comment::ReviewComment; use crate::ai::agent::{ - AIAgentActionType, AIAgentInput, AIAgentOutput, AIAgentOutputMessage, - AIAgentOutputMessageType, AIAgentTodo, ArtifactCreatedData, CallMCPToolResult, FileContext, - FileGlobResult, FileGlobV2Result, GrepResult, ReadFilesResult, ReadMCPResourceResult, - RequestCommandOutputResult, RequestFileEditsResult, SearchCodebaseResult, SubagentCall, - TodoOperation, UploadArtifactResult, WriteToLongRunningShellCommandResult, + AIAgentActionResultType, AIAgentActionType, AIAgentInput, AIAgentOutput, + AIAgentOutputMessage, AIAgentOutputMessageType, AIAgentTodo, ArtifactCreatedData, + CallMCPToolResult, FileContext, FileGlobResult, FileGlobV2Result, GrepResult, + ReadFilesResult, ReadMCPResourceResult, RequestCommandOutputResult, RequestFileEditsResult, + SearchCodebaseResult, SubagentCall, TodoOperation, UploadArtifactResult, + WriteToLongRunningShellCommandResult, }; use crate::code::buffer_location::LocalOrRemotePath; diff --git a/app/src/ai/agent_sdk/driver/snapshot.rs b/app/src/ai/agent_sdk/driver/snapshot.rs index 66d54d0a..6462e4f0 100644 --- a/app/src/ai/agent_sdk/driver/snapshot.rs +++ b/app/src/ai/agent_sdk/driver/snapshot.rs @@ -34,12 +34,12 @@ use anyhow::{Context as _, Result}; use command::r#async::Command; use command::Stdio; use futures::future::join_all; -use tokio::fs::{self as tokio_fs, OpenOptions}; -use tokio::io::AsyncWriteExt as _; -use tokio::sync::{mpsc, oneshot}; use galaxy_core::report_error; use galaxyui::r#async::executor::Background; use galaxyui::r#async::FutureExt as _; +use tokio::fs::{self as tokio_fs, OpenOptions}; +use tokio::io::AsyncWriteExt as _; +use tokio::sync::{mpsc, oneshot}; use crate::ai::agent_sdk::retry::with_bounded_retry; use crate::ai::ambient_agents::AmbientAgentTaskId; @@ -825,7 +825,7 @@ pub(crate) async fn upload_snapshot_for_handoff( ); } let mut target_map: HashMap = HashMap::new(); - for (file, target) in file_infos.iter().zip(response.uploads.into_iter()) { + for (file, target) in file_infos.iter().zip(response.uploads) { target_map.insert(file.filename.clone(), target); } @@ -1006,7 +1006,7 @@ async fn upload_gathered_snapshot( chunk.len(), ); } - for (file, target) in chunk.iter().zip(targets.into_iter()) { + for (file, target) in chunk.iter().zip(targets) { target_map.insert(file.filename.clone(), target); } } diff --git a/app/src/ai/agent_sdk/driver/terminal.rs b/app/src/ai/agent_sdk/driver/terminal.rs index c852a88a..013d8a93 100644 --- a/app/src/ai/agent_sdk/driver/terminal.rs +++ b/app/src/ai/agent_sdk/driver/terminal.rs @@ -8,8 +8,6 @@ use std::task::{Context, Poll}; use std::time::Duration; use futures::channel::oneshot; -use session_sharing_protocol::common::{Role, SessionId}; -use session_sharing_protocol::sharer::SessionRetentionReason; use galaxy_cli::share::{ShareAccessLevel, ShareRequest, ShareSubject}; use galaxy_completer::completer::CommandOutput; use galaxy_core::command::ExitCode; @@ -18,6 +16,8 @@ use galaxy_terminal::model::grid::Dimensions; use galaxy_util::path::ShellFamily; use galaxyui::r#async::FutureExt; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity as _, ViewHandle}; +use session_sharing_protocol::common::{Role, SessionId}; +use session_sharing_protocol::sharer::SessionRetentionReason; use super::AgentDriverError; use crate::ai::ambient_agents::AmbientAgentTaskId; diff --git a/app/src/ai/agent_sdk/driver_tests.rs b/app/src/ai/agent_sdk/driver_tests.rs index 24b2278e..b863ae89 100644 --- a/app/src/ai/agent_sdk/driver_tests.rs +++ b/app/src/ai/agent_sdk/driver_tests.rs @@ -8,8 +8,6 @@ use std::time::Duration; use cloud_object_models::CodeForge; use futures::channel::oneshot; use futures::executor::block_on; -use repo_metadata::{DirectoryWatcher, RepoMetadataEvent, RepoMetadataModel, RepositoryIdentifier}; -use tempfile::TempDir; use galaxy_cli::agent::Harness; use galaxy_cli::mcp::MCPSpec; use galaxy_cli::skill::SkillSpec; @@ -25,6 +23,8 @@ use galaxy_graphql::response_context::ResponseContext; use galaxy_managed_secrets::ManagedSecretValue; use galaxy_util::standardized_path::StandardizedPath; use galaxyui::{App, SingletonEntity as _}; +use repo_metadata::{DirectoryWatcher, RepoMetadataEvent, RepoMetadataModel, RepositoryIdentifier}; +use tempfile::TempDir; use super::{ build_secret_env_vars, AgentDriver, AgentDriverError, IdleTimeoutSender, diff --git a/app/src/ai/agent_sdk/environment.rs b/app/src/ai/agent_sdk/environment.rs index 0392f974..044796ae 100644 --- a/app/src/ai/agent_sdk/environment.rs +++ b/app/src/ai/agent_sdk/environment.rs @@ -2,9 +2,6 @@ use std::collections::HashSet; use comfy_table::Cell; use cynic::QueryBuilder; -use inquire::error::InquireError; -use inquire::{Confirm, Select}; -use serde::Serialize; use galaxy_cli::agent::OutputFormat; use galaxy_cli::environment::{EnvironmentCommand, ImageCommand}; use galaxy_cli::scope::ObjectScope; @@ -16,6 +13,9 @@ use galaxy_graphql::queries::list_warp_dev_images::{ use galaxy_graphql::queries::user_repo_auth_status::UserRepoAuthStatusEnum; use galaxyui::r#async::FutureExt; use galaxyui::{AppContext, ModelContext, SingletonEntity}; +use inquire::error::InquireError; +use inquire::{Confirm, Select}; +use serde::Serialize; use crate::ai::agent_sdk::driver::WARP_DRIVE_SYNC_TIMEOUT; use crate::ai::agent_sdk::oauth_flow::poll_oauth_until_terminal; diff --git a/app/src/ai/agent_sdk/federate.rs b/app/src/ai/agent_sdk/federate.rs index b0f9c1c8..567bf258 100644 --- a/app/src/ai/agent_sdk/federate.rs +++ b/app/src/ai/agent_sdk/federate.rs @@ -1,18 +1,15 @@ use std::process; use anyhow::{anyhow, Result}; -use galaxy_cli::federate::{FederateCommand, IssueGcpTokenArgs, IssueTokenArgs}; -use galaxy_cli::{agent::OutputFormat, GlobalOptions}; -use galaxy_core::{features::FeatureFlag, report_error}; -use galaxy_managed_secrets::ManagedSecretManager; -use galaxyui::{platform::TerminationMode, AppContext, SingletonEntity as _}; -use serde_json::json; use galaxy_cli::agent::OutputFormat; +use galaxy_cli::federate::{FederateCommand, IssueGcpTokenArgs, IssueTokenArgs}; use galaxy_cli::GlobalOptions; use galaxy_core::features::FeatureFlag; use galaxy_core::report_error; +use galaxy_managed_secrets::ManagedSecretManager; use galaxyui::platform::TerminationMode; use galaxyui::{AppContext, SingletonEntity as _}; +use serde_json::json; use super::common::set_ambient_task_context_from_run_id; diff --git a/app/src/ai/agent_sdk/integration_output.rs b/app/src/ai/agent_sdk/integration_output.rs index 64ed2a6d..4c35cbd7 100644 --- a/app/src/ai/agent_sdk/integration_output.rs +++ b/app/src/ai/agent_sdk/integration_output.rs @@ -1,13 +1,13 @@ use chrono::{DateTime, Utc}; use comfy_table::presets::UTF8_FULL; use comfy_table::{Cell, Table}; -use serde::Serialize; -use serde_json::{Map, Value}; use galaxy_cli::agent::OutputFormat; use galaxy_graphql::queries::get_simple_integrations::{ ListedSimpleIntegrationConfig, SimpleIntegration, SimpleIntegrationConnectionStatus, SimpleIntegrationsOutput, }; +use serde::Serialize; +use serde_json::{Map, Value}; use crate::ai::agent_sdk::output::{self, TableFormat}; use crate::util::time_format::format_approx_duration_from_now_utc; diff --git a/app/src/ai/agent_sdk/mcp.rs b/app/src/ai/agent_sdk/mcp.rs index 4e8b966f..20e31bca 100644 --- a/app/src/ai/agent_sdk/mcp.rs +++ b/app/src/ai/agent_sdk/mcp.rs @@ -1,9 +1,8 @@ use comfy_table::Cell; -use galaxy_cli::{mcp::MCPCommand, GlobalOptions}; -use galaxyui::{AppContext, ModelContext, SingletonEntity}; -use serde::Serialize; use galaxy_cli::mcp::MCPCommand; use galaxy_cli::GlobalOptions; +use galaxyui::{AppContext, ModelContext, SingletonEntity}; +use serde::Serialize; use crate::ai::agent_sdk::output::{self, TableFormat}; use crate::ai::mcp::TemplatableMCPServerManager; diff --git a/app/src/ai/agent_sdk/mod.rs b/app/src/ai/agent_sdk/mod.rs index e5e2c75b..3eddf64d 100644 --- a/app/src/ai/agent_sdk/mod.rs +++ b/app/src/ai/agent_sdk/mod.rs @@ -12,6 +12,7 @@ use anyhow::Context; pub(crate) use driver::harness::{task_env_vars, validate_cli_installed, ClaudeHarness}; pub use driver::AgentDriver; use driver::AgentDriverError; +use galaxy_core::features::FeatureFlag; use telemetry::CliTelemetryEvent; use tracing::Instrument as _; use warp_cli::agent::{ @@ -32,7 +33,6 @@ use warp_cli::secret::SecretCommand; use warp_cli::share::ShareRequest; use warp_cli::task::{MessageCommand, TaskCommand}; use warp_cli::{CliCommand, GlobalOptions, OZ_HARNESS_ENV}; -use galaxy_core::features::FeatureFlag; use warp_graphql::object_permissions::OwnerType; use warp_isolation_platform::IsolationPlatformError; #[cfg(not(target_family = "wasm"))] diff --git a/app/src/ai/agent_sdk/mod_tests.rs b/app/src/ai/agent_sdk/mod_tests.rs index bfd077fd..46f76303 100644 --- a/app/src/ai/agent_sdk/mod_tests.rs +++ b/app/src/ai/agent_sdk/mod_tests.rs @@ -1,4 +1,3 @@ -use serde_json::json; use galaxy_cli::agent::Harness; use galaxy_cli::artifact::{ ArtifactCommand, DownloadArtifactArgs, GetArtifactArgs, UploadArtifactArgs, @@ -6,6 +5,7 @@ use galaxy_cli::artifact::{ use galaxy_cli::task::{MessageCommand, MessageSendArgs, MessageWatchArgs, TaskCommand}; use galaxy_cli::CliCommand; use galaxy_core::telemetry::TelemetryEvent; +use serde_json::json; use super::{command_requires_auth, command_to_telemetry_event, reconcile_task_harness}; diff --git a/app/src/ai/agent_sdk/output.rs b/app/src/ai/agent_sdk/output.rs index 3a21dc60..421413c9 100644 --- a/app/src/ai/agent_sdk/output.rs +++ b/app/src/ai/agent_sdk/output.rs @@ -4,12 +4,12 @@ use anyhow::Context; use comfy_table::modifiers::UTF8_ROUND_CORNERS; use comfy_table::presets::UTF8_FULL; use comfy_table::{Cell, ContentArrangement, Table}; -use jaq_all::data::Runner; -use jaq_all::fmts::write::Writer; -use jaq_all::fmts::Format; // Use jaq_json directly to ensure serde support is included. use galaxy_cli::agent::OutputFormat; use galaxy_cli::json_filter::{JqFilter, JsonOutput}; +use jaq_all::data::Runner; +use jaq_all::fmts::write::Writer; +use jaq_all::fmts::Format; use jaq_json::{write as jaq_write, Val}; use serde::Serialize; use tabwriter::TabWriter; diff --git a/app/src/ai/agent_sdk/profiles.rs b/app/src/ai/agent_sdk/profiles.rs index d696bf81..edd49597 100644 --- a/app/src/ai/agent_sdk/profiles.rs +++ b/app/src/ai/agent_sdk/profiles.rs @@ -1,9 +1,8 @@ use comfy_table::Cell; -use galaxy_cli::{agent::AgentProfileCommand, GlobalOptions}; -use galaxyui::{AppContext, ModelContext, SingletonEntity}; -use serde::Serialize; use galaxy_cli::agent::AgentProfileCommand; use galaxy_cli::GlobalOptions; +use galaxyui::{AppContext, ModelContext, SingletonEntity}; +use serde::Serialize; use crate::ai::agent_sdk::output::{self, TableFormat}; use crate::ai::execution_profiles::profiles::AIExecutionProfilesModel; diff --git a/app/src/ai/agent_sdk/provider.rs b/app/src/ai/agent_sdk/provider.rs index 33ac781c..4d192bbc 100644 --- a/app/src/ai/agent_sdk/provider.rs +++ b/app/src/ai/agent_sdk/provider.rs @@ -1,11 +1,11 @@ //! Provider command for linking third-party services. use comfy_table::Cell; -use serde::Serialize; use galaxy_cli::provider::{ProviderCommand, ProviderType}; use galaxy_cli::GlobalOptions; use galaxy_core::channel::ChannelState; use galaxyui::platform::TerminationMode; use galaxyui::{AppContext, ModelContext, SingletonEntity}; +use serde::Serialize; use crate::ai::agent_sdk::output::{self, TableFormat}; use crate::workspaces::user_workspaces::UserWorkspaces; diff --git a/app/src/ai/agent_sdk/schedule.rs b/app/src/ai/agent_sdk/schedule.rs index 51a26e90..7b660cbb 100644 --- a/app/src/ai/agent_sdk/schedule.rs +++ b/app/src/ai/agent_sdk/schedule.rs @@ -1,7 +1,6 @@ use chrono::{DateTime, Utc}; use comfy_table::Cell; use futures::future; -use serde::Serialize; use galaxy_cli::agent::OutputFormat; use galaxy_cli::schedule::{ CreateScheduleArgs, DeleteScheduleArgs, GetScheduleArgs, PauseScheduleArgs, ScheduleCommand, @@ -11,6 +10,7 @@ use galaxy_cli::GlobalOptions; use galaxy_graphql::queries::get_scheduled_agent_history::ScheduledAgentHistory; use galaxyui::platform::TerminationMode; use galaxyui::{AppContext, SingletonEntity}; +use serde::Serialize; use super::common::{EnvironmentChoice, ResolveConfigurationError}; use super::output::{self, TableFormat}; diff --git a/app/src/ai/agent_sdk/secret.rs b/app/src/ai/agent_sdk/secret.rs index e70ce46f..bfd01242 100644 --- a/app/src/ai/agent_sdk/secret.rs +++ b/app/src/ai/agent_sdk/secret.rs @@ -4,8 +4,6 @@ use std::io::{self, IsTerminal as _, Read}; use anyhow::{Context, Result}; use chrono::{DateTime, Utc}; use comfy_table::Cell; -use inquire::{Confirm, InquireError, Password}; -use serde::Serialize; use galaxy_cli::agent::OutputFormat; use galaxy_cli::scope::ObjectScope; use galaxy_cli::secret::{ @@ -20,6 +18,8 @@ use galaxy_managed_secrets::client::SecretOwner; use galaxy_managed_secrets::{ManagedSecretManager, ManagedSecretValue}; use galaxyui::platform::TerminationMode; use galaxyui::{AppContext, SingletonEntity as _}; +use inquire::{Confirm, InquireError, Password}; +use serde::Serialize; use super::output::{self, TableFormat}; use crate::auth::UserUid; diff --git a/app/src/ai/agent_sdk/telemetry.rs b/app/src/ai/agent_sdk/telemetry.rs index fb22ea36..ce9ec691 100644 --- a/app/src/ai/agent_sdk/telemetry.rs +++ b/app/src/ai/agent_sdk/telemetry.rs @@ -1,3 +1,4 @@ +use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; use serde_json::{json, Value}; use strum_macros::{EnumDiscriminants, EnumIter}; diff --git a/app/src/ai/agent_tips.rs b/app/src/ai/agent_tips.rs index 72c5bca7..74093fa5 100644 --- a/app/src/ai/agent_tips.rs +++ b/app/src/ai/agent_tips.rs @@ -4,6 +4,7 @@ use std::time::Duration; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; use markdown_parser::FormattedTextFragment; +use rand::seq::SliceRandom; use warpui::keymap::Keystroke; use warpui::r#async::{SpawnedFutureHandle, Timer}; use warpui::{AppContext, Entity, ModelContext, SingletonEntity}; @@ -624,7 +625,6 @@ impl AITipModel { return; } - // Select a random tip let mut rng = rand::thread_rng(); self.current_tip = self.tips.choose(&mut rng).cloned(); diff --git a/app/src/ai/ai_document_view.rs b/app/src/ai/ai_document_view.rs index 3cbb46d9..64dd5f3d 100644 --- a/app/src/ai/ai_document_view.rs +++ b/app/src/ai/ai_document_view.rs @@ -2,7 +2,6 @@ use std::path::PathBuf; use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::icons; use galaxy_core::ui::icons::ICON_DIMENSIONS; use galaxy_core::ui::theme::Fill as ThemeFill; @@ -20,6 +19,7 @@ use galaxyui::{ id, AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::ai::agent::conversation::AIConversationId; use crate::ai::blocklist::agent_view::AgentViewEntryOrigin; diff --git a/app/src/ai/ambient_agents/scheduled.rs b/app/src/ai/ambient_agents/scheduled.rs index 894cede9..aea39077 100644 --- a/app/src/ai/ambient_agents/scheduled.rs +++ b/app/src/ai/ambient_agents/scheduled.rs @@ -6,9 +6,9 @@ pub use cloud_object_models::{ }; use futures::channel::oneshot; use futures::FutureExt; -use serde_json::{Map, Value}; use galaxy_graphql::queries::get_scheduled_agent_history::ScheduledAgentHistory; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity}; +use serde_json::{Map, Value}; use crate::cloud_object::model::generic_string_model::StringModel; use crate::cloud_object::model::json_model::JsonModel; diff --git a/app/src/ai/ambient_agents/spawn_tests.rs b/app/src/ai/ambient_agents/spawn_tests.rs index f25a4f24..a80b1443 100644 --- a/app/src/ai/ambient_agents/spawn_tests.rs +++ b/app/src/ai/ambient_agents/spawn_tests.rs @@ -2,6 +2,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use chrono::Utc; +use futures::StreamExt; use session_sharing_protocol::common::SessionId; use super::{ @@ -10,7 +11,9 @@ use super::{ }; use crate::ai::agent::UserQueryMode; use crate::ai::ambient_agents::{AmbientAgentTask, AmbientAgentTaskState}; +use crate::server::retry_strategies::MAX_ATTEMPTS; use crate::server::server_api::ai::{MockAIClient, SpawnAgentResponse, TaskStatusMessage}; +use crate::server::server_api::presigned_upload::HttpStatusError; use crate::terminal::shared_session; fn task_with( @@ -127,7 +130,6 @@ async fn followup_submits_before_polling_and_ignores_previous_session_id() { #[tokio::test] async fn followup_api_error_does_not_poll() { - let mut mock = MockAIClient::new(); mock.expect_submit_run_followup() .times(1) @@ -154,7 +156,6 @@ async fn followup_api_error_does_not_poll() { #[tokio::test] async fn followup_terminal_failure_surfaces_status_message() { - // Post-fix, a follow-up only surfaces a terminal-state failure after observing at least // one working state, so the new run's `Error` is interpreted as the follow-up's outcome // rather than residue of the prior run. The mock yields `InProgress` (no joinable @@ -227,7 +228,6 @@ async fn followup_terminal_failure_surfaces_status_message() { #[tokio::test] async fn followup_without_previous_session_id_accepts_joinable_session() { - let session_id = SessionId::new(); let expected_session_id = session_id; let mut mock = MockAIClient::new(); @@ -285,7 +285,6 @@ async fn followup_without_previous_session_id_accepts_joinable_session() { #[tokio::test] async fn followup_without_previous_session_id_errors_if_run_finishes_before_session() { - // Same shape as `followup_terminal_failure_surfaces_status_message`: the follow-up // must first observe a working state before a terminal `Succeeded` is interpreted as // the follow-up's outcome. @@ -356,7 +355,6 @@ async fn followup_without_previous_session_id_errors_if_run_finishes_before_sess #[tokio::test] async fn followup_skips_prior_terminal_state_until_working_then_attaches() { - // Reproduces the race fix's happy path: the server hasn't yet transitioned the task off // its prior `Blocked` state on the first poll, but does so before the next. The poll // loop must silently skip the prior-terminal observation, then surface the new run's @@ -445,7 +443,6 @@ async fn followup_skips_prior_terminal_state_until_working_then_attaches() { #[tokio::test] async fn followup_skips_prior_terminal_then_surfaces_real_failure() { - // Variant of the happy-path test where the new run legitimately fails after a working // state. The prior-terminal `Blocked` observation must still be suppressed, and the // new run's `Error` + `status_message` must surface as the follow-up's outcome. @@ -533,7 +530,6 @@ async fn followup_skips_prior_terminal_then_surfaces_real_failure() { #[tokio::test] async fn followup_cancelled_state_breaks_skip_loop() { - // `Cancelled` is a carve-out: even before a working state has been observed it falls // through to terminal handling so a user-initiated cancellation can never leak an // infinite poll loop. @@ -581,7 +577,6 @@ async fn followup_cancelled_state_breaks_skip_loop() { #[tokio::test] async fn followup_bounded_skip_for_server_stall() { - // If the server is wedged on the prior terminal state, the bounded-skip counter must // eventually give up so the stream doesn't poll forever. let call_count = Arc::new(AtomicUsize::new(0)); @@ -642,7 +637,6 @@ fn run_id() -> crate::ai::ambient_agents::AmbientAgentTaskId { } fn transient_http_error() -> anyhow::Error { - use crate::server::server_api::presigned_upload::HttpStatusError; anyhow::Error::new(HttpStatusError { status: 429, body: "Too Many Requests".to_string(), @@ -660,9 +654,6 @@ fn permanent_http_error() -> anyhow::Error { #[tokio::test] async fn poll_retries_transient_429_errors() { - - use crate::server::retry_strategies::MAX_ATTEMPTS; - let mut mock = MockAIClient::new(); let call_count = Arc::new(AtomicUsize::new(0)); @@ -739,7 +730,6 @@ async fn poll_retries_transient_429_errors() { #[tokio::test] async fn poll_fails_on_permanent_http_error() { - let mut mock = MockAIClient::new(); mock.expect_spawn_agent().returning(|_| { @@ -801,8 +791,6 @@ async fn poll_fails_on_permanent_http_error() { #[tokio::test] async fn poll_gives_up_after_max_transient_retries() { - - let mut mock = MockAIClient::new(); let call_count = Arc::new(AtomicUsize::new(0)); @@ -871,7 +859,6 @@ async fn poll_gives_up_after_max_transient_retries() { #[tokio::test] async fn poll_stops_on_terminal_failure_like_state() { - let mut mock = MockAIClient::new(); mock.expect_spawn_agent().returning(|_| { @@ -1001,7 +988,6 @@ fn session_join_info_ignores_empty_link_and_invalid_session_id() { #[tokio::test] async fn poll_for_session_join_info_waits_until_link_is_available() { - let mut mock = MockAIClient::new(); let call_count = Arc::new(AtomicUsize::new(0)); diff --git a/app/src/ai/ambient_agents/task.rs b/app/src/ai/ambient_agents/task.rs index ffdc92c4..cef013e9 100644 --- a/app/src/ai/ambient_agents/task.rs +++ b/app/src/ai/ambient_agents/task.rs @@ -5,14 +5,14 @@ use chrono::{DateTime, Duration as ChronoDuration, Utc}; #[cfg(not(target_family = "wasm"))] pub use cloud_object_models::HarnessModelConfig; pub use cloud_object_models::{AgentConfigSnapshot, HarnessAuthSecretsConfig, HarnessConfig}; +use galaxy_core::report_error; +use galaxy_core::ui::theme::{GalaxyTheme, WarpTheme}; +use galaxyui::color::ColorU; +use galaxyui::{SingletonEntity, View, ViewContext}; use iso8601_duration::Duration as Iso8601Duration; use serde::{Deserialize, Serialize}; use session_sharing_protocol::common::SessionId; use url::Url; -use galaxy_core::report_error; -use galaxy_core::ui::theme::WarpTheme; -use galaxyui::color::ColorU; -use galaxyui::{SingletonEntity, View, ViewContext}; use super::AmbientAgentTaskId; use crate::ai::artifacts::{deserialize_artifacts, Artifact}; diff --git a/app/src/ai/ambient_agents/telemetry.rs b/app/src/ai/ambient_agents/telemetry.rs index 9e63dde1..44db97f6 100644 --- a/app/src/ai/ambient_agents/telemetry.rs +++ b/app/src/ai/ambient_agents/telemetry.rs @@ -1,3 +1,5 @@ +use galaxy_core::features::FeatureFlag; +use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; use serde::Serialize; use serde_json::{json, Value}; use strum_macros::{EnumDiscriminants, EnumIter}; diff --git a/app/src/ai/aws_credentials.rs b/app/src/ai/aws_credentials.rs index 9304a1ce..1829721d 100644 --- a/app/src/ai/aws_credentials.rs +++ b/app/src/ai/aws_credentials.rs @@ -7,11 +7,11 @@ use aws_credential_types::provider::error::CredentialsError; use aws_credential_types::provider::ProvideCredentials; use futures::channel::oneshot::channel; use futures::future::BoxFuture; -use tokio::sync::Mutex; -use vec1::vec1; use galaxy_managed_secrets::client::IdentityTokenOptions; use galaxy_managed_secrets::ManagedSecretManager; use galaxyui::{ModelContext, ModelHandle, SingletonEntity}; +use tokio::sync::Mutex; +use vec1::vec1; use crate::settings::{AISettings, AISettingsChangedEvent}; use crate::terminal::event::{AfterBlockCompletedEvent, BlockType, UserBlockCompleted}; @@ -137,7 +137,7 @@ pub async fn load_aws_credentials_from_sdk( let region_provider = aws_config::meta::region::RegionProviderChain::default_provider(); let loader = aws_config::defaults(aws_config::BehaviorVersion::latest()).region(region_provider); - let loader = if profile.trim().is_empty() { + let loader = if profile.trim().is_empty() || profile.trim() == "default" { loader // Let AWS SDK use its default behavior } else { loader.profile_name(profile) diff --git a/app/src/ai/bedrock/client.rs b/app/src/ai/bedrock/client.rs index b1a98a33..90173754 100644 --- a/app/src/ai/bedrock/client.rs +++ b/app/src/ai/bedrock/client.rs @@ -2,17 +2,17 @@ use std::sync::{Arc, Mutex}; use anyhow::Result; use aws_config::BehaviorVersion; +use aws_credential_types::provider::ProvideCredentials; use aws_sdk_bedrockruntime::config::Region; use aws_sdk_bedrockruntime::Client as BedrockRuntimeClient; -use crate::settings::ai::BedrockAuthMethod; - use super::convert::{build_converse_request, CachingConfig, ConversationMessage, ToolDefinition}; use super::diagnostic::BedrockDiagnosticLogger; use super::external_config::ExternalBedrockConfig; use super::models::apply_cross_region_prefix; use super::response_translator::bedrock_stream_to_response_events; use crate::ai::agent::api::ResponseStream; +use crate::settings::ai::BedrockAuthMethod; fn strip_context_marker(model_id: &str) -> String { if let Some(base) = model_id.strip_suffix("[1m]") { @@ -36,6 +36,7 @@ pub struct BedrockClientConfig { pub region: String, pub access_key_id: String, pub secret_access_key: String, + pub session_token: Option, pub cross_region_inference: bool, } @@ -86,10 +87,23 @@ pub enum BedrockError { impl BedrockClient { pub async fn from_config(config: BedrockClientConfig) -> Result { + log::info!( + "[bedrock] from_config input: auth_method={:?}, profile={:?}, region={:?}, access_key_id_set={}, secret_access_key_set={}, session_token_set={}", + config.auth_method, + config.profile, + config.region, + !config.access_key_id.is_empty(), + !config.secret_access_key.is_empty(), + config.session_token.is_some(), + ); + let aws_config = match config.auth_method { BedrockAuthMethod::Profile | BedrockAuthMethod::Sso => { - let mut loader = - aws_config::defaults(BehaviorVersion::latest()).profile_name(&config.profile); + let mut loader = aws_config::defaults(BehaviorVersion::latest()); + + if !config.profile.is_empty() && config.profile != "default" { + loader = loader.profile_name(&config.profile); + } if !config.region.is_empty() { loader = loader.region(Region::new(config.region.clone())); @@ -105,7 +119,7 @@ impl BedrockClient { let creds = aws_credential_types::Credentials::new( &config.access_key_id, &config.secret_access_key, - None, + config.session_token, None, "warp-bedrock-static", ); @@ -123,6 +137,24 @@ impl BedrockClient { } }; + if let Some(provider) = aws_config.credentials_provider() { + match provider.provide_credentials().await { + Ok(creds) => { + log::info!( + "[bedrock] Resolved AWS credentials successfully: access_key_id={:?}, has_session_token={}, expiry={:?}", + creds.access_key_id(), + creds.session_token().is_some(), + creds.expiry(), + ); + } + Err(e) => { + log::warn!("[bedrock] Failed to resolve AWS credentials from provider: {e:?}"); + } + } + } else { + log::warn!("[bedrock] No credentials provider found in resolved AWS config"); + } + let region = aws_config .region() .map(|r| r.to_string()) @@ -136,6 +168,7 @@ impl BedrockClient { }) } + #[allow(clippy::too_many_arguments)] pub async fn converse_stream( &self, model_id: &str, @@ -174,6 +207,13 @@ impl BedrockClient { tools.len() ); + log::info!( + "[bedrock] Sending request payload to Bedrock:\nSystem Prompt: {:?}\nMessages: {:#?}\nTools: {:#?}", + system_prompt, + messages, + tools + ); + let converted = build_converse_request( messages.clone(), system_prompt.clone(), @@ -302,12 +342,10 @@ impl BedrockClient { })?; let mut response_text = String::new(); - if let Some(output_msg) = output.output() { - if let aws_sdk_bedrockruntime::types::ConverseOutput::Message(msg) = output_msg { - for block in msg.content() { - if let aws_sdk_bedrockruntime::types::ContentBlock::Text(text) = block { - response_text.push_str(text); - } + if let Some(aws_sdk_bedrockruntime::types::ConverseOutput::Message(msg)) = output.output() { + for block in msg.content() { + if let aws_sdk_bedrockruntime::types::ContentBlock::Text(text) = block { + response_text.push_str(text); } } } diff --git a/app/src/ai/bedrock/convert.rs b/app/src/ai/bedrock/convert.rs index d8fe84e5..afcb300a 100644 --- a/app/src/ai/bedrock/convert.rs +++ b/app/src/ai/bedrock/convert.rs @@ -10,7 +10,6 @@ use aws_smithy_types::Document; use serde_json::Value as JsonValue; use super::external_config::ExternalBedrockConfig; - // Re-export shared provider types so existing imports from bedrock::convert continue to work. pub use crate::ai::provider::types::{ ContentPart, ConversationMessage, MessageContent, MessageRole, ToolDefinition, @@ -47,6 +46,7 @@ pub struct ConvertedRequest { pub tool_config: Option, } +#[allow(clippy::too_many_arguments)] pub fn build_converse_request( messages: Vec, system_prompt: Option, diff --git a/app/src/ai/bedrock/convert_tests.rs b/app/src/ai/bedrock/convert_tests.rs index 48b94346..b33337eb 100644 --- a/app/src/ai/bedrock/convert_tests.rs +++ b/app/src/ai/bedrock/convert_tests.rs @@ -1,4 +1,4 @@ -use aws_sdk_bedrockruntime::types::{ContentBlock, ConversationRole}; +use aws_sdk_bedrockruntime::types::{ContentBlock, ConversationRole, SystemContentBlock, Tool}; use serde_json::json; use super::convert::*; diff --git a/app/src/ai/bedrock/diagnostic.rs b/app/src/ai/bedrock/diagnostic.rs index 7c714b80..73f24c5e 100644 --- a/app/src/ai/bedrock/diagnostic.rs +++ b/app/src/ai/bedrock/diagnostic.rs @@ -1,10 +1,13 @@ -use chrono::{Local, Utc}; -use serde_json::Value as JsonValue; +#![allow(dead_code)] + use std::fs::{self, File, OpenOptions}; use std::io::{BufWriter, Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; use std::sync::Mutex; +use chrono::{Local, Utc}; +use serde_json::Value as JsonValue; + use super::convert::{ConversationMessage, MessageContent, MessageRole, ToolDefinition}; const ENV_VAR: &str = "GALAXY_BEDROCK_DIAGNOSTICS"; diff --git a/app/src/ai/bedrock/e2e_tests.rs b/app/src/ai/bedrock/e2e_tests.rs index 046d0af4..0a832c9c 100644 --- a/app/src/ai/bedrock/e2e_tests.rs +++ b/app/src/ai/bedrock/e2e_tests.rs @@ -1,13 +1,13 @@ +use std::path::PathBuf; use std::sync::{Arc, Mutex}; use futures::StreamExt; use serde_json::json; -use std::path::PathBuf; +use warp_multi_agent_api as api; use super::client::{BedrockClient, BedrockClientConfig}; use super::convert::{ConversationMessage, MessageContent, MessageRole, ToolDefinition}; use crate::settings::ai::BedrockAuthMethod; -use warp_multi_agent_api as api; fn make_user_query_message(id: &str, task_id: &str, query: &str) -> api::Message { api::Message { @@ -24,6 +24,7 @@ fn make_user_query_message(id: &str, task_id: &str, query: &str) -> api::Message mode: None, intended_agent: 0, })), + ..Default::default() } } @@ -54,6 +55,7 @@ fn make_tool_call_run_shell( }, )), })), + ..Default::default() } } @@ -81,6 +83,7 @@ fn make_tool_call_read_files( }, )), })), + ..Default::default() } } @@ -113,12 +116,14 @@ fn make_tool_result_shell( output: output.into(), exit_code, command_id: String::new(), + ..Default::default() }, )), }, )), }, )), + ..Default::default() } } @@ -155,6 +160,7 @@ fn make_tool_result_read_files( )), }, )), + ..Default::default() } } @@ -217,6 +223,7 @@ fn make_settings(model: &str) -> api::request::Settings { supports_bundled_skills: false, supports_research_agent: false, supports_orchestration_v2: false, + ..Default::default() } } @@ -260,6 +267,7 @@ fn get_test_config() -> Option { region, access_key_id: String::new(), secret_access_key: String::new(), + session_token: None, cross_region_inference: false, }) } @@ -691,7 +699,7 @@ impl AgentSimulation { match name { "run_shell_command" => { let command = input["command"].as_str().unwrap_or("echo 'no command'"); - let output = std::process::Command::new("sh") + let output = command::blocking::Command::new("sh") .arg("-c") .arg(command) .current_dir(&self.project_path) @@ -759,7 +767,7 @@ impl AgentSimulation { .unwrap_or(self.project_path.to_str().unwrap_or(".")); let mut result = String::new(); for query in queries { - let output = std::process::Command::new("grep") + let output = command::blocking::Command::new("grep") .args(["-rn", query, path]) .output(); if let Ok(out) = output { @@ -999,7 +1007,7 @@ async fn test_agent_multi_turn_tool_use_produces_output() { let tool_use_id = format!("tool_{}", total_turns); let (result, is_error) = match tool.name.as_str() { "run_shell_command" => { - let ls_output = std::process::Command::new("ls") + let ls_output = command::blocking::Command::new("ls") .arg("-la") .current_dir(&project_path) .output() @@ -1075,7 +1083,7 @@ async fn test_agent_multi_turn_tool_use_produces_output() { // 2. No partial reasoning fragments leak to the UI // 3. The stream protocol is correct (Init, CreateTask, content, Finished) assert!( - sim.all_text_output.len() > 0 || total_turns > 1, + !sim.all_text_output.is_empty() || total_turns > 1, "Agent should either produce text or make multiple tool calls to explore" ); @@ -1160,39 +1168,34 @@ async fn test_reasoning_model_produces_substantial_output() { while let Some(event_result) = stream.next().await { event_count += 1; let event = event_result.expect("event should be Ok"); - if let Some(event_type) = &event.r#type { - match event_type { - api::response_event::Type::ClientActions(actions) => { - for action in &actions.actions { - if let Some(action_type) = &action.action { - match action_type { - api::client_action::Action::CreateTask(_) => { - had_create_task = true; + if let Some(api::response_event::Type::ClientActions(actions)) = &event.r#type { + for action in &actions.actions { + if let Some(action_type) = &action.action { + match action_type { + api::client_action::Action::CreateTask(_) => { + had_create_task = true; + } + api::client_action::Action::AddMessagesToTask(add) => { + for msg in &add.messages { + if let Some(api::message::Message::AgentOutput(output)) = + &msg.message + { + total_text.push_str(&output.text); } - api::client_action::Action::AddMessagesToTask(add) => { - for msg in &add.messages { - if let Some(api::message::Message::AgentOutput(output)) = - &msg.message - { - total_text.push_str(&output.text); - } - } - } - api::client_action::Action::AppendToMessageContent(append) => { - if let Some(msg) = &append.message { - if let Some(api::message::Message::AgentOutput(output)) = - &msg.message - { - total_text.push_str(&output.text); - } - } - } - _ => {} } } + api::client_action::Action::AppendToMessageContent(append) => { + if let Some(msg) = &append.message { + if let Some(api::message::Message::AgentOutput(output)) = + &msg.message + { + total_text.push_str(&output.text); + } + } + } + _ => {} } } - _ => {} } } } @@ -1610,7 +1613,7 @@ async fn test_slash_create_new_project() { if !events.is_empty() { assert!( - text.len() > 0 + !text.is_empty() || events .iter() .any(|e| matches!(e.event_type, StreamEventType::ToolCallMessage { .. })), @@ -1645,7 +1648,7 @@ async fn test_slash_auto_code_diff() { assert_valid_stream(&events, "slash_auto_code_diff"); if !events.is_empty() { - let has_action = text.len() > 0 + let has_action = !text.is_empty() || events .iter() .any(|e| matches!(e.event_type, StreamEventType::ToolCallMessage { .. })); @@ -1775,7 +1778,7 @@ async fn test_slash_query_with_canned_response() { assert_valid_stream(&events, "slash_query_with_canned_response"); if !events.is_empty() { - let has_output = text.len() > 0 + let has_output = !text.is_empty() || events .iter() .any(|e| matches!(e.event_type, StreamEventType::ToolCallMessage { .. })); diff --git a/app/src/ai/bedrock/external_config.rs b/app/src/ai/bedrock/external_config.rs index 3101b2be..3cff89b6 100644 --- a/app/src/ai/bedrock/external_config.rs +++ b/app/src/ai/bedrock/external_config.rs @@ -144,7 +144,6 @@ fn parse_claude_code_model_map( model_id: arn, display_name, vision_supported: true, - context_size: 200_000, } }) .collect() diff --git a/app/src/ai/bedrock/integration_tests.rs b/app/src/ai/bedrock/integration_tests.rs index 3d77fd4a..155b3424 100644 --- a/app/src/ai/bedrock/integration_tests.rs +++ b/app/src/ai/bedrock/integration_tests.rs @@ -22,6 +22,7 @@ fn get_test_config() -> Option { region, access_key_id: String::new(), secret_access_key: String::new(), + session_token: None, cross_region_inference: false, }) } @@ -81,6 +82,7 @@ async fn collect_stream_output( while let Some(event) = stream.next().await { let event = event.expect("stream event should be Ok"); if let Some(event_type) = event.r#type { + use warp_multi_agent_api::message::Message; use warp_multi_agent_api::response_event::Type; match event_type { Type::ClientActions(actions) => { @@ -90,24 +92,16 @@ async fn collect_stream_output( match action_type { Action::AddMessagesToTask(add) => { for msg in add.messages { - if let Some(msg_content) = msg.message { - use warp_multi_agent_api::message::Message; - match msg_content { - Message::AgentOutput(output) => { - text.push_str(&output.text); - } - _ => {} - } + if let Some(Message::AgentOutput(output)) = msg.message { + text.push_str(&output.text); } } } Action::AppendToMessageContent(append) => { - if let Some(msg) = append.message { - if let Some(msg_content) = msg.message { - if let Message::AgentOutput(output) = msg_content { - text.push_str(&output.text); - } - } + if let Some(Message::AgentOutput(output)) = + append.message.and_then(|m| m.message) + { + text.push_str(&output.text); } } _ => {} @@ -553,9 +547,10 @@ async fn test_arn_based_model() { return; }; - let arn = std::env::var("BEDROCK_TEST_ARN").unwrap_or_else(|_| { - "arn:aws:bedrock:us-east-1:156729649053:application-inference-profile/1tim45pgo320".into() - }); + let Some(arn) = std::env::var("BEDROCK_TEST_ARN").ok() else { + eprintln!("Skipping: BEDROCK_TEST_ARN not set"); + return; + }; let client = BedrockClient::from_config(config) .await @@ -696,3 +691,100 @@ async fn test_all_tools_visible_to_model() { tools.len() ); } + +#[tokio::test] +async fn test_bedrock_integration_live_stream() { + let Some(config) = get_test_config() else { + eprintln!("Skipping: BEDROCK_INTEGRATION_TEST not set"); + return; + }; + + println!("[live-test] Initializing Bedrock client..."); + let client = BedrockClient::from_config(config) + .await + .expect("client creation"); + let model = get_test_model(); + println!("[live-test] Using model: {model}"); + + let messages = vec![ConversationMessage { + role: MessageRole::User, + content: MessageContent::Text( + "Write a 2-line poem about antigravity. Output only the poem.".into(), + ), + }]; + + println!("[live-test] Requesting stream response from Bedrock..."); + let stream = client + .converse_stream( + &model, + "live-test-task-id", + true, + messages, + None, + None, + vec![], + 1024, + None, + false, + None, + None, + Arc::new(Mutex::new(Vec::new())), + Vec::new(), + ) + .await + .expect("converse_stream should succeed"); + + let mut full_text = String::new(); + let mut stream = stream; + + while let Some(event) = stream.next().await { + let event = event.expect("stream event should be Ok"); + if let Some(event_type) = event.r#type { + use warp_multi_agent_api::message::Message; + use warp_multi_agent_api::response_event::Type; + match event_type { + Type::ClientActions(actions) => { + for action in actions.actions { + if let Some(action_type) = action.action { + use warp_multi_agent_api::client_action::Action; + match action_type { + Action::AddMessagesToTask(add) => { + for msg in add.messages { + if let Some(Message::AgentOutput(output)) = msg.message { + print!("{}", output.text); + full_text.push_str(&output.text); + } + } + } + Action::AppendToMessageContent(append) => { + if let Some(Message::AgentOutput(output)) = + append.message.and_then(|m| m.message) + { + print!("{}", output.text); + full_text.push_str(&output.text); + } + } + _ => {} + } + } + } + } + Type::Finished(finished) => { + println!( + "\n[live-test] Stream finished. Reason: {:?}", + finished.reason + ); + if let Some(meta) = finished.conversation_usage_metadata { + if let Some(usage) = meta.byok_token_usage.get("bedrock") { + println!("[live-test] Token Usage - Total: {}", usage.total_tokens); + } + } + } + _ => {} + } + } + } + + println!("[live-test] Received full response:\n{}", full_text.trim()); + assert!(!full_text.is_empty(), "Model returned an empty response"); +} diff --git a/app/src/ai/bedrock/models.rs b/app/src/ai/bedrock/models.rs index 3ec272dc..e4bf7dfe 100644 --- a/app/src/ai/bedrock/models.rs +++ b/app/src/ai/bedrock/models.rs @@ -1,6 +1,7 @@ -use crate::settings::ai::BedrockModelConfig; +#![allow(dead_code)] use super::external_config::ExternalBedrockConfig; +use crate::settings::ai::BedrockModelConfig; pub struct DefaultModel { pub model_id: &'static str, @@ -128,7 +129,6 @@ pub fn get_effective_models(user_models: &[BedrockModelConfig]) -> Vec Vec Vec { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::ToolCallResult( api::message::ToolCallResult { tool_call_id: result.tool_call_id.clone(), @@ -382,6 +387,7 @@ fn extract_input_messages(request: &api::Request) -> Vec { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::UserQuery( api::message::UserQuery { query: query.query.clone(), @@ -422,6 +428,7 @@ fn extract_input_messages(request: &api::Request) -> Vec { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::UserQuery( api::message::UserQuery { query: query_text, @@ -445,6 +452,7 @@ fn extract_input_messages(request: &api::Request) -> Vec { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::UserQuery(api::message::UserQuery { query: query.query.clone(), ..Default::default() @@ -462,6 +470,7 @@ fn extract_input_messages(request: &api::Request) -> Vec { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::ToolCallResult( api::message::ToolCallResult { tool_call_id: result.tool_call_id.clone(), @@ -492,6 +501,7 @@ fn extract_input_messages(request: &api::Request) -> Vec { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::UserQuery(api::message::UserQuery { query: prompt, ..Default::default() @@ -728,7 +738,6 @@ fn ensure_starts_with_user_message(messages: &mut Vec) { /// 4. Removes trailing assistant tool_use messages that have no following user message. /// 5. Ensures strict user/assistant role alternation. fn ensure_tool_results_paired(messages: &mut Vec) { - // Collect all tool_result IDs that exist anywhere in the conversation. let mut all_result_ids = HashSet::new(); for msg in messages.iter() { @@ -1035,7 +1044,7 @@ pub fn extract_tools(request: &api::Request) -> Vec { let input_schema = tool .input_schema .as_ref() - .map(|s| prost_struct_to_json(s)) + .map(prost_struct_to_json) .unwrap_or_else(|| serde_json::json!({"type": "object", "properties": {}})); tools.push(ToolDefinition { name, @@ -1057,7 +1066,7 @@ pub fn extract_tools(request: &api::Request) -> Vec { let input_schema = tool .input_schema .as_ref() - .map(|s| prost_struct_to_json(s)) + .map(prost_struct_to_json) .unwrap_or_else(|| serde_json::json!({"type": "object", "properties": {}})); tools.push(ToolDefinition { name, diff --git a/app/src/ai/bedrock/response_translator.rs b/app/src/ai/bedrock/response_translator.rs index dffe9a7e..46f8103e 100644 --- a/app/src/ai/bedrock/response_translator.rs +++ b/app/src/ai/bedrock/response_translator.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use std::sync::{Arc, Mutex}; use aws_sdk_bedrockruntime::operation::converse_stream::ConverseStreamOutput; @@ -10,11 +12,10 @@ use uuid::Uuid; use warp_multi_agent_api::response_event::stream_finished; use warp_multi_agent_api::{self as api, ClientAction, ResponseEvent}; -use crate::ai::agent::api::Event; -use crate::server::server_api::AIApiError; - use super::convert::{ContentPart, ConversationMessage, MessageContent, MessageRole}; use super::diagnostic::BedrockDiagnosticLogger; +use crate::ai::agent::api::Event; +use crate::server::server_api::AIApiError; fn json_to_prost_struct(value: &serde_json::Value) -> prost_types::Struct { let fields = match value.as_object() { @@ -57,6 +58,7 @@ pub fn context_window_for_model(model_id: &str) -> u32 { } } +#[allow(clippy::too_many_arguments)] pub fn bedrock_stream_to_response_events( mut output: ConverseStreamOutput, task_id: String, @@ -129,41 +131,36 @@ pub fn bedrock_stream_to_response_events( } StreamEvent::ContentBlockStart(block_start) => { log::debug!("[bedrock] Event #{event_count}: ContentBlockStart"); - if let Some(start) = block_start.start() { - match start { - ContentBlockStart::ToolUse(tool_start) => { - _has_tool_calls = true; - if !buffered_text.is_empty() { - let msg_id = current_text_message_id - .clone() - .unwrap_or_else(|| Uuid::new_v4().to_string()); - if !text_flushed { - current_text_message_id = Some(msg_id.clone()); - text_flushed = true; - log::debug!("[bedrock] Flushing buffered text ({} chars) before tool call", buffered_text.len()); - let add_msg = build_add_agent_output_message( - &task_id, - &msg_id, - &buffered_text, - ); - yield Ok(add_msg); - } else { - log::debug!("[bedrock] Flushing remaining buffered text ({} chars) as append before tool call", buffered_text.len()); - let append = build_append_text( - &task_id, - &msg_id, - &buffered_text, - ); - yield Ok(append); - } - buffered_text.clear(); - } - current_tool_use_id = tool_start.tool_use_id().to_string(); - current_tool_name = tool_start.name().to_string(); - current_tool_input_json.clear(); + if let Some(ContentBlockStart::ToolUse(tool_start)) = block_start.start() { + _has_tool_calls = true; + if !buffered_text.is_empty() { + let msg_id = current_text_message_id + .clone() + .unwrap_or_else(|| Uuid::new_v4().to_string()); + if !text_flushed { + current_text_message_id = Some(msg_id.clone()); + text_flushed = true; + log::debug!("[bedrock] Flushing buffered text ({} chars) before tool call", buffered_text.len()); + let add_msg = build_add_agent_output_message( + &task_id, + &msg_id, + &buffered_text, + ); + yield Ok(add_msg); + } else { + log::debug!("[bedrock] Flushing remaining buffered text ({} chars) as append before tool call", buffered_text.len()); + let append = build_append_text( + &task_id, + &msg_id, + &buffered_text, + ); + yield Ok(append); } - _ => {} + buffered_text.clear(); } + current_tool_use_id = tool_start.tool_use_id().to_string(); + current_tool_name = tool_start.name().to_string(); + current_tool_input_json.clear(); } } StreamEvent::ContentBlockDelta(delta) => { @@ -187,7 +184,7 @@ pub fn bedrock_stream_to_response_events( // AddMessagesToTask carries enough content for // the exchange to be fully registered before // subsequent AppendToMessageContent events arrive. - if buffered_text.len() >= 1 { + if !buffered_text.is_empty() { let msg_id = Uuid::new_v4().to_string(); current_text_message_id = Some(msg_id.clone()); text_flushed = true; @@ -201,10 +198,8 @@ pub fn bedrock_stream_to_response_events( } } } - ContentBlockDelta::ReasoningContent(reasoning) => { - if let ReasoningContentBlockDelta::Text(text) = reasoning { - log::trace!("[bedrock] Reasoning delta ({} chars) - not displayed to user", text.len()); - } + ContentBlockDelta::ReasoningContent(ReasoningContentBlockDelta::Text(text)) => { + log::trace!("[bedrock] Reasoning delta ({} chars) - not displayed to user", text.len()); } ContentBlockDelta::ToolUse(tool_delta) => { current_tool_input_json.push_str(tool_delta.input()); @@ -593,6 +588,7 @@ fn build_user_query_message(task_id: &str, query_text: &str) -> ResponseEvent { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::UserQuery(api::message::UserQuery { query: query_text.to_string(), ..Default::default() @@ -682,10 +678,14 @@ pub fn build_stream_finished( context_window_usage: context_usage, summarized: is_summarization, credits_spent: 0.0, + platform_credits_spent: 0.0, + total_input_tokens: input_tokens as u32, token_usage: vec![], tool_usage_metadata: None, warp_token_usage: std::collections::HashMap::new(), byok_token_usage, + custom_endpoint_token_usage: std::collections::HashMap::new(), + context_window_segments: vec![], }); ResponseEvent { @@ -757,6 +757,7 @@ fn build_add_agent_output_message( timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::AgentOutput( api::message::AgentOutput { text: initial_text.to_string(), @@ -790,6 +791,7 @@ fn build_append_text(task_id: &str, message_id: &str, text_delta: &str) -> Respo timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::AgentOutput( api::message::AgentOutput { text: text_delta.to_string(), @@ -1227,6 +1229,7 @@ pub fn build_tool_call_message( timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::ToolCall(api::message::ToolCall { tool_call_id: effective_tool_call_id, tool: Some(tool_variant), @@ -1243,6 +1246,7 @@ pub fn build_tool_call_message( timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::AgentOutput( api::message::AgentOutput { text: format!( diff --git a/app/src/ai/bedrock/response_translator_tests.rs b/app/src/ai/bedrock/response_translator_tests.rs index 5efc9faf..fa886ce4 100644 --- a/app/src/ai/bedrock/response_translator_tests.rs +++ b/app/src/ai/bedrock/response_translator_tests.rs @@ -1,4 +1,5 @@ -use warp_multi_agent_api::{self as api, response_event::stream_finished}; +use warp_multi_agent_api::response_event::stream_finished; +use warp_multi_agent_api::{self as api}; use super::response_translator::*; diff --git a/app/src/ai/bedrock/settings_view.rs b/app/src/ai/bedrock/settings_view.rs index 8d2f854c..e036c3b6 100644 --- a/app/src/ai/bedrock/settings_view.rs +++ b/app/src/ai/bedrock/settings_view.rs @@ -1,11 +1,12 @@ +use galaxyui::elements::{ + Container, CornerRadius, CrossAxisAlignment, Flex, ParentElement, Radius, Text, +}; +use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; + use crate::ai::bedrock::convert::CachingConfig; use crate::ai::bedrock::external_config::ExternalBedrockConfig; use crate::appearance::Appearance; use crate::ui_components::blended_colors; -use galaxyui::{ - elements::{Container, CornerRadius, CrossAxisAlignment, Flex, ParentElement, Radius, Text}, - AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, -}; pub struct SettingsView { external_config: ExternalBedrockConfig, diff --git a/app/src/ai/bedrock/test_fixtures/sample_project/src/lib.rs b/app/src/ai/bedrock/test_fixtures/sample_project/src/lib.rs index a4643b58..c672135d 100644 --- a/app/src/ai/bedrock/test_fixtures/sample_project/src/lib.rs +++ b/app/src/ai/bedrock/test_fixtures/sample_project/src/lib.rs @@ -9,16 +9,5 @@ pub fn multiply(a: i32, b: i32) -> i32 { } #[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_add() { - assert_eq!(add(2, 3), 5); - } - - #[test] - fn test_multiply() { - assert_eq!(multiply(3, 4), 12); - } -} +#[path = "lib_tests.rs"] +mod tests; diff --git a/app/src/ai/bedrock/test_fixtures/sample_project/src/lib_tests.rs b/app/src/ai/bedrock/test_fixtures/sample_project/src/lib_tests.rs new file mode 100644 index 00000000..968eba40 --- /dev/null +++ b/app/src/ai/bedrock/test_fixtures/sample_project/src/lib_tests.rs @@ -0,0 +1,11 @@ +use super::*; + +#[test] +fn test_add() { + assert_eq!(add(2, 3), 5); +} + +#[test] +fn test_multiply() { + assert_eq!(multiply(3, 4), 12); +} diff --git a/app/src/ai/bedrock/translator.rs b/app/src/ai/bedrock/translator.rs index 212a9761..81d989d8 100644 --- a/app/src/ai/bedrock/translator.rs +++ b/app/src/ai/bedrock/translator.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use std::sync::{Arc, Mutex}; use warp_multi_agent_api as api; diff --git a/app/src/ai/blocklist/action_model.rs b/app/src/ai/blocklist/action_model.rs index 1dd4520f..22dba730 100644 --- a/app/src/ai/blocklist/action_model.rs +++ b/app/src/ai/blocklist/action_model.rs @@ -34,10 +34,10 @@ pub use execute::{ StartAgentExecutorEvent, StartAgentRequest, StartAgentRequestId, }; use futures::future::{join_all, BoxFuture}; +use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use itertools::Itertools; use parking_lot::FairMutex; use preprocess::{PendingPreprocessedActions, PreprocessId}; -use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use self::execute::ask_user_question::AskUserQuestionExecutor; use self::execute::search_codebase::SearchCodebaseExecutor; diff --git a/app/src/ai/blocklist/action_model/execute.rs b/app/src/ai/blocklist/action_model/execute.rs index 897eaf19..ea15e7b2 100644 --- a/app/src/ai/blocklist/action_model/execute.rs +++ b/app/src/ai/blocklist/action_model/execute.rs @@ -40,9 +40,20 @@ use futures::future::BoxFuture; #[cfg(feature = "local_fs")] use futures::AsyncReadExt; use futures::FutureExt; +use galaxy_core::execution_mode::AppExecutionMode; +use galaxy_core::features::FeatureFlag; +#[cfg(feature = "local_fs")] +use galaxy_files::{FileModel, TextFileReadResult}; +#[cfg(feature = "local_fs")] +use galaxy_util::file::FileLoadError; +#[cfg(feature = "local_fs")] +use galaxy_util::file_type::is_buffer_binary; +use galaxyui::r#async::{Spawnable, SpawnableOutput}; +use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use grep::GrepExecutor; #[cfg(feature = "local_fs")] use mime_guess::from_path; +use notebooks::NotebookExecutor; use parking_lot::FairMutex; use read_documents::ReadDocumentsExecutor; pub(super) use read_files::ReadFilesExecutor; @@ -69,16 +80,6 @@ pub use suggest_prompt::PromptSuggestionExecutor; use upload_artifact::UploadArtifactExecutor; use use_computer::UseComputerExecutor; use wait_for_events::WaitForEventsExecutor; -use galaxy_core::execution_mode::AppExecutionMode; -use galaxy_core::features::FeatureFlag; -#[cfg(feature = "local_fs")] -use galaxy_files::{FileModel, TextFileReadResult}; -#[cfg(feature = "local_fs")] -use galaxy_util::file::FileLoadError; -#[cfg(feature = "local_fs")] -use galaxy_util::file_type::is_buffer_binary; -use galaxyui::r#async::{Spawnable, SpawnableOutput}; -use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use self::search_codebase::SearchCodebaseExecutor; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/ai/blocklist/action_model/execute/ask_user_question.rs b/app/src/ai/blocklist/action_model/execute/ask_user_question.rs index f1a7f408..4797f576 100644 --- a/app/src/ai/blocklist/action_model/execute/ask_user_question.rs +++ b/app/src/ai/blocklist/action_model/execute/ask_user_question.rs @@ -5,7 +5,9 @@ use galaxyui::{Entity, EntityId, ModelContext, SingletonEntity}; use super::{ActionExecution, AnyActionExecution, ExecuteActionInput, PreprocessActionInput}; use crate::ai::agent::{AIAgentActionResultType, AIAgentActionType}; +use crate::ai::blocklist::orchestration_events::OrchestrationEventService; use crate::ai::blocklist::BlocklistAIPermissions; +use crate::BlocklistAIHistoryModel; pub enum AskUserQuestionDecision { Completed(Vec), diff --git a/app/src/ai/blocklist/action_model/execute/ask_user_question_tests.rs b/app/src/ai/blocklist/action_model/execute/ask_user_question_tests.rs index 6fff5d93..449e47ea 100644 --- a/app/src/ai/blocklist/action_model/execute/ask_user_question_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/ask_user_question_tests.rs @@ -36,6 +36,7 @@ fn build_action(action_id: &str) -> AIAgentAction { }, task_id: TaskId::new(format!("task-{action_id}")), requires_result: false, + tool_name: None, } } diff --git a/app/src/ai/blocklist/action_model/execute/call_mcp_tool.rs b/app/src/ai/blocklist/action_model/execute/call_mcp_tool.rs index e8db517f..7b224695 100644 --- a/app/src/ai/blocklist/action_model/execute/call_mcp_tool.rs +++ b/app/src/ai/blocklist/action_model/execute/call_mcp_tool.rs @@ -1,10 +1,10 @@ use futures::future::BoxFuture; use futures::FutureExt; #[cfg(not(target_family = "wasm"))] -use itertools::Itertools; -#[cfg(not(target_family = "wasm"))] use galaxyui::SingletonEntity; use galaxyui::{Entity, EntityId, ModelContext, ModelHandle}; +#[cfg(not(target_family = "wasm"))] +use itertools::Itertools; #[cfg(not(target_family = "wasm"))] use super::get_server_output_id; diff --git a/app/src/ai/blocklist/action_model/execute/file_glob.rs b/app/src/ai/blocklist/action_model/execute/file_glob.rs index d7adee56..079f6749 100644 --- a/app/src/ai/blocklist/action_model/execute/file_glob.rs +++ b/app/src/ai/blocklist/action_model/execute/file_glob.rs @@ -4,10 +4,10 @@ use std::time::Duration; use futures::future::BoxFuture; use futures::FutureExt; +use galaxy_core::features::FeatureFlag; use galaxyui::r#async::FutureExt as AsyncFutureExt; use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use itertools::Itertools; -use galaxy_core::features::FeatureFlag; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::{ diff --git a/app/src/ai/blocklist/action_model/execute/notebooks.rs b/app/src/ai/blocklist/action_model/execute/notebooks.rs index 607acc57..39b2d165 100644 --- a/app/src/ai/blocklist/action_model/execute/notebooks.rs +++ b/app/src/ai/blocklist/action_model/execute/notebooks.rs @@ -3,25 +3,22 @@ //! These tools interact with Galaxy Drive CloudNotebook objects directly, //! as opposed to the plan tools which work through AIDocumentModel. -use futures::{future::BoxFuture, FutureExt}; +use futures::future::BoxFuture; +use futures::FutureExt; use galaxyui::{Entity, ModelContext, SingletonEntity}; -use crate::{ - ai::{ - agent::{ - AIAgentAction, AIAgentActionType, CreateDocumentsRequest, CreateDocumentsResult, - DocumentContext, EditDocumentsRequest, EditDocumentsResult, ReadDocumentsRequest, - ReadDocumentsResult, - }, - document::ai_document_model::AIDocumentVersion, - }, - cloud_object::model::persistence::CloudModel, - notebooks::CloudNotebookModel, - server::{cloud_objects::update_manager::UpdateManager, ids::ClientId}, - workspaces::user_workspaces::UserWorkspaces, -}; - use super::{ActionExecution, AnyActionExecution, ExecuteActionInput, PreprocessActionInput}; +use crate::ai::agent::{ + AIAgentAction, AIAgentActionType, CreateDocumentsRequest, CreateDocumentsResult, + DocumentContext, EditDocumentsRequest, EditDocumentsResult, ReadDocumentsRequest, + ReadDocumentsResult, +}; +use crate::ai::document::ai_document_model::AIDocumentVersion; +use crate::cloud_object::model::persistence::CloudModel; +use crate::notebooks::CloudNotebookModel; +use crate::server::cloud_objects::update_manager::UpdateManager; +use crate::server::ids::ClientId; +use crate::workspaces::user_workspaces::UserWorkspaces; pub struct NotebookExecutor; diff --git a/app/src/ai/blocklist/action_model/execute/read_documents_tests.rs b/app/src/ai/blocklist/action_model/execute/read_documents_tests.rs index 011ecb6b..89468831 100644 --- a/app/src/ai/blocklist/action_model/execute/read_documents_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/read_documents_tests.rs @@ -34,6 +34,7 @@ fn read_action(document_id: AIDocumentId) -> AIAgentAction { action: AIAgentActionType::ReadDocuments(ReadDocumentsRequest { document_ids: vec![document_id], }), + tool_name: None, } } diff --git a/app/src/ai/blocklist/action_model/execute/read_skill_tests.rs b/app/src/ai/blocklist/action_model/execute/read_skill_tests.rs index b8ea79ba..b4c6d46f 100644 --- a/app/src/ai/blocklist/action_model/execute/read_skill_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/read_skill_tests.rs @@ -4,16 +4,16 @@ use std::path::PathBuf; use ai::skills::{parse_skill, ParsedSkill, SkillProvider, SkillReference, SkillScope}; use async_channel::unbounded; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::watcher::DirectoryWatcher; -use repo_metadata::RepoMetadataModel; -use tempfile::TempDir; use galaxy_core::features::FeatureFlag; use galaxy_core::HostId; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxy_util::remote_path::RemotePath; use galaxy_util::standardized_path::StandardizedPath; use galaxyui::{App, ModelHandle}; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::watcher::DirectoryWatcher; +use repo_metadata::RepoMetadataModel; +use tempfile::TempDir; use watcher::HomeDirectoryWatcher; use super::*; @@ -36,7 +36,7 @@ fn initialize_app(app: &mut App) { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); app.add_singleton_model(SkillManager::new); } fn add_test_read_skill_executor(app: &mut App) -> ModelHandle { @@ -112,6 +112,7 @@ fn test_read_skill_executor_success() { }), task_id: TaskId::new("test-task-id".to_string()), requires_result: false, + tool_name: None, }; let input = ExecuteActionInput { @@ -174,6 +175,7 @@ fn disconnected_remote_session_does_not_fall_back_to_client_global_bundled_skill }), task_id: TaskId::new("test-task-id".to_string()), requires_result: false, + tool_name: None, }; let input = ExecuteActionInput { action: &action, @@ -259,6 +261,7 @@ fn remote_session_reads_remote_bundled_skill_catalog() { }), task_id: TaskId::new("test-task-id".to_string()), requires_result: false, + tool_name: None, }; let input = ExecuteActionInput { action: &action, @@ -307,6 +310,7 @@ fn test_read_skill_executor_reads_enabled_bundled_skill() { }), task_id: TaskId::new("test-task-id".to_string()), requires_result: false, + tool_name: None, }; let input = ExecuteActionInput { @@ -351,6 +355,7 @@ fn test_read_skill_executor_rejects_warp_control_bundled_skills_when_disabled() }), task_id: TaskId::new(format!("test-task-id-{skill_id}")), requires_result: false, + tool_name: None, }; let input = ExecuteActionInput { @@ -386,6 +391,7 @@ fn test_read_skill_executor_file_not_found() { }), task_id: TaskId::new("test-task-id".to_string()), requires_result: false, + tool_name: None, }; let input = ExecuteActionInput { diff --git a/app/src/ai/blocklist/action_model/execute/request_file_edits.rs b/app/src/ai/blocklist/action_model/execute/request_file_edits.rs index 4dcbb0df..c7705f69 100644 --- a/app/src/ai/blocklist/action_model/execute/request_file_edits.rs +++ b/app/src/ai/blocklist/action_model/execute/request_file_edits.rs @@ -12,6 +12,7 @@ pub(crate) use diff_application::{apply_edits, FileReadResult}; use futures::channel::oneshot; use futures::future::BoxFuture; use futures::FutureExt; +use galaxy_core::send_telemetry_from_ctx; use itertools::Itertools; pub(crate) use telemetry::MalformedFinalLineProxyEvent; #[allow(unused_imports)] @@ -21,7 +22,6 @@ pub use telemetry::{ RequestFileEditsTelemetryEvent, }; use vec1::{vec1, Vec1}; -use galaxy_core::send_telemetry_from_ctx; use warp_util::file::FileSaveError; use warpui::{Entity, EntityId, ModelContext, ModelHandle, SingletonEntity as _, ViewHandle}; diff --git a/app/src/ai/blocklist/action_model/execute/run_agents.rs b/app/src/ai/blocklist/action_model/execute/run_agents.rs index 0db2159a..24c96987 100644 --- a/app/src/ai/blocklist/action_model/execute/run_agents.rs +++ b/app/src/ai/blocklist/action_model/execute/run_agents.rs @@ -14,9 +14,9 @@ use ai::agent::orchestration_config::OrchestrationConfig; use ai::skills::SkillReference; use futures::future::BoxFuture; use futures::FutureExt; +use galaxy_core::execution_mode::AppExecutionMode; use settings::Setting; use warp_cli::agent::Harness; -use galaxy_core::execution_mode::AppExecutionMode; use warpui::{Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use super::start_agent::{StartAgentExecutor, StartAgentOutcome}; diff --git a/app/src/ai/blocklist/action_model/execute/run_agents_tests.rs b/app/src/ai/blocklist/action_model/execute/run_agents_tests.rs index 0b591a88..13638e0e 100644 --- a/app/src/ai/blocklist/action_model/execute/run_agents_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/run_agents_tests.rs @@ -4,9 +4,9 @@ use ai::agent::action::{RunAgentsAgentRunConfig, RunAgentsExecutionMode, RunAgen use ai::agent::orchestration_config::{ OrchestrationConfig, OrchestrationConfigStatus, OrchestrationExecutionMode, }; -use settings::Setting; use galaxy_core::execution_mode::ExecutionMode; use galaxy_core::features::FeatureFlag; +use settings::Setting; use warpui::{App, Entity, EntityId, ModelHandle}; use super::*; @@ -239,6 +239,7 @@ fn remote_run_agents_action(harness_type: &str) -> AIAgentAction { plan_id: String::new(), harness_auth_secret_name: None, }), + tool_name: None, } } diff --git a/app/src/ai/blocklist/action_model/execute/search_codebase.rs b/app/src/ai/blocklist/action_model/execute/search_codebase.rs index 7a77cc52..2aae6e7c 100644 --- a/app/src/ai/blocklist/action_model/execute/search_codebase.rs +++ b/app/src/ai/blocklist/action_model/execute/search_codebase.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use futures::channel::oneshot; use futures::future::BoxFuture; use futures::FutureExt; +use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use itertools::Itertools; use super::{ diff --git a/app/src/ai/blocklist/action_model/execute/shell_command.rs b/app/src/ai/blocklist/action_model/execute/shell_command.rs index 61fc286f..ac31ced3 100644 --- a/app/src/ai/blocklist/action_model/execute/shell_command.rs +++ b/app/src/ai/blocklist/action_model/execute/shell_command.rs @@ -249,6 +249,8 @@ impl ShellCommandExecutor { block_id: model.block_list().active_block().id().clone(), output: "Error: Cannot execute command because another command is still running in the terminal.".to_string(), exit_code: ExitCode::from(1), + start_ts: None, + completed_ts: None, }, )); } diff --git a/app/src/ai/blocklist/action_model/execute/start_agent.rs b/app/src/ai/blocklist/action_model/execute/start_agent.rs index fd3f0e51..7381b634 100644 --- a/app/src/ai/blocklist/action_model/execute/start_agent.rs +++ b/app/src/ai/blocklist/action_model/execute/start_agent.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use futures::future::BoxFuture; use futures::FutureExt; -use shell_words::split as split_shell_words; use galaxy_cli::agent::Harness; use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity}; +use shell_words::split as split_shell_words; use super::{ActionExecution, AnyActionExecution, ExecuteActionInput, PreprocessActionInput}; use crate::ai::agent::conversation::{AIConversationId, ConversationStatus}; @@ -485,7 +485,7 @@ impl StartAgentExecutor { // In local mode (no parent_run_id), block until the child finishes // so the parent model receives the child's output as the tool result. - let wait_for_completion = parent_run_id.is_none(); + let _wait_for_completion = parent_run_id.is_none(); let (sender, receiver) = async_channel::bounded(1); let request_id = self.next_request_id(); diff --git a/app/src/ai/blocklist/action_model/execute/start_agent_tests.rs b/app/src/ai/blocklist/action_model/execute/start_agent_tests.rs index ab10fcdc..7f9615c8 100644 --- a/app/src/ai/blocklist/action_model/execute/start_agent_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/start_agent_tests.rs @@ -45,6 +45,7 @@ fn build_start_agent_action_with_prompt( }, task_id: TaskId::new("start-agent-task".to_string()), requires_result: false, + tool_name: None, } } diff --git a/app/src/ai/blocklist/action_model/execute/upload_artifact_tests.rs b/app/src/ai/blocklist/action_model/execute/upload_artifact_tests.rs index c37017b4..6443894a 100644 --- a/app/src/ai/blocklist/action_model/execute/upload_artifact_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/upload_artifact_tests.rs @@ -41,6 +41,7 @@ fn build_upload_artifact_action(file_path: &str) -> AIAgentAction { }), task_id: TaskId::new("upload-artifact-task".to_string()), requires_result: false, + tool_name: None, } } diff --git a/app/src/ai/blocklist/action_model/execute/wait_for_events_tests.rs b/app/src/ai/blocklist/action_model/execute/wait_for_events_tests.rs index 5135f904..16e5d9cd 100644 --- a/app/src/ai/blocklist/action_model/execute/wait_for_events_tests.rs +++ b/app/src/ai/blocklist/action_model/execute/wait_for_events_tests.rs @@ -131,6 +131,7 @@ fn execute_invokes_parent_registration_and_honors_child_short_circuit() { }, task_id: TaskId::new("wait-task".to_string()), requires_result: false, + tool_name: None, }; let execution = executor.update(&mut app, |executor, ctx| { diff --git a/app/src/ai/blocklist/action_model/preprocess_tests.rs b/app/src/ai/blocklist/action_model/preprocess_tests.rs index bb3aee30..6768c0aa 100644 --- a/app/src/ai/blocklist/action_model/preprocess_tests.rs +++ b/app/src/ai/blocklist/action_model/preprocess_tests.rs @@ -18,6 +18,7 @@ fn create_test_action(id: AIAgentActionId) -> AIAgentAction { citations: vec![], }, requires_result: false, + tool_name: None, } } diff --git a/app/src/ai/blocklist/agent_view/agent_input_footer/editor.rs b/app/src/ai/blocklist/agent_view/agent_input_footer/editor.rs index 3add0400..8ad85cfa 100644 --- a/app/src/ai/blocklist/agent_view/agent_input_footer/editor.rs +++ b/app/src/ai/blocklist/agent_view/agent_input_footer/editor.rs @@ -3,9 +3,9 @@ //! Uses the shared [`ChipConfigurator`] with `LeftRightZones` layout to let users //! drag/drop chips between left, right, and unused banks. -use settings::Setting as _; use galaxyui::keymap::FixedBinding; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use settings::Setting as _; use super::toolbar_item::AgentToolbarItemKind; use crate::appearance::AppearanceEvent; diff --git a/app/src/ai/blocklist/agent_view/agent_input_footer/environment_selector.rs b/app/src/ai/blocklist/agent_view/agent_input_footer/environment_selector.rs index 709393f2..530f162f 100644 --- a/app/src/ai/blocklist/agent_view/agent_input_footer/environment_selector.rs +++ b/app/src/ai/blocklist/agent_view/agent_input_footer/environment_selector.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use settings::Setting; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::Fill; @@ -14,6 +11,9 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use settings::Setting; use super::{AgentInputButtonTheme, AmbientAgentViewModel}; use crate::ai::ambient_agents::telemetry::CloudAgentTelemetryEvent; diff --git a/app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs b/app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs index f87181a1..5fd92b77 100644 --- a/app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs +++ b/app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs @@ -13,17 +13,6 @@ use std::time::Duration; use ai::document::{AIDocumentId, AIDocumentVersion}; use chrono::{DateTime, Local}; -use parking_lot::FairMutex; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -#[cfg(feature = "voice_input")] -use settings::Setting; -use settings::ToggleableSetting; -#[cfg(not(target_family = "wasm"))] -use tokio::fs; -use toolbar_item::AgentToolbarItemKind; -#[cfg(feature = "voice_input")] -use voice_input::{StartListeningError, VoiceSessionResult}; use galaxy_cli::agent::Harness; use galaxy_core::context_flag::ContextFlag; use galaxy_core::report_if_error; @@ -43,6 +32,17 @@ use galaxyui::{ AppContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use parking_lot::FairMutex; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +#[cfg(feature = "voice_input")] +use settings::Setting; +use settings::ToggleableSetting; +#[cfg(not(target_family = "wasm"))] +use tokio::fs; +use toolbar_item::AgentToolbarItemKind; +#[cfg(feature = "voice_input")] +use voice_input::{StartListeningError, VoiceSessionResult}; #[cfg(feature = "local_fs")] pub(crate) use self::environment_selector::sort_environments_by_recency; @@ -233,6 +233,9 @@ pub struct AgentInputFooter { // `Workspace::start_local_to_cloud_handoff`. handoff_to_cloud_button: ViewHandle, + start_remote_control_button: ViewHandle, + stop_remote_control_button: ViewHandle, + // CLI agent voice input state (self-contained, bypasses editor voice flow). #[cfg(feature = "voice_input")] cli_voice_input_state: CLIVoiceInputState, @@ -579,7 +582,7 @@ impl AgentInputFooter { let start_remote_control_button = ctx.add_typed_action_view(|_ctx| { ActionButton::new("/remote-control", RemoteControlButtonTheme) .with_icon(Icon::Phone01) - .with_tooltip(START_REMOTE_CONTROL_TOOLTIP) + .with_tooltip("Start remote control") .with_size(cli_button_size) .with_tooltip_alignment(TooltipAlignment::Left) .on_click(|ctx| { @@ -845,6 +848,8 @@ impl AgentInputFooter { display_chip_config, fast_forward_button, handoff_to_cloud_button, + start_remote_control_button, + stop_remote_control_button, #[cfg(feature = "voice_input")] cli_voice_input_state: CLIVoiceInputState::default(), #[cfg(feature = "voice_input")] @@ -2299,6 +2304,8 @@ pub enum AgentInputFooterAction { ShowContextMenu { position: Vector2F, }, + StartRemoteControl, + StopRemoteControl, } impl TypedActionView for AgentInputFooter { @@ -2497,6 +2504,12 @@ impl TypedActionView for AgentInputFooter { position: *position, }); } + AgentInputFooterAction::StartRemoteControl => { + ctx.emit(AgentInputFooterEvent::StartRemoteControl); + } + AgentInputFooterAction::StopRemoteControl => { + ctx.emit(AgentInputFooterEvent::StopRemoteControl); + } } } } @@ -2541,6 +2554,8 @@ pub enum AgentInputFooterEvent { /// source conversation with content) or activates `&` compose mode /// (preserving any in-flight prompt). HandoffChipClicked, + StartRemoteControl, + StopRemoteControl, } impl Entity for AgentInputFooter { diff --git a/app/src/ai/blocklist/agent_view/agent_input_footer/toolbar_item.rs b/app/src/ai/blocklist/agent_view/agent_input_footer/toolbar_item.rs index 37081674..eeac3d6d 100644 --- a/app/src/ai/blocklist/agent_view/agent_input_footer/toolbar_item.rs +++ b/app/src/ai/blocklist/agent_view/agent_input_footer/toolbar_item.rs @@ -71,6 +71,9 @@ pub enum AgentToolbarItemKind { // Agent view only – "Hand off to cloud" chip. HandoffToCloud, + + // Agent view only – "Share session" button. + ShareSession, } impl AgentToolbarItemKind { @@ -81,7 +84,8 @@ impl AgentToolbarItemKind { | Self::NLDToggle | Self::ContextWindowUsage | Self::FastForwardToggle - | Self::HandoffToCloud => ToolbarAvailability::AgentViewOnly, + | Self::HandoffToCloud + | Self::ShareSession => ToolbarAvailability::AgentViewOnly, Self::FileExplorer | Self::RichInput | Self::Settings => { ToolbarAvailability::CLIAgentOnly } @@ -102,6 +106,7 @@ impl AgentToolbarItemKind { Self::FastForwardToggle => !status.is_viewer() || status.is_executor(), // Handoff is host-initiated; viewers cannot hand off another user's conversation. Self::HandoffToCloud => !status.is_viewer(), + Self::ShareSession => !status.is_viewer(), Self::ContextChip(_) | Self::ModelSelector | Self::NLDToggle @@ -124,6 +129,7 @@ impl AgentToolbarItemKind { Self::Settings => "Settings", Self::FastForwardToggle => "Fast Forward", Self::HandoffToCloud => "Hand off to cloud", + Self::ShareSession => "Share Session", } } @@ -142,6 +148,7 @@ impl AgentToolbarItemKind { // The bundled `upload-cloud-01.svg` (cloud-with-upward-arrow) is the // closest fit among the existing icons for V0; design may swap it later. Self::HandoffToCloud => Some(Icon::UploadCloud), + Self::ShareSession => Some(Icon::Share), } } diff --git a/app/src/ai/blocklist/agent_view/agent_message_bar.rs b/app/src/ai/blocklist/agent_view/agent_message_bar.rs index 5424ae17..f9c51d23 100644 --- a/app/src/ai/blocklist/agent_view/agent_message_bar.rs +++ b/app/src/ai/blocklist/agent_view/agent_message_bar.rs @@ -7,11 +7,10 @@ use galaxyui::assets::asset_cache::AssetSource; use galaxyui::elements::{Container, Element, Empty, MouseStateHandle}; use galaxyui::keymap::Keystroke; use galaxyui::platform::OperatingSystem; -use galaxyui::{AppContext, Entity, ModelHandle, SingletonEntity, View, ViewContext}; -use parking_lot::FairMutex; use galaxyui::{ AppContext, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use parking_lot::FairMutex; use super::{AgentViewState, EphemeralMessageModel, EphemeralMessageModelEvent}; use crate::ai::agent::conversation::AIConversation; diff --git a/app/src/ai/blocklist/agent_view/agent_view_block.rs b/app/src/ai/blocklist/agent_view/agent_view_block.rs index 62a063d7..2b10cd2f 100644 --- a/app/src/ai/blocklist/agent_view/agent_view_block.rs +++ b/app/src/ai/blocklist/agent_view/agent_view_block.rs @@ -1,6 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; -use settings::Setting; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::Icon; use galaxyui::elements::{ @@ -16,6 +13,9 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, EventContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; +use settings::Setting; use super::{AgentViewController, AgentViewEntryOrigin}; use crate::ai::active_agent_views_model::ActiveAgentViewsModel; diff --git a/app/src/ai/blocklist/agent_view/controller.rs b/app/src/ai/blocklist/agent_view/controller.rs index 12b57737..5a0e4ff1 100644 --- a/app/src/ai/blocklist/agent_view/controller.rs +++ b/app/src/ai/blocklist/agent_view/controller.rs @@ -1,12 +1,12 @@ use std::sync::Arc; use std::time::Duration; -use instant::Instant; -use parking_lot::FairMutex; use galaxy_core::ui::appearance::Appearance; use galaxyui::keymap::Keystroke; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; +use instant::Instant; +use parking_lot::FairMutex; use super::{DismissalStrategy, EphemeralMessage, EphemeralMessageModel}; use crate::ai::agent::conversation::AIConversationId; @@ -1021,7 +1021,6 @@ fn exit_confirmation_message( ) -> Message { use galaxyui::SingletonEntity; - let appearance = Appearance::handle(app).as_ref(app); let (keystroke, text) = match trigger { diff --git a/app/src/ai/blocklist/agent_view/inline_agent_view_header.rs b/app/src/ai/blocklist/agent_view/inline_agent_view_header.rs index ff4415b6..2c9b7647 100644 --- a/app/src/ai/blocklist/agent_view/inline_agent_view_header.rs +++ b/app/src/ai/blocklist/agent_view/inline_agent_view_header.rs @@ -1,12 +1,12 @@ use std::sync::Arc; use ai::agent::action::{AIAgentActionType, ShellCommandDelay}; -use parking_lot::FairMutex; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{CornerRadius, Radius}; use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, View, ViewContext, }; +use parking_lot::FairMutex; use crate::ai::agent::icons; use crate::ai::blocklist::block::cli_controller::LongRunningCommandControlState; diff --git a/app/src/ai/blocklist/agent_view/mod.rs b/app/src/ai/blocklist/agent_view/mod.rs index 0a67a379..e1e0d8df 100644 --- a/app/src/ai/blocklist/agent_view/mod.rs +++ b/app/src/ai/blocklist/agent_view/mod.rs @@ -22,15 +22,15 @@ pub use agent_view_block::*; pub use controller::*; pub(crate) use conversation_selection::AgentViewConversationSelection; pub use ephemeral_message_model::*; -use galaxyui::fonts::Properties; -pub use inline_agent_view_header::*; -pub use orchestration_pill_bar::{render_orchestration_breadcrumbs, OrchestrationPillBar}; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::Fill; +use galaxyui::fonts::Properties; use galaxyui::keymap::Keystroke; use galaxyui::{AppContext, SingletonEntity}; +pub use inline_agent_view_header::*; +pub use orchestration_pill_bar::{render_orchestration_breadcrumbs, OrchestrationPillBar}; +use pathfinder_color::ColorU; pub use zero_state_block::*; use crate::terminal::model::TerminalModel; diff --git a/app/src/ai/blocklist/agent_view/orchestration_conversation_links.rs b/app/src/ai/blocklist/agent_view/orchestration_conversation_links.rs index 5a6d1a88..cc962ede 100644 --- a/app/src/ai/blocklist/agent_view/orchestration_conversation_links.rs +++ b/app/src/ai/blocklist/agent_view/orchestration_conversation_links.rs @@ -1,5 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -11,6 +9,8 @@ use galaxyui::fonts::Weight::Bold; use galaxyui::platform::Cursor; use galaxyui::text_layout::ClipConfig; use galaxyui::{AppContext, Element, EntityId, EventContext, SingletonEntity}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; use crate::ai::agent::api::ServerConversationToken; use crate::ai::agent::conversation::{AIConversation, AIConversationId}; diff --git a/app/src/ai/blocklist/agent_view/orchestration_pill_bar.rs b/app/src/ai/blocklist/agent_view/orchestration_pill_bar.rs index 3b8e9c56..882734df 100644 --- a/app/src/ai/blocklist/agent_view/orchestration_pill_bar.rs +++ b/app/src/ai/blocklist/agent_view/orchestration_pill_bar.rs @@ -7,9 +7,6 @@ use std::collections::hash_map::DefaultHasher; use std::collections::{HashMap, HashSet}; use std::hash::{Hash, Hasher}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use warp_cli::agent::Harness; use galaxy_core::channel::ChannelState; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; @@ -17,6 +14,9 @@ use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::{Fill, WarpTheme}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use warp_cli::agent::Harness; use warpui::elements::new_scrollable::{NewScrollable, ScrollableAppearance, SingleAxisConfig}; use warpui::elements::{ Align, AnchorPair, ChildAnchor, ChildView, ClippedScrollStateHandle, ConstrainedBox, Container, diff --git a/app/src/ai/blocklist/agent_view/orchestration_pill_bar_tests.rs b/app/src/ai/blocklist/agent_view/orchestration_pill_bar_tests.rs index 82765271..01a2fdca 100644 --- a/app/src/ai/blocklist/agent_view/orchestration_pill_bar_tests.rs +++ b/app/src/ai/blocklist/agent_view/orchestration_pill_bar_tests.rs @@ -55,6 +55,7 @@ fn pill_bar_data_layer_finds_restored_children_before_pane_creation() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }) .expect("child conversation data should serialize"), last_modified_at: now, @@ -105,6 +106,7 @@ fn pill_bar_data_layer_finds_restored_children_before_pane_creation() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }) .expect("parent conversation data should serialize"), last_modified_at: now - chrono::Duration::seconds(1), diff --git a/app/src/ai/blocklist/agent_view/shortcuts/mod.rs b/app/src/ai/blocklist/agent_view/shortcuts/mod.rs index 79f6157f..acde2fb1 100644 --- a/app/src/ai/blocklist/agent_view/shortcuts/mod.rs +++ b/app/src/ai/blocklist/agent_view/shortcuts/mod.rs @@ -2,13 +2,13 @@ mod model; use std::borrow::Cow; -pub use model::*; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ Border, Container, CrossAxisAlignment, Expanded, Flex, ParentElement, Text, }; +pub use model::*; +use pathfinder_color::ColorU; use warpui::keymap::Keystroke; use warpui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use warpui::{AppContext, Element, SingletonEntity}; @@ -259,6 +259,7 @@ pub fn render_agent_shortcuts_view( } pub mod styles { + use super::Appearance; pub fn keystroke_size(appearance: &Appearance) -> f32 { font_size(appearance) + 2. diff --git a/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs b/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs index d8b5fe6c..38de717c 100644 --- a/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs +++ b/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! Inline subagent panel rendered within the parent agent's chat flow. //! //! Shows a collapsible panel with the subagent's status, a mini-transcript of @@ -11,7 +13,7 @@ use galaxyui::{AppContext, SingletonEntity}; use pathfinder_color::ColorU; use warp_multi_agent_api as api; -use crate::ai::agent::conversation::{AIConversationId, ConversationStatus}; +use crate::ai::agent::conversation::{AIConversationId, ConversationStatus, StatusColorStyle}; use crate::ai::agent::AIAgentActionId; use crate::ai::blocklist::block::AIBlockAction; use crate::ai::blocklist::inline_action::inline_action_header::{ @@ -127,7 +129,7 @@ fn render_panel_header( // Left: status icon + agent name + status text let mut left_side = Flex::row().with_cross_axis_alignment(CrossAxisAlignment::Center); - let (icon, icon_color) = status.status_icon_and_color(theme); + let (icon, icon_color) = status.status_icon_and_color(theme, StatusColorStyle::Standard); let status_icon_element = ConstrainedBox::new(galaxyui::elements::Icon::new(icon.into(), icon_color).finish()) .with_width(icon_size(app)) @@ -151,8 +153,10 @@ fn render_panel_header( ConversationStatus::InProgress => "Working...", ConversationStatus::Success => "Complete", ConversationStatus::Error => "Error", + ConversationStatus::TransientError => "Retrying...", ConversationStatus::Cancelled => "Cancelled", ConversationStatus::Blocked { .. } => "Blocked", + ConversationStatus::WaitingForEvents => "Waiting...", }; let status_text_color = blended_colors::text_disabled(theme, surface); left_side.add_child( diff --git a/app/src/ai/blocklist/agent_view/zero_state_block.rs b/app/src/ai/blocklist/agent_view/zero_state_block.rs index 4b05cef1..a178416f 100644 --- a/app/src/ai/blocklist/agent_view/zero_state_block.rs +++ b/app/src/ai/blocklist/agent_view/zero_state_block.rs @@ -1,12 +1,10 @@ +#![allow(dead_code)] + use std::borrow::Cow; use std::cmp::Reverse; use std::path::Path; use std::sync::Arc; -use itertools::Itertools as _; -use markdown_parser::{parse_markdown, FormattedText, FormattedTextFragment, FormattedTextLine}; -use parking_lot::FairMutex; -use settings::Setting; use galaxy_core::features::FeatureFlag; use galaxy_core::report_if_error; use galaxy_core::ui::Icon; @@ -25,7 +23,9 @@ use galaxyui::{ Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; -use std::{borrow::Cow, cmp::Reverse, path::Path, sync::Arc}; +use itertools::Itertools as _; +use markdown_parser::{parse_markdown, FormattedText, FormattedTextFragment, FormattedTextLine}; +use parking_lot::FairMutex; use crate::ai::active_agent_views_model::{ActiveAgentViewsModel, ConversationOrTaskId}; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/ai/blocklist/block.rs b/app/src/ai/blocklist/block.rs index 40c9f7fb..aa33d3f7 100644 --- a/app/src/ai/blocklist/block.rs +++ b/app/src/ai/blocklist/block.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! Implementation of "AI blocks" used to render AI queries and outputs in the blocklist. pub mod cli; pub mod cli_controller; @@ -28,6 +30,9 @@ use base64::Engine as _; use chrono::Duration; use cli_controller::{CLISubagentController, CLISubagentEvent}; use find::FindState; +use galaxy_core::features::FeatureFlag; +use galaxy_core::ui::theme::color::internal_colors; +use galaxy_core::ui::theme::Fill; use indexmap::IndexMap; use itertools::Itertools; use model::AIBlockOutputStatus; @@ -40,9 +45,6 @@ use repo_metadata::repositories::DetectedRepositories; use secret_redaction::*; use serde::Serialize; use settings::Setting as _; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::Fill; use warp_editor::content::buffer::InitialBufferState; #[cfg(feature = "local_fs")] use warp_editor::content::edit::resolve_asset_source_relative_to_directory; @@ -129,6 +131,7 @@ use crate::ai::blocklist::inline_action::search_codebase::{ use crate::ai::blocklist::inline_action::suggested_unit_tests::{ SuggestedUnitTestsEvent, SuggestedUnitTestsView, }; +use crate::ai::blocklist::inline_action::summarization::SummarizationView; use crate::ai::blocklist::inline_action::web_fetch::WebFetchView; use crate::ai::blocklist::inline_action::web_search::WebSearchView; use crate::ai::blocklist::permissions::{ @@ -478,6 +481,9 @@ pub(super) struct AIBlockStateHandles { /// ReadSkill and ReadFiles action banners. Keyed by action id so that /// multiple skill banners in the same block don't share hover/click state. skill_button_handles: HashMap, + usage_button_handle: MouseStateHandle, + subagent_panel_states: + HashMap, } #[derive(Default, Clone, Debug)] @@ -1067,6 +1073,7 @@ pub struct AIBlock { terminal_view_handle: WeakViewHandle, ask_user_question_view: Option>, + is_usage_footer_expanded: bool, } struct EmbeddedCodeEditorView { @@ -1512,6 +1519,7 @@ impl AIBlock { resolved_blocklist_image_sources: Default::default(), terminal_view_handle, ask_user_question_view: None, + is_usage_footer_expanded: false, }; me.run_secret_redaction_on_user_query(me.client_ids.conversation_id, ctx); me.spawn_link_detection(ctx); @@ -2638,16 +2646,14 @@ impl AIBlock { base_branch, }, .. - } => { - if self.model.is_restored() && FeatureFlag::PRCommentsV2.is_enabled() { - self.handle_insert_code_review_comments( - id.clone(), - repo_path, - comments, - base_branch.as_deref(), - ctx, - ); - } + } if self.model.is_restored() && FeatureFlag::PRCommentsV2.is_enabled() => { + self.handle_insert_code_review_comments( + id.clone(), + repo_path, + comments, + base_branch.as_deref(), + ctx, + ); } _ => (), } @@ -3995,7 +4001,7 @@ impl AIBlock { return; } - let view = ctx.add_view(|ctx| SummarizationView::new(ctx)); + let view = ctx.add_view(SummarizationView::new); self.summarization_views.insert(key, view); ctx.notify(); } @@ -6328,6 +6334,7 @@ pub enum AIBlockAction { ToggleSubagentPanel { action_id: AIAgentActionId, }, + ToggleIsUsageFooterExpanded, } impl TypedActionView for AIBlock { @@ -6335,6 +6342,16 @@ impl TypedActionView for AIBlock { fn handle_action(&mut self, action: &Self::Action, ctx: &mut ViewContext) { match action { + AIBlockAction::ToggleIsUsageFooterExpanded => { + self.is_usage_footer_expanded = !self.is_usage_footer_expanded; + ctx.notify(); + } + AIBlockAction::ToggleSubagentPanel { action_id } => { + if let Some(state) = self.state_handles.subagent_panel_states.get_mut(action_id) { + state.is_expanded = !state.is_expanded; + ctx.notify(); + } + } AIBlockAction::SetCollapsibleBlockPinnedToBottom { message_id, pinned_to_bottom, diff --git a/app/src/ai/blocklist/block/cli.rs b/app/src/ai/blocklist/block/cli.rs index 580f7487..764116ce 100644 --- a/app/src/ai/blocklist/block/cli.rs +++ b/app/src/ai/blocklist/block/cli.rs @@ -4,12 +4,6 @@ use std::rc::Rc; use std::sync::Arc; use std::time::Duration; -use lazy_static::lazy_static; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use parking_lot::{FairMutex, RwLock}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxy_core::report_error; use galaxy_core::semantic_selection::SemanticSelection; @@ -37,6 +31,12 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use lazy_static::lazy_static; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use parking_lot::{FairMutex, RwLock}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; use super::cli_controller::{CLISubagentController, CLISubagentEvent, UserTakeOverReason}; use super::model::{AIBlockModel, AIBlockModelHelper, AIBlockModelImpl, AIBlockOutputStatus}; @@ -628,25 +628,25 @@ impl CLISubagentView { AIAgentActionType::SearchCodebase(_) | AIAgentActionType::ReadFiles(_) | AIAgentActionType::Grep { .. } - | AIAgentActionType::FileGlobV2 { .. } => { - if should_show_read_files_speedbump(ctx) { - AISettings::handle(ctx).update(ctx, |settings, ctx| { - let _ = settings - .should_show_agent_mode_autoread_files_speedbump - .set_value(false, ctx); - }); + | AIAgentActionType::FileGlobV2 { .. } + if should_show_read_files_speedbump(ctx) => + { + AISettings::handle(ctx).update(ctx, |settings, ctx| { + let _ = settings + .should_show_agent_mode_autoread_files_speedbump + .set_value(false, ctx); + }); - BlocklistAIPermissions::handle(ctx).update(ctx, |permissions, ctx| { - if let Err(e) = permissions.set_always_allow_read_files( - self.always_allow_read_files_checked, - self.terminal_view_id, - ctx, - ) { - report_error!(e); - } - }); - ctx.notify(); - } + BlocklistAIPermissions::handle(ctx).update(ctx, |permissions, ctx| { + if let Err(e) = permissions.set_always_allow_read_files( + self.always_allow_read_files_checked, + self.terminal_view_id, + ctx, + ) { + report_error!(e); + } + }); + ctx.notify(); } _ => {} } @@ -1153,32 +1153,28 @@ impl View for CLISubagentView { } } } - AIAgentOutputMessageType::WebSearch(WebSearchStatus::Searching { query }) => { - if !should_hide_responses { - result.add_child( - render_scrollable_container( - ScrollableContainerProps { - scroll_state: self - .state_handles - .action_scroll_state - .clone(), - child: render_web_search(query.clone(), app), - background_color: internal_colors::neutral_2( - appearance.theme(), - ), - border: Some( - Border::all(1.).with_border_fill( - internal_colors::neutral_3(theme), - ), - ), - max_height: resizable_height, - }, - app, - ) - .with_margin_bottom(8.) - .finish(), - ); - } + AIAgentOutputMessageType::WebSearch(WebSearchStatus::Searching { query }) + if !should_hide_responses => + { + result.add_child( + render_scrollable_container( + ScrollableContainerProps { + scroll_state: self.state_handles.action_scroll_state.clone(), + child: render_web_search(query.clone(), app), + background_color: internal_colors::neutral_2( + appearance.theme(), + ), + border: Some( + Border::all(1.) + .with_border_fill(internal_colors::neutral_3(theme)), + ), + max_height: resizable_height, + }, + app, + ) + .with_margin_bottom(8.) + .finish(), + ); } _ => (), } diff --git a/app/src/ai/blocklist/block/cli_controller.rs b/app/src/ai/blocklist/block/cli_controller.rs index 24ec19dd..16f22e5b 100644 --- a/app/src/ai/blocklist/block/cli_controller.rs +++ b/app/src/ai/blocklist/block/cli_controller.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::sync::Arc; +use galaxyui::{Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use instant::Instant; use parking_lot::FairMutex; use serde::{Deserialize, Serialize}; diff --git a/app/src/ai/blocklist/block/model.rs b/app/src/ai/blocklist/block/model.rs index 9b50423e..aeacba0c 100644 --- a/app/src/ai/blocklist/block/model.rs +++ b/app/src/ai/blocklist/block/model.rs @@ -2,11 +2,11 @@ mod helper; mod model_impl; use chrono::TimeDelta; +use galaxy_core::features::FeatureFlag; +use galaxyui::{AppContext, ViewContext}; pub use helper::AIBlockModelHelper; pub use model_impl::*; use session_sharing_protocol::common::ParticipantId; -use galaxy_core::features::FeatureFlag; -use galaxyui::{AppContext, ViewContext}; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::{ @@ -219,7 +219,10 @@ pub trait AIBlockModel { #[cfg(any(test, feature = "integration_tests"))] pub mod testing { - use super::{AIBlockModel, AIBlockOutputStatus, OutputStatusUpdateCallback}; + use super::{ + AIBlockModel, AIBlockOutputStatus, AIConversationId, AppContext, LLMId, + OutputStatusUpdateCallback, ViewContext, + }; use crate::ai::agent::{AIAgentInput, AIAgentOutput, ServerOutputId, Shared}; use crate::ai::blocklist::model::{ AIRequestType, PassiveRequestType, PassiveSuggestionTriggerType, diff --git a/app/src/ai/blocklist/block/model/model_impl.rs b/app/src/ai/blocklist/block/model/model_impl.rs index 732c0dd6..ef9ebbb4 100644 --- a/app/src/ai/blocklist/block/model/model_impl.rs +++ b/app/src/ai/blocklist/block/model/model_impl.rs @@ -2,10 +2,9 @@ use std::marker::PhantomData; use anyhow::{anyhow, Result}; use chrono::{Local, TimeDelta}; -use galaxyui::{AppContext, SingletonEntity, View, ViewContext}; +use galaxyui::{AppContext, Entity, SingletonEntity, View, ViewContext}; use history_model::{BlocklistAIHistoryEvent, BlocklistAIHistoryModel}; use session_sharing_protocol::common::ParticipantId; -use galaxyui::{AppContext, Entity, SingletonEntity, ViewContext}; use super::{AIBlockModel, AIBlockOutputStatus, OutputStatusUpdateCallback}; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/ai/blocklist/block/number_shortcut_buttons_tests.rs b/app/src/ai/blocklist/block/number_shortcut_buttons_tests.rs index 4d988e28..760dc5a9 100644 --- a/app/src/ai/blocklist/block/number_shortcut_buttons_tests.rs +++ b/app/src/ai/blocklist/block/number_shortcut_buttons_tests.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::new_scrollable::SingleAxisConfig; use galaxyui::elements::{ChildView, Clipped, ClippedScrollStateHandle, ConstrainedBox, Fill}; @@ -10,7 +9,7 @@ use galaxyui::{ App, Entity, Event, Presenter, TypedActionView, View, ViewContext, ViewHandle, WindowId, WindowInvalidation, }; -use std::{cell::RefCell, rc::Rc}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::*; diff --git a/app/src/ai/blocklist/block/pending_user_query_block.rs b/app/src/ai/blocklist/block/pending_user_query_block.rs index 933efdc5..7352ab0a 100644 --- a/app/src/ai/blocklist/block/pending_user_query_block.rs +++ b/app/src/ai/blocklist/block/pending_user_query_block.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use parking_lot::RwLock; use galaxy_core::features::FeatureFlag; use galaxy_core::semantic_selection::SemanticSelection; use galaxyui::elements::{ @@ -12,6 +11,7 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use parking_lot::RwLock; use crate::ai::blocklist::block::view_impl::common::render_user_avatar; use crate::ai::blocklist::block::view_impl::{ diff --git a/app/src/ai/blocklist/block/status_bar.rs b/app/src/ai/blocklist/block/status_bar.rs index fa883ecd..413d94d2 100644 --- a/app/src/ai/blocklist/block/status_bar.rs +++ b/app/src/ai/blocklist/block/status_bar.rs @@ -2,31 +2,32 @@ use std::collections::HashSet; use std::sync::Arc; use std::time::Duration; -use instant::Instant; -use markdown_parser::FormattedTextFragment; -use parking_lot::FairMutex; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxy_core::ui::Icon as CoreIcon; -use warp_multi_agent_api as api; use galaxyui::elements::shimmering_text::ShimmeringTextStateHandle; use galaxyui::elements::{Border, Container, Empty, Flex, MouseStateHandle, ParentElement, Text}; use galaxyui::keymap::Keystroke; use galaxyui::presenter::ChildView; use galaxyui::r#async::{SpawnedFutureHandle, Timer}; +use galaxyui::text_layout::ClipConfig; use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use instant::Instant; +use markdown_parser::FormattedTextFragment; +use parking_lot::FairMutex; +use pathfinder_color::ColorU; +use warp_multi_agent_api as api; use super::cli_controller::{CLISubagentController, CLISubagentEvent, UserTakeOverReason}; use super::model::{AIBlockModel, AIBlockModelImpl, AIBlockOutputStatus}; use super::view_impl::common::{ render_switch_control_to_user_button, render_warping_indicator, render_warping_indicator_base, AutoExecuteButtonProps, ButtonProps, ForceRefreshButtonProps, MaybeShimmeringText, - WarpingIndicatorProps, WarpingProps, LOAD_OUTPUT_MESSAGE, WAITING_FOR_USER_INPUT_MESSAGE, + WarpingIndicatorProps, WarpingProps, WAITING_FOR_USER_INPUT_MESSAGE, }; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::{ @@ -39,6 +40,7 @@ use crate::ai::blocklist::agent_view::{ agent_view_bg_fill, is_in_cloud_context, AgentMessageBar, AgentViewController, EphemeralMessageModel, }; +use crate::ai::blocklist::block::view_impl::common::random_load_output_message; use crate::ai::blocklist::model::AIBlockModelHelper; use crate::ai::blocklist::summarization_cancel_dialog::{ self, SummarizationCancelDialog, SummarizationCancelDialogEvent, diff --git a/app/src/ai/blocklist/block/view_impl.rs b/app/src/ai/blocklist/block/view_impl.rs index 682525d6..0566c3d9 100644 --- a/app/src/ai/blocklist/block/view_impl.rs +++ b/app/src/ai/blocklist/block/view_impl.rs @@ -32,16 +32,13 @@ mod todos; use std::collections::{HashMap, HashSet}; use common::get_highlight_ranges_for_find_matches; -use itertools::Itertools; -use pathfinder_color::ColorU; -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxy_core::semantic_selection::SemanticSelection; use galaxy_core::ui::color::contrast::{ foreground_color_with_minimum_contrast, MinimumAllowedContrast, }; use galaxy_core::ui::color::Rgb; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme, WarpTheme}; use galaxyui::elements::{ Align, Border, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Expanded, Flex, FormattedTextElement, Highlight, HighlightedRange, Hoverable, @@ -53,6 +50,9 @@ use galaxyui::platform::Cursor; use galaxyui::text_layout::TextStyle; use galaxyui::ui_components::components::UiComponent; use galaxyui::{AppContext, Element, SingletonEntity, View, ViewContext}; +use itertools::Itertools; +use pathfinder_color::ColorU; +use settings::Setting as _; use super::secret_redaction::SecretRedactionState; use super::{ @@ -1127,6 +1127,7 @@ impl View for AIBlock { disable_rule_suggestions_button: &self.disable_rule_suggestions_button, has_accepted_edits, current_todo_list: self.current_todo_list(app), + is_usage_footer_expanded: self.is_usage_footer_expanded, finish_reason: self.finish_reason.as_ref(), shared_session_status: &shared_session_status, terminal_view_id: self.terminal_view_id, diff --git a/app/src/ai/blocklist/block/view_impl/common.rs b/app/src/ai/blocklist/block/view_impl/common.rs index ae0677f4..ebb3f167 100644 --- a/app/src/ai/blocklist/block/view_impl/common.rs +++ b/app/src/ai/blocklist/block/view_impl/common.rs @@ -12,10 +12,6 @@ use std::path::Path; use std::path::PathBuf; use std::sync::Arc; -use itertools::Itertools; -use markdown_parser::{FormattedText, FormattedTextInline, TableAlignment}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; @@ -45,6 +41,11 @@ use galaxyui::text_layout::{ClipConfig, TextAlignment, TextStyle}; use galaxyui::ui_components::button::Button; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{Action, AppContext, Element, EventContext, SingletonEntity, View, ViewHandle}; +use itertools::Itertools; +use markdown_parser::{FormattedText, FormattedTextInline, TableAlignment}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use rand::Rng; use super::output::LinkActionConstructors; use super::{add_highlights_to_rich_text, add_highlights_to_text}; diff --git a/app/src/ai/blocklist/block/view_impl/common_tests.rs b/app/src/ai/blocklist/block/view_impl/common_tests.rs index e72695d2..3207314f 100644 --- a/app/src/ai/blocklist/block/view_impl/common_tests.rs +++ b/app/src/ai/blocklist/block/view_impl/common_tests.rs @@ -3,13 +3,13 @@ use std::path::PathBuf; use std::sync::Arc; use ai::skills::{ParsedSkill, SkillProvider, SkillScope}; -use itertools::Itertools; -use ui_components::lightbox::{LightboxImage, LightboxImageSource}; -use warp_util::local_or_remote_path::LocalOrRemotePath; #[cfg(feature = "local_fs")] use galaxyui::assets::asset_cache::AssetSource; use galaxyui::elements::{Empty, MouseStateHandle}; use galaxyui::{App, Element}; +use itertools::Itertools; +use ui_components::lightbox::{LightboxImage, LightboxImageSource}; +use warp_util::local_or_remote_path::LocalOrRemotePath; #[cfg(feature = "local_fs")] use super::{blocklist_image_asset_source, ResolvedBlocklistImageSources}; diff --git a/app/src/ai/blocklist/block/view_impl/orchestration.rs b/app/src/ai/blocklist/block/view_impl/orchestration.rs index c3ebaa7b..5f5a815c 100644 --- a/app/src/ai/blocklist/block/view_impl/orchestration.rs +++ b/app/src/ai/blocklist/block/view_impl/orchestration.rs @@ -1,13 +1,13 @@ //! Rendering functions for orchestration-related output items (messaging & agent management). -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; use galaxyui::elements::{ ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, FormattedTextElement, Hoverable, MouseStateHandle, ParentElement, Radius, Shrinkable, Text, }; use galaxyui::platform::Cursor; use galaxyui::{AppContext, Element, SingletonEntity}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; use super::common::render_scrollable_collapsible_content; use super::output::{action_icon, Props}; diff --git a/app/src/ai/blocklist/block/view_impl/orchestration_tests.rs b/app/src/ai/blocklist/block/view_impl/orchestration_tests.rs index 550280ae..cbd14a7d 100644 --- a/app/src/ai/blocklist/block/view_impl/orchestration_tests.rs +++ b/app/src/ai/blocklist/block/view_impl/orchestration_tests.rs @@ -299,6 +299,7 @@ fn participant_for_restored_child_run_id_resolves_to_agent_name() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }) .expect("child conversation data should serialize"), last_modified_at: now, @@ -352,6 +353,7 @@ fn participant_for_restored_child_run_id_resolves_to_agent_name() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }) .expect("parent conversation data should serialize"), last_modified_at: now - chrono::Duration::seconds(1), diff --git a/app/src/ai/blocklist/block/view_impl/output.rs b/app/src/ai/blocklist/block/view_impl/output.rs index f524011a..1ed41007 100644 --- a/app/src/ai/blocklist/block/view_impl/output.rs +++ b/app/src/ai/blocklist/block/view_impl/output.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! Renders the AI output portion of the AI block. //! //! This includes text, code snippets, suggested commands, and interactive inline action UX. @@ -14,12 +16,6 @@ use ai::agent::action::{ }; use ai::agent::file_locations::group_file_contexts_for_display; use ai::skills::{ParsedSkill, SkillReference}; -use indexmap::IndexMap; -use itertools::Itertools; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::channel::ChannelState; use galaxy_core::ui::theme::color::internal_colors; use galaxy_util::local_or_remote_path::LocalOrRemotePath; @@ -37,6 +33,12 @@ use galaxyui::ui_components::radio_buttons::{RadioButtonItem, RadioButtonLayout} use galaxyui::{ Action, AppContext, Element, EntityId, ModelHandle, SingletonEntity, View, ViewHandle, }; +use indexmap::IndexMap; +use itertools::Itertools; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use ui_components::{button, Component as _, Options as _}; use super::common::{ format_elapsed_seconds, render_debug_footer, render_failed_output, render_informational_footer, @@ -93,6 +95,7 @@ use crate::ai::blocklist::inline_action::requested_command::RequestedCommand; use crate::ai::blocklist::inline_action::run_agents_card_view::RunAgentsCardView; use crate::ai::blocklist::inline_action::search_codebase::SearchCodebaseView; use crate::ai::blocklist::inline_action::suggested_unit_tests::SuggestedUnitTestsView; +use crate::ai::blocklist::inline_action::summarization::SummarizationView; use crate::ai::blocklist::inline_action::web_fetch::WebFetchView; use crate::ai::blocklist::inline_action::web_search::WebSearchView; use crate::ai::blocklist::keyboard_navigable_buttons::KeyboardNavigableButtons; @@ -170,6 +173,7 @@ pub(crate) struct Props<'a> { pub(super) disable_rule_suggestions_button: &'a ViewHandle, pub(super) current_todo_list: Option<&'a AIAgentTodoList>, pub(super) has_accepted_edits: bool, + pub(super) is_usage_footer_expanded: bool, pub(super) finish_reason: Option<&'a FinishReason>, pub(super) shared_session_status: &'a SharedSessionStatus, pub(super) terminal_view_id: EntityId, @@ -886,13 +890,9 @@ pub(super) fn render(props: Props, app: &AppContext) -> Box { AIAgentOutputMessageType::Summarization { text, finished_duration, - summarization_type, + summarization_type: SummarizationType::ConversationSummary, .. - } if matches!( - summarization_type, - SummarizationType::ConversationSummary - ) => - { + } => { if let Some(summarization_view) = props.summarization_views.get(&output_message.id) { diff --git a/app/src/ai/blocklist/block/view_impl/query.rs b/app/src/ai/blocklist/block/view_impl/query.rs index 73ef3f99..c09a53e5 100644 --- a/app/src/ai/blocklist/block/view_impl/query.rs +++ b/app/src/ai/blocklist/block/view_impl/query.rs @@ -2,9 +2,9 @@ //! //! Queries are not rendered in blocks corresponding to requested command or requested action responses. -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors; +use pathfinder_color::ColorU; use warpui::elements::{ Container, CornerRadius, DispatchEventResult, EventHandler, Flex, MainAxisAlignment, MainAxisSize, ParentElement, Radius, Shrinkable, Wrap, diff --git a/app/src/ai/blocklist/block_tests.rs b/app/src/ai/blocklist/block_tests.rs index f6a7687c..b996dbca 100644 --- a/app/src/ai/blocklist/block_tests.rs +++ b/app/src/ai/blocklist/block_tests.rs @@ -3,9 +3,9 @@ use std::path::PathBuf; use ai::agent::action::{RunAgentsAgentRunConfig, RunAgentsExecutionMode}; use ai::agent::action_result::StartAgentVersion; use ai::skills::SkillReference; -use settings::Setting; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui::{App, SingletonEntity}; +use settings::Setting; use super::{ default_collapsible_state_for_orchestration_action, diff --git a/app/src/ai/blocklist/context_model.rs b/app/src/ai/blocklist/context_model.rs index 8a95f7fa..fc356e84 100644 --- a/app/src/ai/blocklist/context_model.rs +++ b/app/src/ai/blocklist/context_model.rs @@ -7,12 +7,11 @@ use std::sync::Arc; use ai::project_context::model::ProjectContextModel; use galaxy_core::features::FeatureFlag; -use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; -use parking_lot::FairMutex; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui::{ AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity, WeakModelHandle, }; +use parking_lot::FairMutex; use super::agent_view::{AgentViewEntryOrigin, EnterAgentViewError}; use super::block::DirectoryContext; diff --git a/app/src/ai/blocklist/controller.rs b/app/src/ai/blocklist/controller.rs index 716840d0..016dfd95 100644 --- a/app/src/ai/blocklist/controller.rs +++ b/app/src/ai/blocklist/controller.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! This module contains core business logic for Agent Mode, primarily sending input to an AI //! model and receiving output. //! @@ -8,7 +10,7 @@ mod pending_response_streams; pub mod response_stream; pub(super) mod shared_session; mod slash_command; -use std::collections::{HashMap, HashSet}; +use std::collections::{HashMap, HashSet, VecDeque}; #[cfg(not(target_family = "wasm"))] use std::path::PathBuf; use std::sync::Arc; @@ -17,13 +19,13 @@ use std::time::Duration; use ai::skills::SkillPathOrigin; use anyhow::anyhow; use chrono::{DateTime, Local}; +use galaxy_core::assertions::safe_assert; use input_context::{input_context_for_request, parse_context_attachments}; use itertools::Itertools; use parking_lot::FairMutex; use pending_response_streams::PendingResponseStreams; use session_sharing_protocol::common::ParticipantId; pub use slash_command::*; -use galaxy_core::assertions::safe_assert; use warp_multi_agent_api::{message, Task, ToolType}; use warpui::r#async::{SpawnedFutureHandle, Timer}; use warpui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; @@ -58,6 +60,7 @@ use crate::ai::document::ai_document_model::{ AIDocumentId, AIDocumentModel, AIDocumentUserEditStatus, }; use crate::ai::llms::{LLMId, LLMPreferences}; +use crate::ai::provider::types::ContentPart; use crate::ai::AIRequestUsageModel; use crate::cloud_object::model::persistence::CloudModel; use crate::features::FeatureFlag; @@ -1688,6 +1691,65 @@ impl BlocklistAIController { self.pending_passive_follow_ups.remove(&conversation_id); } + fn check_and_record_loop_detection( + &mut self, + conversation_id: AIConversationId, + results: &[AIAgentActionResult], + ) -> Option { + use std::hash::{Hash, Hasher}; + + let state = self.loop_detection.entry(conversation_id).or_default(); + let mut has_success = false; + + for result in results { + if result.result.is_failed() { + let discriminant = std::mem::discriminant(&result.result); + // Use a stable description that includes the tool type and the *input* + // (command, file paths, etc.) but NOT the variable output, so the same + // failing command with different output is still recognized as a loop. + let description = result.result.loop_description(); + + let mut hasher = std::collections::hash_map::DefaultHasher::new(); + discriminant.hash(&mut hasher); + description.hash(&mut hasher); + let input_hash = hasher.finish(); + + state.record_failure(LoopDetectionEntry { + tool_discriminant: discriminant, + input_hash, + description: description.clone(), + }); + } else if result.result.is_successful() { + has_success = true; + } + } + + // If we had at least one success in this batch, clear loop state — + // the agent is making progress. + if has_success { + state.clear(); + return None; + } + + // Check for loops + if let Some(looping_entry) = state.detect_loop() { + let warning = format!( + "[SYSTEM] Loop detected: the same action has failed {} or more times consecutively. \ + Do NOT repeat this action or any similar approach.\n\n\ + Failing action: {}\n\n\ + Take a completely different approach to accomplish the goal. \ + If you cannot find an alternative, explain to the user what is failing and why.", + LOOP_DETECTION_THRESHOLD, + looping_entry.description + ); + // Clear the state so we don't keep injecting on every subsequent turn + state.clear(); + Some(warning) + } else { + None + } + } + fn conversation_ready_for_pending_events( &self, conversation_id: AIConversationId, @@ -2766,7 +2828,7 @@ impl BlocklistAIController { .conversation(&conversation_id) .is_some_and(|c| c.status().is_in_progress()) { - let terminal_view_id = self.terminal_view_id; + let terminal_view_id = self.terminal_surface_id; history_model.update(ctx, |history_model, ctx| { if let Some(conversation) = history_model.conversation_mut(&conversation_id) { @@ -3288,7 +3350,7 @@ impl BlocklistAIController { ); history_model.update(ctx, |history_model, ctx| { history_model.update_conversation_status( - self.terminal_view_id, + self.terminal_surface_id, conversation_id, crate::ai::agent::conversation::ConversationStatus::Success, ctx, @@ -3605,28 +3667,41 @@ impl BlocklistAIController { conversation_id: AIConversationId, ctx: &mut ModelContext, ) { + use settings::Setting; + use crate::ai::bedrock::client::{BedrockClient, BedrockClientConfig}; use crate::ai::bedrock::convert::{ConversationMessage, MessageContent, MessageRole}; use crate::ai::bedrock::response_translator::{ context_window_for_model, estimate_cost_cents, }; use crate::settings::ai::AISettings; - use settings::Setting; let settings = AISettings::as_ref(ctx); if !*settings.bedrock_enabled.value() { return; } - let config = BedrockClientConfig { + let api_key_manager = ::ai::api_keys::ApiKeyManager::as_ref(ctx); + let mut config = BedrockClientConfig { auth_method: *settings.bedrock_auth_method.value(), profile: settings.bedrock_profile.value().clone(), region: settings.bedrock_region.value().clone(), access_key_id: settings.bedrock_access_key_id.value().clone(), secret_access_key: settings.bedrock_secret_access_key.value().clone(), + session_token: None, cross_region_inference: *settings.bedrock_cross_region_inference.value(), + }; + + if let ::ai::api_keys::AwsCredentialsState::Loaded { credentials, .. } = + api_key_manager.aws_credentials_state() + { + config.auth_method = crate::settings::BedrockAuthMethod::StaticKeys; + config.access_key_id = credentials.access_key().to_string(); + config.secret_access_key = credentials.secret_key().to_string(); + config.session_token = credentials.session_token().map(|s| s.to_string()); } - .with_external_fallbacks(); + + let config = config.with_external_fallbacks(); let cross_region = config.cross_region_inference; // Use Sonnet for summarization — cheaper and fast enough for this task @@ -3764,7 +3839,7 @@ impl BlocklistAIController { // Use the conversation's active model for context window sizing, // not the summarizer model. let active_model_id = crate::ai::llms::LLMPreferences::as_ref(ctx) - .get_active_base_model(ctx, Some(me.terminal_view_id)) + .get_active_base_model(ctx, Some(me.terminal_surface_id)) .id .to_string(); @@ -3838,7 +3913,7 @@ impl BlocklistAIController { }); // Update cost tracking - history_model.update(ctx, |history_model, _| { + history_model.update(ctx, |history_model, ctx| { use warp_multi_agent_api::response_event::stream_finished; let token_usage = vec![stream_finished::TokenUsage { model_id: "bedrock".to_string(), @@ -3854,6 +3929,7 @@ impl BlocklistAIController { token_usage, None, false, + ctx, ); }); } diff --git a/app/src/ai/blocklist/controller/input_context.rs b/app/src/ai/blocklist/controller/input_context.rs index 80f98f28..2ac54c0f 100644 --- a/app/src/ai/blocklist/controller/input_context.rs +++ b/app/src/ai/blocklist/controller/input_context.rs @@ -4,10 +4,10 @@ use std::sync::Arc; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; use chrono::Local; use galaxy_core::features::FeatureFlag; +use galaxy_graphql::generic_string_object::GenericStringObjectFormat as GraphQLFormat; use galaxyui::{AppContext, SingletonEntity}; use lazy_static::lazy_static; use regex::Regex; -use galaxy_graphql::generic_string_object::GenericStringObjectFormat as GraphQLFormat; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::{ diff --git a/app/src/ai/blocklist/controller/response_stream.rs b/app/src/ai/blocklist/controller/response_stream.rs index 2759011f..3f8dc820 100644 --- a/app/src/ai/blocklist/controller/response_stream.rs +++ b/app/src/ai/blocklist/controller/response_stream.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use std::cell::RefCell; use std::rc::Rc; use std::sync::Arc; @@ -6,15 +8,19 @@ use anyhow::anyhow; use chrono::{DateTime, Local, TimeDelta}; use futures::channel::oneshot; use galaxyui::{Entity, ModelContext, SingletonEntity}; +use settings::Setting; use uuid::Uuid; use warp_multi_agent_api::response_event; use crate::ai::agent::api::{self, generate_multi_agent_output, ConvertToAPITypeError}; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::{AIIdentifiers, CancellationReason}; +use crate::ai::bedrock::client::BedrockClientConfig; +use crate::ai::openai::client::OpenAIClientConfig; +use crate::ai::provider::ProviderConfig; use crate::network::NetworkStatus; use crate::server::server_api::{AIApiError, ServerApiProvider}; -use crate::{report_error, send_telemetry_from_ctx}; +use crate::{report_error, send_telemetry_from_ctx, AISettings}; /// Maximum number of times a single MAA request is re-sent before the failure is /// surfaced. @@ -165,6 +171,66 @@ impl ResponseStream { } } + fn resolve_provider_config(model_id: &str, ctx: &ModelContext) -> ProviderConfig { + let settings = AISettings::as_ref(ctx); + + // Check if OpenAI/LiteLLM provider is enabled + if *settings.openai_enabled.value() { + let base_url = settings.openai_base_url.value().clone(); + let api_key = { + let key = settings.openai_api_key.value().clone(); + if key.is_empty() { + None + } else { + Some(key) + } + }; + // Use the model override from settings if set, otherwise use the selected model ID. + // This allows LiteLLM models to pass through their actual model_id to the proxy. + let model = { + let m = settings.openai_model.value().clone(); + if m.is_empty() { + Some(model_id.to_string()) + } else { + Some(m) + } + }; + return ProviderConfig::OpenAI(OpenAIClientConfig { + base_url, + api_key, + model, + }); + } + + // Fall back to Bedrock + if *settings.bedrock_enabled.value() { + let auth_method = *settings.bedrock_auth_method.value(); + let api_key_manager = ::ai::api_keys::ApiKeyManager::as_ref(ctx); + let mut config = BedrockClientConfig { + auth_method, + profile: settings.bedrock_profile.value().clone(), + region: settings.bedrock_region.value().clone(), + access_key_id: settings.bedrock_access_key_id.value().clone(), + secret_access_key: settings.bedrock_secret_access_key.value().clone(), + session_token: None, + cross_region_inference: *settings.bedrock_cross_region_inference.value(), + }; + + if let ::ai::api_keys::AwsCredentialsState::Loaded { credentials, .. } = + api_key_manager.aws_credentials_state() + { + config.auth_method = crate::settings::BedrockAuthMethod::StaticKeys; + config.access_key_id = credentials.access_key().to_string(); + config.secret_access_key = credentials.secret_key().to_string(); + config.session_token = credentials.session_token().map(|s| s.to_string()); + } + + return ProviderConfig::Bedrock(config.with_external_fallbacks()); + } + + ProviderConfig::None + } + pub fn new( params: api::RequestParams, ai_identifiers: AIIdentifiers, @@ -176,10 +242,17 @@ impl ResponseStream { let request_id = Uuid::new_v4(); let provider_config = Self::resolve_provider_config(params.model.as_str(), ctx); + let server_api = ServerApiProvider::as_ref(ctx).get_ai_client().clone(); let params_clone = params.clone(); let _ = ctx.spawn( async move { - generate_multi_agent_output(provider_config, params_clone, cancellation_rx).await + generate_multi_agent_output( + provider_config, + server_api, + params_clone, + cancellation_rx, + ) + .await }, move |me, stream, ctx| { me.handle_response_stream_result(request_id, stream, ctx); @@ -260,15 +333,16 @@ impl ResponseStream { self.current_request_id = Some(request_id); let params = self.params.clone(); let provider_config = Self::resolve_provider_config(params.model.as_str(), ctx); - let _ = - ctx.spawn( - async move { - generate_multi_agent_output(provider_config, params, cancellation_rx).await - }, - move |me, stream, ctx| { - me.handle_response_stream_result(request_id, stream, ctx); - }, - ); + let server_api = ServerApiProvider::as_ref(ctx).get_ai_client().clone(); + let _ = ctx.spawn( + async move { + generate_multi_agent_output(provider_config, server_api, params, cancellation_rx) + .await + }, + move |me, stream, ctx| { + me.handle_response_stream_result(request_id, stream, ctx); + }, + ); } /// Cancels the stream. The conversation_id is preserved in the emitted event for async handling. diff --git a/app/src/ai/blocklist/controller/shared_session.rs b/app/src/ai/blocklist/controller/shared_session.rs index 4e467fa6..5bf079e6 100644 --- a/app/src/ai/blocklist/controller/shared_session.rs +++ b/app/src/ai/blocklist/controller/shared_session.rs @@ -451,7 +451,7 @@ impl BlocklistAIController { exchange.input.iter().any(|input| input.is_user_query()); if let Some(output) = exchange.output_status.output() { - actions_to_queue.extend(output.get().actions().cloned().collect_vec().into_iter()); + actions_to_queue.extend(output.get().actions().cloned().collect_vec()); } } diff --git a/app/src/ai/blocklist/controller/slash_command.rs b/app/src/ai/blocklist/controller/slash_command.rs index 731ef4bc..da703d4f 100644 --- a/app/src/ai/blocklist/controller/slash_command.rs +++ b/app/src/ai/blocklist/controller/slash_command.rs @@ -41,6 +41,9 @@ pub enum SlashCommandRequest { skill: ai::skills::ParsedSkill, user_query: Option, }, + Summarize { + prompt: Option, + }, } impl SlashCommandRequest { @@ -106,7 +109,7 @@ impl SlashCommandRequest { ctx, ); let entrypoint = self.entrypoint(); - let is_summarize = matches!(self, Self::Summarize { .. }); + let _is_summarize = matches!(self, Self::Summarize { .. }); let inputs = self.input( context, prompt_files, @@ -300,7 +303,8 @@ impl SlashCommandRequest { SlashCommandRequest::CreateNewProject { .. } | SlashCommandRequest::CreateEnvironment { .. } | SlashCommandRequest::FetchReviewComments { .. } - | SlashCommandRequest::InvokeSkill { .. } => EntrypointType::UserInitiated, + | SlashCommandRequest::InvokeSkill { .. } + | SlashCommandRequest::Summarize { .. } => EntrypointType::UserInitiated, } } } diff --git a/app/src/ai/blocklist/handoff/touched_repos.rs b/app/src/ai/blocklist/handoff/touched_repos.rs index fbc86e91..275f12d8 100644 --- a/app/src/ai/blocklist/handoff/touched_repos.rs +++ b/app/src/ai/blocklist/handoff/touched_repos.rs @@ -170,15 +170,10 @@ async fn git_origin_url(git_root: &Path) -> Option { /// matching the env-creation flow). fn parse_github_repo(remote_url: &str) -> Option { let trimmed = remote_url.trim(); - let path_part = if let Some(rest) = trimmed.strip_prefix("git@github.com:") { - rest - } else if let Some(rest) = trimmed.strip_prefix("https://github.com/") { - rest - } else if let Some(rest) = trimmed.strip_prefix("ssh://git@github.com/") { - rest - } else { - return None; - }; + let path_part = None + .or_else(|| trimmed.strip_prefix("git@github.com:")) + .or_else(|| trimmed.strip_prefix("https://github.com/")) + .or_else(|| trimmed.strip_prefix("ssh://git@github.com/"))?; let path_part = path_part.strip_suffix(".git").unwrap_or(path_part); let mut segments = path_part.splitn(2, '/'); diff --git a/app/src/ai/blocklist/history_model.rs b/app/src/ai/blocklist/history_model.rs index 1ea7c5f0..7a966427 100644 --- a/app/src/ai/blocklist/history_model.rs +++ b/app/src/ai/blocklist/history_model.rs @@ -8,11 +8,11 @@ use anyhow::anyhow; use chrono::{DateTime, Local, NaiveDateTime}; #[cfg(feature = "local_fs")] use diesel::SqliteConnection; +use galaxy_core::features::FeatureFlag; use itertools::Itertools as _; use serde::{Deserialize, Serialize}; use uuid::Uuid; use warp_cli::agent::Harness; -use galaxy_core::features::FeatureFlag; use warp_multi_agent_api::client_action::{Action, StartNewConversation}; use warp_multi_agent_api::response_event::stream_finished::{ ConversationUsageMetadata, TokenUsage, @@ -1525,6 +1525,10 @@ impl BlocklistAIHistoryModel { autoexecute_override: Some(source_conversation.autoexecute_override().into()), last_event_sequence: None, pinned: false, + progressive_summary: source_conversation + .progressive_summary() + .map(|s| s.to_string()), + messages_summarized_up_to: source_conversation.messages_summarized_up_to(), }; let forked_conversation_id = AIConversationId::new(); if let Err(e) = sqlite_sender.send(ModelEvent::UpdateMultiAgentConversation { @@ -1684,6 +1688,8 @@ impl BlocklistAIHistoryModel { autoexecute_override: Some(conversation.autoexecute_override().into()), last_event_sequence: None, pinned: false, + progressive_summary: conversation.progressive_summary().map(|s| s.to_string()), + messages_summarized_up_to: conversation.messages_summarized_up_to(), }; let forked_conversation_id = AIConversationId::new(); @@ -2698,6 +2704,10 @@ fn merged_remote_child_placeholder_conversation_data( reverted_action_ids: None, root_task_is_optimistic: None, autoexecute_override: None, + progressive_summary: cloud_conversation + .progressive_summary() + .map(|s| s.to_string()), + messages_summarized_up_to: cloud_conversation.messages_summarized_up_to(), } } diff --git a/app/src/ai/blocklist/history_model_tests.rs b/app/src/ai/blocklist/history_model_tests.rs index 7bf24062..0b2387eb 100644 --- a/app/src/ai/blocklist/history_model_tests.rs +++ b/app/src/ai/blocklist/history_model_tests.rs @@ -38,6 +38,7 @@ use crate::persistence::ModelEvent; use crate::server::ids::ServerId; use crate::server::telemetry::context_provider::AppTelemetryContextProvider; use crate::terminal::model::session::SessionId; +use crate::test_util::ai_agent_tasks::{create_api_task, create_message}; use crate::test_util::settings::{ initialize_history_persistence_for_tests, initialize_settings_for_tests, }; @@ -626,6 +627,7 @@ fn test_initialize_historical_conversations_resolves_parent_agent_id_children_vi autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, now, None, @@ -648,6 +650,7 @@ fn test_initialize_historical_conversations_resolves_parent_agent_id_children_vi autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, now - chrono::Duration::seconds(1), Some("Parent query"), @@ -698,6 +701,7 @@ fn test_initialize_historical_conversations_uses_root_task_description_title() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }) .expect("conversation data should serialize"), last_modified_at: now, @@ -762,6 +766,7 @@ fn test_initialize_historical_conversations_eagerly_hydrates_orchestration_child autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, now, // Child needs at least one root task so `AIConversation::new_restored` succeeds. @@ -785,6 +790,7 @@ fn test_initialize_historical_conversations_eagerly_hydrates_orchestration_child autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, now - chrono::Duration::seconds(1), Some("Parent query"), @@ -1081,6 +1087,7 @@ fn create_server_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }; ServerAIConversationMetadata { @@ -1229,7 +1236,6 @@ fn test_merge_cloud_metadata_updates_already_restored_conversations() { #[test] fn test_merge_cloud_metadata_refreshes_stale_restored_conversation_metadata() { - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); let terminal_view_id = EntityId::new(); @@ -1277,7 +1283,6 @@ fn test_merge_cloud_metadata_refreshes_stale_restored_conversation_metadata() { #[test] fn test_merge_cloud_metadata_reuses_restored_conversation_id_for_token() { - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); let terminal_view_id = EntityId::new(); @@ -1685,7 +1690,6 @@ fn test_child_conversation_ids_of_unknown_parent() { #[test] fn test_restore_conversations_maintains_children_by_parent() { - App::test((), |mut app| async move { let terminal_view_id = EntityId::new(); let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1707,7 +1711,6 @@ fn test_restore_conversations_maintains_children_by_parent() { #[test] fn test_restore_conversations_indexes_child_by_parent_agent_id() { - App::test((), |mut app| async move { let terminal_view_id = EntityId::new(); let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1738,7 +1741,6 @@ fn test_restore_conversations_indexes_child_by_parent_agent_id() { #[test] fn test_restore_conversations_dedup_children_by_parent() { - App::test((), |mut app| async move { let terminal_view_id = EntityId::new(); let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -2284,7 +2286,6 @@ fn test_optimistic_root_restore_round_trip_yields_in_progress_optimistic_root() /// (the synthesized optimistic root no longer produces a stub). #[test] fn test_truncate_from_exchange_to_empty_persist_event_has_empty_updated_tasks() { - App::test((), |mut app| async move { initialize_settings_for_tests(&mut app); @@ -2390,7 +2391,6 @@ fn test_truncate_from_exchange_to_empty_persist_event_has_empty_updated_tasks() /// with the server id and no orphan optimistic tasks. #[test] fn test_two_restart_cycles_keep_exactly_one_server_root_task_row() { - App::test((), |mut app| async move { initialize_settings_for_tests(&mut app); @@ -2698,7 +2698,6 @@ fn test_find_by_token_after_merge_cloud_metadata() { #[test] fn test_find_by_token_after_restore_conversations() { - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); let terminal_view_id = EntityId::new(); @@ -2925,6 +2924,7 @@ fn test_find_by_token_after_insert_forked_conversation_from_tasks() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }; let tasks = vec![warp_multi_agent_api::Task { id: "root-task".to_string(), @@ -2957,7 +2957,6 @@ fn test_find_by_token_after_insert_forked_conversation_from_tasks() { #[test] fn test_find_by_token_after_mark_conversations_historical_for_terminal_surface() { - App::test((), |mut app| async move { let now = Local::now(); let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -3117,6 +3116,7 @@ fn test_fork_then_bind_handoff_token_resolves_to_forked_conversation() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("restored source conversation should build"); @@ -3165,7 +3165,6 @@ fn test_fork_then_bind_handoff_token_resolves_to_forked_conversation() { #[test] fn test_fork_then_bind_handoff_token_persists_to_restored_conversation() { - App::test((), |mut app| async move { initialize_settings_for_tests(&mut app); @@ -3201,6 +3200,7 @@ fn test_fork_then_bind_handoff_token_persists_to_restored_conversation() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("restored source conversation should build"); @@ -3266,7 +3266,6 @@ fn test_fork_then_bind_handoff_token_persists_to_restored_conversation() { #[test] fn test_fork_then_bind_handoff_token_updates_cached_metadata_and_emits_refresh_events() { - App::test((), |mut app| async move { initialize_settings_for_tests(&mut app); @@ -3310,6 +3309,7 @@ fn test_fork_then_bind_handoff_token_updates_cached_metadata_and_emits_refresh_e autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("restored source conversation should build"); @@ -3436,6 +3436,7 @@ fn test_fork_conversation_preserves_task_ids_when_requested() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("restored source conversation should build"); @@ -3498,7 +3499,6 @@ fn setup_app_for_history_model_tests(app: &mut App) { /// in-progress-ready state. #[test] fn test_new_conversation_does_not_inherit_waiting_for_events() { - App::test((), |mut app| async move { setup_app_for_history_model_tests(&mut app); let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new_for_test()); @@ -3545,7 +3545,6 @@ fn test_new_conversation_does_not_inherit_waiting_for_events() { #[test] fn test_fork_conversation_title_override_replaces_prefix() { - App::test((), |mut app| async move { initialize_settings_for_tests(&mut app); @@ -3582,6 +3581,7 @@ fn test_fork_conversation_title_override_replaces_prefix() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("restored source conversation should build"); @@ -3671,6 +3671,7 @@ fn hydrate_remote_child_placeholder_with_cloud_transcript_preserves_placeholder_ autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("placeholder conversation should build"); @@ -3717,6 +3718,7 @@ fn hydrate_remote_child_placeholder_with_cloud_transcript_preserves_placeholder_ autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }), ) .expect("cloud conversation should build"); diff --git a/app/src/ai/blocklist/inline_action/ask_user_question_view.rs b/app/src/ai/blocklist/inline_action/ask_user_question_view.rs index f542f8c2..38a6193f 100644 --- a/app/src/ai/blocklist/inline_action/ask_user_question_view.rs +++ b/app/src/ai/blocklist/inline_action/ask_user_question_view.rs @@ -4,9 +4,8 @@ use std::time::Duration; use ai::agent::action::{AskUserQuestionItem, AskUserQuestionOption, AskUserQuestionType}; use ai::agent::action_result::{AskUserQuestionAnswerItem, AskUserQuestionResult}; -use itertools::Itertools; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::{GalaxyTheme, WarpTheme}; use galaxyui::elements::new_scrollable::SingleAxisConfig; use galaxyui::elements::{ Border, ChildView, Clipped, ClippedScrollStateHandle, ConstrainedBox, Container, CornerRadius, @@ -24,6 +23,7 @@ use galaxyui::{ LayoutContext, ModelHandle, PaintContext, SingletonEntity, SizeConstraint, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::icons::yellow_stop_icon; diff --git a/app/src/ai/blocklist/inline_action/code_diff_view.rs b/app/src/ai/blocklist/inline_action/code_diff_view.rs index 703a4848..651f1176 100644 --- a/app/src/ai/blocklist/inline_action/code_diff_view.rs +++ b/app/src/ai/blocklist/inline_action/code_diff_view.rs @@ -10,11 +10,6 @@ use ai::diff_validation::{ SearchAndReplace, V4AHunk, }; use anyhow::Result; -use lazy_static::lazy_static; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_geometry::vector::vec2f; -use rand::distributions::Alphanumeric; -use rand::{thread_rng, Rng as _}; use galaxy_core::features::FeatureFlag; use galaxy_core::platform::SessionPlatform; use galaxy_core::settings::ToggleableSetting; @@ -46,14 +41,11 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; -use rand::{distributions::Alphanumeric, thread_rng, Rng as _}; -use std::{ - collections::HashMap, - path::{Path, PathBuf}, - rc::Rc, - sync::Arc, - time::Duration, -}; +use lazy_static::lazy_static; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_geometry::vector::vec2f; +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng as _}; use super::malformed_line_heuristics::has_malformed_terminal_correction_signal; use crate::ai::agent::icons::{self, yellow_stop_icon}; diff --git a/app/src/ai/blocklist/inline_action/host_picker.rs b/app/src/ai/blocklist/inline_action/host_picker.rs index 1b499755..e193381d 100644 --- a/app/src/ai/blocklist/inline_action/host_picker.rs +++ b/app/src/ai/blocklist/inline_action/host_picker.rs @@ -327,10 +327,8 @@ impl HostPicker { match event { EditorEvent::Enter => self.commit_custom(ctx), EditorEvent::Escape => self.cancel_custom(ctx), - EditorEvent::Blurred => { - if self.is_custom_mode { - self.commit_custom(ctx); - } + EditorEvent::Blurred if self.is_custom_mode => { + self.commit_custom(ctx); } _ => {} } diff --git a/app/src/ai/blocklist/inline_action/inline_action_header.rs b/app/src/ai/blocklist/inline_action/inline_action_header.rs index 945425d2..7ca618e8 100644 --- a/app/src/ai/blocklist/inline_action/inline_action_header.rs +++ b/app/src/ai/blocklist/inline_action/inline_action_header.rs @@ -1,9 +1,9 @@ use std::borrow::Cow; use std::rc::Rc; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; +use pathfinder_color::ColorU; use warpui::elements::{ Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, EventHandler, Expanded, Flex, FormattedTextElement, Hoverable, MainAxisAlignment, MainAxisSize, diff --git a/app/src/ai/blocklist/inline_action/orchestration_controls.rs b/app/src/ai/blocklist/inline_action/orchestration_controls.rs index 8027b526..86eb6bd7 100644 --- a/app/src/ai/blocklist/inline_action/orchestration_controls.rs +++ b/app/src/ai/blocklist/inline_action/orchestration_controls.rs @@ -10,11 +10,11 @@ use std::collections::HashMap; use ai::agent::action::RunAgentsExecutionMode; use ai::agent::orchestration_config::{OrchestrationConfig, OrchestrationExecutionMode}; +use galaxy_core::ui::theme::Fill; use pathfinder_color::ColorU; use pathfinder_geometry::vector::{vec2f, Vector2F}; use settings::Setting; use warp_cli::agent::Harness; -use galaxy_core::ui::theme::Fill; use warpui::elements::{ Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Expanded, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, diff --git a/app/src/ai/blocklist/inline_action/requested_action.rs b/app/src/ai/blocklist/inline_action/requested_action.rs index e013f918..1826099b 100644 --- a/app/src/ai/blocklist/inline_action/requested_action.rs +++ b/app/src/ai/blocklist/inline_action/requested_action.rs @@ -11,9 +11,6 @@ use std::borrow::Cow; -use lazy_static::lazy_static; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors::neutral_2; use galaxyui::elements::{ @@ -23,6 +20,9 @@ use galaxyui::elements::{ use galaxyui::fonts::FamilyId; use galaxyui::keymap::Keystroke; use galaxyui::{AppContext, Element, SingletonEntity}; +use lazy_static::lazy_static; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; use super::inline_action_header::HeaderConfig; use crate::ai::blocklist::block::view_impl::WithContentItemSpacing; diff --git a/app/src/ai/blocklist/inline_action/requested_command.rs b/app/src/ai/blocklist/inline_action/requested_command.rs index f48f8aeb..26f4063b 100644 --- a/app/src/ai/blocklist/inline_action/requested_command.rs +++ b/app/src/ai/blocklist/inline_action/requested_command.rs @@ -4,10 +4,6 @@ use std::collections::HashMap; use std::rc::Rc; use std::sync::Arc; -use lazy_static::lazy_static; -use parking_lot::FairMutex; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::Icon; use galaxy_editor::render::element::VerticalExpansionBehavior; @@ -22,6 +18,10 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, EventContext, ModelHandle, SingletonEntity, TypedActionView, UpdateView, View, ViewContext, ViewHandle, }; +use lazy_static::lazy_static; +use parking_lot::FairMutex; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; use super::inline_action_icons::{self, icon_size}; use crate::ai::agent::conversation::ConversationStatus; diff --git a/app/src/ai/blocklist/inline_action/requested_command_attribution.rs b/app/src/ai/blocklist/inline_action/requested_command_attribution.rs index 6a31f47d..36cb8f80 100644 --- a/app/src/ai/blocklist/inline_action/requested_command_attribution.rs +++ b/app/src/ai/blocklist/inline_action/requested_command_attribution.rs @@ -1,8 +1,8 @@ //! Module to attribute AI-generated requested commands //! to known documents (e.g. Warp Drive objects). -use markdown_parser::{parse_markdown, FormattedTextLine}; use galaxyui::{AppContext, SingletonEntity}; +use markdown_parser::{parse_markdown, FormattedTextLine}; use crate::ai::agent::AIAgentCitation; use crate::cloud_object::model::persistence::CloudModel; diff --git a/app/src/ai/blocklist/inline_action/run_agents_card_view.rs b/app/src/ai/blocklist/inline_action/run_agents_card_view.rs index bd66d1e2..847468b8 100644 --- a/app/src/ai/blocklist/inline_action/run_agents_card_view.rs +++ b/app/src/ai/blocklist/inline_action/run_agents_card_view.rs @@ -10,8 +10,8 @@ use ai::agent::action::{RunAgentsAgentRunConfig, RunAgentsExecutionMode, RunAgen use ai::agent::action_result::{RunAgentsAgentOutcomeKind, RunAgentsResult}; use ai::agent::orchestration_config::{OrchestrationConfig, OrchestrationConfigStatus}; use ai::skills::SkillReference; -use pathfinder_geometry::vector::vec2f; use galaxy_core::send_telemetry_from_ctx; +use pathfinder_geometry::vector::vec2f; use warpui::elements::{ Border, ChildAnchor, ChildView, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Radius, Stack, Text, Wrap, diff --git a/app/src/ai/blocklist/inline_action/run_agents_card_view_tests.rs b/app/src/ai/blocklist/inline_action/run_agents_card_view_tests.rs index f7da65fd..be8876b5 100644 --- a/app/src/ai/blocklist/inline_action/run_agents_card_view_tests.rs +++ b/app/src/ai/blocklist/inline_action/run_agents_card_view_tests.rs @@ -373,9 +373,11 @@ mod format_terminal_state_tests { } mod override_from_approved_config_tests { + use ai::agent::action::RunAgentsExecutionMode; use ai::agent::orchestration_config::{OrchestrationConfig, OrchestrationExecutionMode}; use super::super::RunAgentsEditState; + use super::*; fn local_config(model: &str, harness: &str) -> OrchestrationConfig { OrchestrationConfig { diff --git a/app/src/ai/blocklist/inline_action/suggested_unit_tests.rs b/app/src/ai/blocklist/inline_action/suggested_unit_tests.rs index c1862e00..d7f61f77 100644 --- a/app/src/ai/blocklist/inline_action/suggested_unit_tests.rs +++ b/app/src/ai/blocklist/inline_action/suggested_unit_tests.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use rand::distributions::Alphanumeric; -use rand::{thread_rng, Rng as _}; use galaxy_core::settings::ToggleableSetting; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ @@ -15,7 +12,9 @@ use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, }; -use rand::{distributions::Alphanumeric, thread_rng, Rng as _}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng as _}; use crate::ai::agent::{AIAgentActionId, AIIdentifiers}; use crate::ai::predict::prompt_suggestions::{ diff --git a/app/src/ai/blocklist/inline_action/summarization.rs b/app/src/ai/blocklist/inline_action/summarization.rs index d7fca5ba..527bb5a7 100644 --- a/app/src/ai/blocklist/inline_action/summarization.rs +++ b/app/src/ai/blocklist/inline_action/summarization.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::shimmering_text::{ ShimmerConfig, ShimmeringTextElement, ShimmeringTextStateHandle, @@ -9,7 +11,6 @@ use galaxyui::elements::{ use galaxyui::r#async::{SpawnedFutureHandle, Timer}; use galaxyui::{AppContext, Entity, SingletonEntity, View, ViewContext}; use instant::Instant; -use std::time::Duration; use super::inline_action_header::{ INLINE_ACTION_HEADER_VERTICAL_PADDING, INLINE_ACTION_HORIZONTAL_PADDING, diff --git a/app/src/ai/blocklist/input_model.rs b/app/src/ai/blocklist/input_model.rs index c513fd70..8a0a4486 100644 --- a/app/src/ai/blocklist/input_model.rs +++ b/app/src/ai/blocklist/input_model.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use futures::stream::AbortHandle; +use galaxy_completer::completer::CompletionContext; use galaxy_core::features::FeatureFlag; use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use input_classifier::util::{is_agent_follow_up_input, is_one_off_natural_language_word}; @@ -17,7 +18,6 @@ use parking_lot::FairMutex; use serde::{Deserialize, Serialize}; use session_sharing_protocol::common::{InputMode, InputType as ProtocolInputType}; use settings::Setting as _; -use galaxy_completer::completer::CompletionContext; /// The source of the final input type decision applied to the user input. #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/app/src/ai/blocklist/orchestration_event_streamer.rs b/app/src/ai/blocklist/orchestration_event_streamer.rs index a3a59937..70f5cd5f 100644 --- a/app/src/ai/blocklist/orchestration_event_streamer.rs +++ b/app/src/ai/blocklist/orchestration_event_streamer.rs @@ -1,3 +1,5 @@ +#![allow(deprecated, dead_code)] + use std::collections::{HashMap, HashSet, VecDeque}; use std::sync::Arc; use std::time::Duration; @@ -5,14 +7,14 @@ use std::time::Duration; use anyhow::anyhow; use async_trait::async_trait; use futures::channel::mpsc; -use uuid::Uuid; use galaxy_cli::agent::Harness; use galaxy_core::features::FeatureFlag; -use warp_multi_agent_api as api; use galaxyui::r#async::{SpawnedFutureHandle, Timer}; use galaxyui::{ Entity, EntityId, GetSingletonModelHandle, ModelContext, SingletonEntity, UpdateModel, }; +use uuid::Uuid; +use warp_multi_agent_api as api; use super::history_model::{BlocklistAIHistoryEvent, BlocklistAIHistoryModel}; use super::orchestration_events::{ diff --git a/app/src/ai/blocklist/orchestration_event_streamer_tests.rs b/app/src/ai/blocklist/orchestration_event_streamer_tests.rs index ccdfa794..d4d41e37 100644 --- a/app/src/ai/blocklist/orchestration_event_streamer_tests.rs +++ b/app/src/ai/blocklist/orchestration_event_streamer_tests.rs @@ -1,7 +1,8 @@ use std::sync::Arc; -use mockall::predicate::eq; +use chrono::Utc; use galaxy_core::features::FeatureFlag; +use mockall::predicate::eq; use warpui::App; use super::*; @@ -162,6 +163,7 @@ fn ai_conversation_new_restored_preserves_last_event_sequence() { autoexecute_override: None, last_event_sequence: Some(42), pinned: false, + ..Default::default() }; let conversation = AIConversation::new_restored(AIConversationId::new(), vec![task], Some(data)) @@ -221,7 +223,6 @@ fn make_ambient_task_with_task_id( fn make_server_metadata_with_harness( harness: AIAgentHarness, ) -> crate::ai::agent::conversation::ServerAIConversationMetadata { - use crate::ai::agent::api::ServerConversationToken; use crate::cloud_object::{Revision, ServerMetadata, ServerPermissions}; use crate::persistence::model::ConversationUsageMetadata; @@ -240,6 +241,7 @@ fn make_server_metadata_with_harness( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: ServerMetadata { uid: ServerId::default(), @@ -262,9 +264,6 @@ fn make_server_metadata_with_harness( #[test] fn dormant_local_claude_child_skips_generic_sse_but_allows_wake_listener() { - - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -317,9 +316,6 @@ fn dormant_local_claude_child_skips_generic_sse_but_allows_wake_listener() { #[test] fn persist_event_cursor_keeps_the_max_sequence_and_updates_history_model() { - - - App::test((), |mut app| async move { initialize_settings_for_tests(&mut app); let (sender, receiver) = std::sync::mpsc::sync_channel::(4); @@ -378,8 +374,6 @@ fn persist_event_cursor_keeps_the_max_sequence_and_updates_history_model() { #[test] fn wake_ready_does_not_advance_cursor_before_wake_preparation() { - - use crate::ai::agent::conversation::AIConversation; use crate::ai::agent_events::AgentMessageEventMetadata; use crate::server::server_api::ai::{AIClient, MockAIClient}; @@ -438,10 +432,8 @@ fn wake_ready_does_not_advance_cursor_before_wake_preparation() { #[test] fn dormant_local_claude_child_uses_task_harness_when_server_metadata_missing() { - use warp_cli::agent::Harness; - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -562,9 +554,6 @@ async fn dormant_claude_wake_consumer_stops_on_first_target_event() { #[test] fn restored_conversations_initialize_v2_streaming_state() { - - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -643,9 +632,6 @@ async fn sse_forwarding_consumer_skips_message_hydration_when_disabled() { } #[test] fn finish_restore_fetch_uses_server_cursor_when_sqlite_is_absent() { - - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -697,9 +683,6 @@ fn finish_restore_fetch_uses_server_cursor_when_sqlite_is_absent() { #[test] fn handle_event_batch_persists_max_seq_to_history_model() { - - - App::test((), |mut app| async move { // `update_event_sequence` calls `write_updated_conversation_state`, // which reads `GeneralSettings`, `AppExecutionMode`, and the global @@ -922,8 +905,6 @@ fn finish_restore_fetch_no_ops_when_conversation_deleted_mid_flight() { // uses the missing entry as a sentinel and must not re-populate // streamer state for the deleted conversation. - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -986,8 +967,6 @@ fn finish_restore_fetch_err_does_not_resurrect_deleted_conversation() { // defeat the deletion sentinel inside the retry timer and cause an // indefinite retry loop). - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1046,8 +1025,6 @@ fn on_conversation_removed_prunes_stale_child_run_id_from_parent() { // model after the removal, which always returned `None` because the // history model emits `RemoveConversation` after dropping the record. - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1099,9 +1076,6 @@ fn on_conversation_removed_prunes_stale_child_run_id_from_parent() { #[test] fn on_conversation_removed_prunes_killed_child_run_id_from_parent_but_keeps_tombstone() { - - - App::test((), |mut app| async move { app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1447,7 +1421,6 @@ fn viewer_mode_consumer_refcount_handles_multiple_panes_and_double_unregister() #[test] fn is_remote_run_view_excludes_shared_session_viewer() { - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1479,7 +1452,6 @@ fn is_remote_run_view_excludes_shared_session_viewer() { #[test] fn is_remote_run_view_excludes_remote_child() { - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); @@ -1590,8 +1562,6 @@ fn finish_restore_fetch_reconnects_sse_when_children_added_to_open_connection() // before children are known, finish_restore_fetch must reconnect SSE // with the updated run_id set rather than leaving children unwatched. - - App::test((), |mut app| async move { let history_model = app.add_singleton_model(|_| BlocklistAIHistoryModel::new(vec![], &[])); diff --git a/app/src/ai/blocklist/orchestration_events.rs b/app/src/ai/blocklist/orchestration_events.rs index 433a0434..3a809d64 100644 --- a/app/src/ai/blocklist/orchestration_events.rs +++ b/app/src/ai/blocklist/orchestration_events.rs @@ -1,5 +1,8 @@ +#![allow(dead_code)] + use std::collections::{HashMap, HashSet}; +use uuid::Uuid; use warp_multi_agent_api as api; use warpui::{Entity, ModelContext, SingletonEntity}; diff --git a/app/src/ai/blocklist/passive_suggestions/legacy.rs b/app/src/ai/blocklist/passive_suggestions/legacy.rs index c99437c8..0f942aaf 100644 --- a/app/src/ai/blocklist/passive_suggestions/legacy.rs +++ b/app/src/ai/blocklist/passive_suggestions/legacy.rs @@ -7,9 +7,9 @@ use std::time::Duration; use chrono::Utc; #[cfg(not(target_family = "wasm"))] use command::r#async::Command; +use galaxy_core::features::FeatureFlag; use parking_lot::FairMutex; use serde_json::json; -use galaxy_core::features::FeatureFlag; use warpui::r#async::{FutureExt as AsyncFutureExt, SpawnedFutureHandle, Timer}; use warpui::{Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; diff --git a/app/src/ai/blocklist/passive_suggestions/maa.rs b/app/src/ai/blocklist/passive_suggestions/maa.rs index 696b4dba..71d5b974 100644 --- a/app/src/ai/blocklist/passive_suggestions/maa.rs +++ b/app/src/ai/blocklist/passive_suggestions/maa.rs @@ -5,8 +5,8 @@ use std::sync::Arc; use ai::agent::action::{AIAgentActionType, FileEdit}; use ai::diff_validation::ParsedDiff; use chrono::{DateTime, Utc}; -use parking_lot::FairMutex; use galaxy_core::features::FeatureFlag; +use parking_lot::FairMutex; use warpui::r#async::SpawnedFutureHandle; use warpui::{Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; @@ -559,9 +559,10 @@ fn coalesce_messages_from_client_actions( use std::collections::HashMap; use field_mask::FieldMaskOperation; + use warp_multi_agent_api as api; use warp_multi_agent_api::client_action::Action; - let mut messages_by_id: HashMap = HashMap::new(); + let mut messages_by_id: HashMap = HashMap::new(); let mut message_order: Vec = Vec::new(); for action in client_actions { diff --git a/app/src/ai/blocklist/permissions.rs b/app/src/ai/blocklist/permissions.rs index 498c713c..e6930cf2 100644 --- a/app/src/ai/blocklist/permissions.rs +++ b/app/src/ai/blocklist/permissions.rs @@ -2,16 +2,14 @@ use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use anyhow::Result; -use galaxy_completer::parsers::simple::decompose_command; -use galaxy_core::user_preferences::GetUserPreferences; -use galaxy_core::{features::FeatureFlag, settings::Setting}; -use galaxy_util::path::EscapeChar; -use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity}; -use serde::{Deserialize, Serialize}; use galaxy_completer::parsers::simple::{command_without_leading_env_vars, decompose_command}; use galaxy_core::execution_mode::AppExecutionMode; use galaxy_core::features::FeatureFlag; use galaxy_core::settings::Setting; +use galaxy_core::user_preferences::GetUserPreferences; +use galaxy_util::path::EscapeChar; +use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity}; +use serde::{Deserialize, Serialize}; use super::BlocklistAIHistoryModel; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/ai/blocklist/permissions_tests.rs b/app/src/ai/blocklist/permissions_tests.rs index 3a5fa446..46bf4523 100644 --- a/app/src/ai/blocklist/permissions_tests.rs +++ b/app/src/ai/blocklist/permissions_tests.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; -use uuid::Uuid; use galaxy_core::execution_mode::ExecutionMode; use galaxy_util::path::EscapeChar; use galaxyui::{App, EntityId, ModelHandle}; +use uuid::Uuid; use super::{BlocklistAIHistoryModel, BlocklistAIPermissions}; use crate::ai::active_agent_views_model::ActiveAgentViewsModel; diff --git a/app/src/ai/blocklist/prompt/plan_and_todo_list.rs b/app/src/ai/blocklist/prompt/plan_and_todo_list.rs index 82b988c5..6c9dca18 100644 --- a/app/src/ai/blocklist/prompt/plan_and_todo_list.rs +++ b/app/src/ai/blocklist/prompt/plan_and_todo_list.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -17,6 +16,7 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::ai::agent::icons::todo_list_icon; use crate::ai::agent::todos::popup::{AgentTodosPopupEvent, AgentTodosPopupView}; diff --git a/app/src/ai/blocklist/prompt/prompt_alert.rs b/app/src/ai/blocklist/prompt/prompt_alert.rs index ebfc6739..56291550 100644 --- a/app/src/ai/blocklist/prompt/prompt_alert.rs +++ b/app/src/ai/blocklist/prompt/prompt_alert.rs @@ -1,11 +1,11 @@ use ai::api_keys::ApiKeyManager; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, FormattedTextElement, HighlightedHyperlink, HyperlinkLens, MainAxisAlignment, MainAxisSize, ParentElement, }; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use crate::ai::blocklist::error_color; use crate::ai::AIRequestUsageModel; diff --git a/app/src/ai/blocklist/queued_query.rs b/app/src/ai/blocklist/queued_query.rs index b268bd54..05063a2b 100644 --- a/app/src/ai/blocklist/queued_query.rs +++ b/app/src/ai/blocklist/queued_query.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; -use uuid::Uuid; use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity}; +use uuid::Uuid; use crate::ai::agent::conversation::AIConversationId; use crate::ai::blocklist::{BlocklistAIHistoryEvent, BlocklistAIHistoryModel, PendingAttachment}; diff --git a/app/src/ai/blocklist/suggested_agent_mode_workflow_modal.rs b/app/src/ai/blocklist/suggested_agent_mode_workflow_modal.rs index b84361eb..4946970f 100644 --- a/app/src/ai/blocklist/suggested_agent_mode_workflow_modal.rs +++ b/app/src/ai/blocklist/suggested_agent_mode_workflow_modal.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use std::default::Default; use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ @@ -15,7 +14,7 @@ use galaxyui::ui_components::components::{Coords, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; -use std::{collections::HashMap, default::Default, sync::Arc}; +use pathfinder_geometry::vector::vec2f; use crate::ai::agent::SuggestedAgentModeWorkflow; use crate::modal::{Modal, ModalEvent}; diff --git a/app/src/ai/blocklist/suggested_rule_modal.rs b/app/src/ai/blocklist/suggested_rule_modal.rs index 43ab3609..3f7636a7 100644 --- a/app/src/ai/blocklist/suggested_rule_modal.rs +++ b/app/src/ai/blocklist/suggested_rule_modal.rs @@ -1,5 +1,5 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; +use pathfinder_geometry::vector::vec2f; use warp_editor::editor::NavigationKey; use warpui::elements::{ Align, Border, ChildAnchor, ChildView, ClippedScrollStateHandle, ClippedScrollable, diff --git a/app/src/ai/blocklist/suggestion_chip_view.rs b/app/src/ai/blocklist/suggestion_chip_view.rs index 5fbdd3d1..915c1e7a 100644 --- a/app/src/ai/blocklist/suggestion_chip_view.rs +++ b/app/src/ai/blocklist/suggestion_chip_view.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; @@ -6,6 +5,7 @@ use galaxyui::elements::{Align, ChildView, Container, ParentElement, SavePositio use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use super::suggested_agent_mode_workflow_modal::SuggestedAgentModeWorkflowAndId; use super::suggested_rule_modal::SuggestedRuleAndId; @@ -312,12 +312,10 @@ impl SuggestionChipView { | CloudModelEvent::ObjectDeleted { type_and_id: CloudObjectTypeAndId::GenericStringObject { id, .. }, .. - } => { + } if self.sync_id == *id => { // If the rule or workflow has been deleted, then we should reset it such that // the suggestion can be added again. - if self.sync_id == *id { - self.reset_suggestion(ctx); - } + self.reset_suggestion(ctx); } _ => {} } diff --git a/app/src/ai/blocklist/summarization_cancel_dialog.rs b/app/src/ai/blocklist/summarization_cancel_dialog.rs index 5ee7e2c1..d40a805c 100644 --- a/app/src/ai/blocklist/summarization_cancel_dialog.rs +++ b/app/src/ai/blocklist/summarization_cancel_dialog.rs @@ -1,12 +1,14 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; -use galaxyui::elements::{Align, Container, CrossAxisAlignment, Dismiss, Flex, ParentElement, Stack}; +use galaxyui::elements::{ + Align, Container, CrossAxisAlignment, Dismiss, Flex, ParentElement, Stack, +}; use galaxyui::fonts::Weight; use galaxyui::keymap::FixedBinding; use galaxyui::platform::Cursor; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{BorderStyle, Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::ui_components::buttons; diff --git a/app/src/ai/blocklist/telemetry.rs b/app/src/ai/blocklist/telemetry.rs index c40b3a5f..39fcca53 100644 --- a/app/src/ai/blocklist/telemetry.rs +++ b/app/src/ai/blocklist/telemetry.rs @@ -1,3 +1,5 @@ +use galaxy_core::features::FeatureFlag; +use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; use serde::Serialize; use serde_json::{json, Value}; use strum_macros::{EnumDiscriminants, EnumIter}; diff --git a/app/src/ai/blocklist/usage/context_window_view.rs b/app/src/ai/blocklist/usage/context_window_view.rs index 271093c3..24c01b98 100644 --- a/app/src/ai/blocklist/usage/context_window_view.rs +++ b/app/src/ai/blocklist/usage/context_window_view.rs @@ -1,10 +1,11 @@ +use galaxyui::elements::{ + Container, CornerRadius, CrossAxisAlignment, Flex, ParentElement, Radius, Text, +}; +use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; + use crate::ai::bedrock::convert::{ContentPart, ConversationMessage, MessageContent, MessageRole}; use crate::appearance::Appearance; use crate::ui_components::blended_colors; -use galaxyui::{ - elements::{Container, CornerRadius, CrossAxisAlignment, Flex, ParentElement, Radius, Text}, - AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, -}; pub struct ContextWindowView { messages: Vec, diff --git a/app/src/ai/blocklist/usage/conversation_usage_view.rs b/app/src/ai/blocklist/usage/conversation_usage_view.rs index 706572df..6db948b6 100644 --- a/app/src/ai/blocklist/usage/conversation_usage_view.rs +++ b/app/src/ai/blocklist/usage/conversation_usage_view.rs @@ -1,8 +1,8 @@ +#![allow(dead_code)] + use std::cmp::Ordering; use std::collections::HashMap; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::Icon; @@ -15,6 +15,8 @@ use galaxyui::fonts::{Properties, Weight}; use galaxyui::platform::Cursor; use galaxyui::text_layout::ClipConfig; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::ai::agent::conversation::AIConversationId; use crate::ai::blocklist::agent_view::orchestration_pill_bar::{ @@ -25,7 +27,7 @@ use crate::ai::blocklist::usage::render_context_window_usage_icon; use crate::ai::blocklist::usage::rollup::{ compute_orchestration_rollup, AgentAvatar, OrchestrationCreditRollup, PerAgentCreditEntry, }; -use crate::ai::blocklist::view_util::format_credits; +use crate::ai::blocklist::view_util::{format_credits, format_token_count}; use crate::ai::blocklist::{BlocklistAIHistoryEvent, BlocklistAIHistoryModel}; use crate::appearance::Appearance; use crate::persistence::model::{ @@ -40,6 +42,7 @@ pub enum DisplayMode { Footer, } +#[derive(Default)] pub struct ConversationUsageInfo { pub credits_spent: f32, pub platform_credits_spent: f32, @@ -341,10 +344,10 @@ impl ConversationUsageView { .map(|r| r.total_credits) .unwrap_or(self.usage_info.credits_spent + self.usage_info.platform_credits_spent); - if self.display_mode == DisplayMode::Footer - && self.usage_info.credits_spent_for_last_block.is_some() - { - let last_block_credits = self.usage_info.credits_spent_for_last_block.unwrap(); + if let (DisplayMode::Footer, Some(last_block_credits)) = ( + self.display_mode, + self.usage_info.credits_spent_for_last_block, + ) { labels.push(render_label_text( "Credits spent (last response)", appearance, diff --git a/app/src/ai/blocklist/usage/conversation_usage_view_tests.rs b/app/src/ai/blocklist/usage/conversation_usage_view_tests.rs index bfa7f965..989eb8cf 100644 --- a/app/src/ai/blocklist/usage/conversation_usage_view_tests.rs +++ b/app/src/ai/blocklist/usage/conversation_usage_view_tests.rs @@ -44,6 +44,7 @@ fn placeholder_usage_info() -> ConversationUsageInfo { lines_added: 0, lines_removed: 0, commands_executed: 0, + ..Default::default() } } diff --git a/app/src/ai/blocklist/view_util.rs b/app/src/ai/blocklist/view_util.rs index d7dc553e..87d8dd8e 100644 --- a/app/src/ai/blocklist/view_util.rs +++ b/app/src/ai/blocklist/view_util.rs @@ -1,8 +1,8 @@ +#![allow(dead_code)] + //! This module contains common utilities for rendering Blocklist AI UI. use std::sync::LazyLock; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, CrossAxisAlignment, Flex, Hoverable, MainAxisAlignment, @@ -14,8 +14,10 @@ use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::ui_components::text::Span; use galaxyui::{AppContext, Element, EntityId, EventContext, SingletonEntity}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; -use crate::themes::theme::{AnsiColorIdentifier, Fill, WarpTheme}; +use crate::themes::theme::{AnsiColorIdentifier, Fill, GalaxyTheme, WarpTheme}; use crate::ui_components::icons::Icon; const PROVIDER_BUTTON_ICON_SIZE: f32 = 14.; diff --git a/app/src/ai/cloud_agent_settings.rs b/app/src/ai/cloud_agent_settings.rs index f8aaeebf..a0d8e019 100644 --- a/app/src/ai/cloud_agent_settings.rs +++ b/app/src/ai/cloud_agent_settings.rs @@ -5,10 +5,10 @@ use std::collections::HashMap; +use galaxy_core::report_if_error; use settings::macros::define_settings_group; use settings::{Setting as _, SupportedPlatforms, SyncToCloud}; use warp_cli::agent::Harness; -use galaxy_core::report_if_error; use crate::server::ids::SyncId; diff --git a/app/src/ai/control_code_parser.rs b/app/src/ai/control_code_parser.rs index 422fba12..1ef09375 100644 --- a/app/src/ai/control_code_parser.rs +++ b/app/src/ai/control_code_parser.rs @@ -1,7 +1,7 @@ use std::ops::Range; -use regex::Regex; use galaxyui::keymap::Keystroke; +use regex::Regex; use crate::terminal::model::escape_sequences::C0; diff --git a/app/src/ai/conversation_details_panel.rs b/app/src/ai/conversation_details_panel.rs index d097339b..5074241a 100644 --- a/app/src/ai/conversation_details_panel.rs +++ b/app/src/ai/conversation_details_panel.rs @@ -5,9 +5,6 @@ use std::str::FromStr; use std::sync::Arc; use chrono::{DateTime, Duration, Local}; -use instant::Instant; -use parking_lot::RwLock; -use pathfinder_color::ColorU; use galaxy_cli::agent::Harness; use galaxy_cli::skill::SkillSpec; use galaxy_core::channel::ChannelState; @@ -27,6 +24,9 @@ use galaxyui::ui_components::components::UiComponent; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use instant::Instant; +use parking_lot::RwLock; +use pathfinder_color::ColorU; use crate::ai::agent::api::ServerConversationToken; #[cfg(not(target_family = "wasm"))] diff --git a/app/src/ai/conversation_details_panel_tests.rs b/app/src/ai/conversation_details_panel_tests.rs index 1f5d795b..bc3f9be6 100644 --- a/app/src/ai/conversation_details_panel_tests.rs +++ b/app/src/ai/conversation_details_panel_tests.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; use chrono::{Local, Utc}; -use persistence::model::{AgentConversationData, ConversationUsageMetadata}; use galaxy_cli::agent::Harness; -use warp_multi_agent_api as api; use galaxyui::{App, EntityId, SingletonEntity}; +use persistence::model::{AgentConversationData, ConversationUsageMetadata}; +use warp_multi_agent_api as api; use super::{ConversationDetailsData, PanelMode}; use crate::ai::agent::api::ServerConversationToken; @@ -75,6 +75,7 @@ fn test_from_conversation_prefers_server_creator_profile() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); conversation.set_server_metadata(create_test_server_metadata( @@ -188,6 +189,7 @@ fn create_test_server_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: ServerMetadata { uid: ServerId::default(), @@ -237,6 +239,7 @@ fn test_from_task_includes_linked_directory_when_run_id_matches() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); @@ -380,6 +383,7 @@ fn test_from_conversation_populates_local_conversation_fields() { is_remote_child: false, root_task_is_optimistic: None, pinned: false, + ..Default::default() }, ); @@ -451,6 +455,7 @@ fn test_from_task_includes_linked_directory_when_server_token_matches() { autoexecute_override: None, last_event_sequence: None, pinned: false, + ..Default::default() }, ); diff --git a/app/src/ai/conversation_status_ui.rs b/app/src/ai/conversation_status_ui.rs index 8d3f6d75..b742e25f 100644 --- a/app/src/ai/conversation_status_ui.rs +++ b/app/src/ai/conversation_status_ui.rs @@ -17,7 +17,7 @@ pub trait StatusElementStyle { } impl StatusElementStyle for ConversationStatus { - fn status_icon_and_color(&self, theme: &WarpTheme) -> (Icon, ColorU) { + fn status_icon_and_color(&self, theme: &GalaxyTheme) -> (Icon, ColorU) { ConversationStatus::status_icon_and_color(self, theme, StatusColorStyle::Standard) } } diff --git a/app/src/ai/custom_model_router_editor.rs b/app/src/ai/custom_model_router_editor.rs index 13400d0b..5cea0bce 100644 --- a/app/src/ai/custom_model_router_editor.rs +++ b/app/src/ai/custom_model_router_editor.rs @@ -828,7 +828,8 @@ impl CustomRouterEditorView { // Error if let Some(msg) = &self.save_error { - let err_color = galaxy_core::ui::theme::Fill::Solid(appearance.theme().ui_error_color()); + let err_color = + galaxy_core::ui::theme::Fill::Solid(appearance.theme().ui_error_color()); col.add_child( Container::new( Text::new(msg.clone(), appearance.ui_font_family(), 12.) diff --git a/app/src/ai/document/ai_document_model.rs b/app/src/ai/document/ai_document_model.rs index 973631ff..f4e6fb07 100644 --- a/app/src/ai/document/ai_document_model.rs +++ b/app/src/ai/document/ai_document_model.rs @@ -10,16 +10,15 @@ use ai::diff_validation::DiffDelta; // TODO(vorporeal): Remove this re-export at some point. pub use ai::document::{AIDocumentId, AIDocumentVersion}; use chrono::{DateTime, Local, Utc}; +use galaxy_editor::model::RichTextEditorModel; +use galaxy_editor::render::model::RichTextStyles; +use galaxyui::color::ColorU; use galaxyui::{ AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity, WindowId, }; use itertools::Itertools; use uuid::Uuid; -use galaxy_editor::model::RichTextEditorModel; -use galaxy_editor::render::model::RichTextStyles; use warp_multi_agent_api as maa_api; -use galaxyui::color::ColorU; -use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity, WindowId}; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::AIAgentActionId; diff --git a/app/src/ai/document/orchestration_config_block.rs b/app/src/ai/document/orchestration_config_block.rs index 0f7c59e3..cc53c8f1 100644 --- a/app/src/ai/document/orchestration_config_block.rs +++ b/app/src/ai/document/orchestration_config_block.rs @@ -6,9 +6,9 @@ use std::collections::HashMap; use ai::agent::action::RunAgentsExecutionMode; use ai::agent::orchestration_config::OrchestrationConfigStatus; +use galaxy_core::send_telemetry_from_ctx; use pathfinder_geometry::vector::vec2f; use warp_cli::agent::Harness; -use galaxy_core::send_telemetry_from_ctx; use warpui::elements::{ ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, Hoverable, MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement, @@ -714,7 +714,9 @@ impl View for OrchestrationConfigBlockView { let card = Container::new(column.finish()) .with_uniform_padding(12.) .with_corner_radius(CornerRadius::with_all(Radius::Pixels(4.))) - .with_background(galaxy_core::ui::theme::color::internal_colors::accent_overlay_1(theme)) + .with_background( + galaxy_core::ui::theme::color::internal_colors::accent_overlay_1(theme), + ) .with_border(warpui::elements::Border::all(1.).with_border_fill(theme.accent())) .finish(); diff --git a/app/src/ai/execution_profiles/editor/manager.rs b/app/src/ai/execution_profiles/editor/manager.rs index da204b61..6ccf618c 100644 --- a/app/src/ai/execution_profiles/editor/manager.rs +++ b/app/src/ai/execution_profiles/editor/manager.rs @@ -1,6 +1,6 @@ -use galaxyui::{Entity, EntityId, ModelContext, SingletonEntity, WindowId}; use std::collections::HashMap; +use galaxyui::{Entity, EntityId, ModelContext, SingletonEntity, WindowId}; use crate::ai::execution_profiles::profiles::ClientProfileId; use crate::pane_group::{ExecutionProfileEditorPane, PaneContent}; diff --git a/app/src/ai/execution_profiles/editor/mod.rs b/app/src/ai/execution_profiles/editor/mod.rs index 863f1e45..4a3b3861 100644 --- a/app/src/ai/execution_profiles/editor/mod.rs +++ b/app/src/ai/execution_profiles/editor/mod.rs @@ -1,10 +1,10 @@ use std::path::{Path, PathBuf}; use ai::api_keys::{ApiKeyManager, ApiKeyManagerEvent}; +use galaxy_core::ui::theme::color::internal_colors; use itertools::Itertools; use regex::Regex; use thousands::Separable; -use galaxy_core::ui::theme::color::internal_colors; use warpui::elements::{ Align, Border, ChildView, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, CrossAxisAlignment, Expanded, Flex, Highlight, MouseStateHandle, ParentElement, diff --git a/app/src/ai/execution_profiles/editor/ui_helpers.rs b/app/src/ai/execution_profiles/editor/ui_helpers.rs index 534d3a69..1f1ca294 100644 --- a/app/src/ai/execution_profiles/editor/ui_helpers.rs +++ b/app/src/ai/execution_profiles/editor/ui_helpers.rs @@ -1,7 +1,7 @@ +use galaxy_core::features::FeatureFlag; use pathfinder_geometry::vector::vec2f; use thousands::Separable; use uuid::Uuid; -use galaxy_core::features::FeatureFlag; use warpui::elements::{ ChildAnchor, ChildView, ConstrainedBox, Container, CrossAxisAlignment, Dismiss, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, OffsetPositioning, ParentAnchor, @@ -768,7 +768,6 @@ fn render_command_denylist_section( appearance: &Appearance, app: &galaxyui::AppContext, ) -> Box { - let ai_disabled = !AISettings::as_ref(app).is_any_ai_enabled(app); let org_denylist = BlocklistAIPermissions::get_org_execute_commands_denylist(app); let mut tooltip_idx = 0usize; diff --git a/app/src/ai/execution_profiles/mod.rs b/app/src/ai/execution_profiles/mod.rs index 89116321..a051eef7 100644 --- a/app/src/ai/execution_profiles/mod.rs +++ b/app/src/ai/execution_profiles/mod.rs @@ -3,9 +3,9 @@ pub use cloud_object_models::{ CloudAIExecutionProfileModel, ComputerUsePermission, RunAgentsPermission, WriteToPtyPermission, PROFILE_NAME_MAX_LENGTH, }; -use markdown_parser::{FormattedTextFragment, FormattedTextInline}; use galaxy_core::features::FeatureFlag; use galaxyui::{AppContext, SingletonEntity}; +use markdown_parser::{FormattedTextFragment, FormattedTextInline}; use super::llms::{LLMContextWindow, LLMInfo, LLMPreferences, LLMProvider}; use crate::cloud_object::model::generic_string_model::StringModel; diff --git a/app/src/ai/execution_profiles/model_menu_items.rs b/app/src/ai/execution_profiles/model_menu_items.rs index 731f29b4..f21cc55e 100644 --- a/app/src/ai/execution_profiles/model_menu_items.rs +++ b/app/src/ai/execution_profiles/model_menu_items.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use itertools::Itertools; use galaxy_core::ui::Icon; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, ParentElement, SavePosition, Shrinkable, @@ -8,6 +7,7 @@ use galaxyui::elements::{ }; use galaxyui::fonts::{Properties, Style}; use galaxyui::{Action, AppContext, Element, SingletonEntity as _}; +use itertools::Itertools; use crate::ai::custom_model_routers::is_custom_router_id; use crate::ai::llms::{ diff --git a/app/src/ai/facts/view/rule.rs b/app/src/ai/facts/view/rule.rs index 63f20aa1..00ee4e06 100644 --- a/app/src/ai/facts/view/rule.rs +++ b/app/src/ai/facts/view/rule.rs @@ -2,10 +2,10 @@ use std::fmt::Debug; use std::path::PathBuf; use ai::project_context::model::{ProjectContextModel, ProjectContextModelEvent}; -use markdown_parser::weight::CustomWeight; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use galaxy_core::ui::appearance::{Appearance, AppearanceEvent}; use galaxy_core::ui::theme::color::internal_colors; +use markdown_parser::weight::CustomWeight; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use warp_util::local_or_remote_path::LocalOrRemotePath; use warpui::elements::{ Align, Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, @@ -20,7 +20,12 @@ use warpui::{ ViewHandle, }; -use super::{is_edit_allowed, is_syncing, style, AIFact, CloudAIFact, CloudAIFactModel}; +use super::{ + is_delete_allowed, is_edit_allowed, is_syncing, style, AIFact, CloudAIFact, CloudAIFactModel, +}; +use crate::ai::facts::predefined_rules::{ + is_predefined_rule, predefined_rule_index, PREDEFINED_RULES, +}; use crate::ai::facts::AIMemory; use crate::cloud_object::model::generic_string_model::GenericStringObjectId; use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent}; @@ -388,7 +393,7 @@ impl RuleView { .cloned() .collect() }; - self.cloud_global_rules = ai_rules + let mut rows: Vec = ai_rules .into_iter() .map(|ai_fact| CloudRuleRow { fact: ai_fact, @@ -418,7 +423,7 @@ impl RuleView { } }); - self.global_rules = rows; + self.cloud_global_rules = rows; ctx.notify(); } @@ -521,7 +526,7 @@ impl RuleView { // Build a map of existing system-defined rules by name for update detection let existing_system_rules: std::collections::HashMap)> = - self.global_rules + self.cloud_global_rules .iter() .filter_map(|row| { let AIFact::Memory(AIMemory { ref name, .. }) = row.fact.model().string_model; diff --git a/app/src/ai/geap_credentials.rs b/app/src/ai/geap_credentials.rs index ee957bbf..8c3a48f2 100644 --- a/app/src/ai/geap_credentials.rs +++ b/app/src/ai/geap_credentials.rs @@ -4,9 +4,9 @@ use ai::api_keys::{ ApiKeyManager, GeapCredentials, GeapCredentialsState, GeapFederation, GeapMintBinding, LoadGeapCredentialsError, GEAP_REFRESH_LEAD_TIME, }; +use galaxy_core::features::FeatureFlag; use serde::{Deserialize, Serialize}; use vec1::vec1; -use galaxy_core::features::FeatureFlag; use warp_managed_secrets::client::{IdentityTokenOptions, TaskIdentityToken}; use warp_managed_secrets::ManagedSecretManager; use warpui::r#async::Timer; diff --git a/app/src/ai/geap_credentials_tests.rs b/app/src/ai/geap_credentials_tests.rs index 07be6509..b6393344 100644 --- a/app/src/ai/geap_credentials_tests.rs +++ b/app/src/ai/geap_credentials_tests.rs @@ -2,10 +2,10 @@ use std::sync::Arc; use std::time::{Duration, SystemTime}; use ai::api_keys::ApiKeyManager; +use galaxyui_extras::user_preferences; use settings::{PrivatePreferences, PublicPreferences}; use warp_managed_secrets::ManagedSecretManager; use warpui::{AddSingletonModel, App}; -use galaxyui_extras::user_preferences; use super::*; use crate::server::server_api::team::MockTeamClient; diff --git a/app/src/ai/get_relevant_files/controller.rs b/app/src/ai/get_relevant_files/controller.rs index 552ecda0..e0a61b94 100644 --- a/app/src/ai/get_relevant_files/controller.rs +++ b/app/src/ai/get_relevant_files/controller.rs @@ -10,8 +10,8 @@ use ai::index::locations::CodeContextLocation; use anyhow::anyhow; use futures_util::stream::AbortHandle; use galaxy_core::features::FeatureFlag; -use instant::Instant; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity}; +use instant::Instant; #[cfg(not(target_family = "wasm"))] use crate::ai::agent::SearchCodebaseFailureReason; diff --git a/app/src/ai/harness_availability.rs b/app/src/ai/harness_availability.rs index 5de86d9f..d9ac50fd 100644 --- a/app/src/ai/harness_availability.rs +++ b/app/src/ai/harness_availability.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; use std::time::Duration; +use galaxy_core::features::FeatureFlag; +use galaxy_core::user_preferences::GetUserPreferences; use instant::Instant; use serde::{Deserialize, Serialize}; use warp_cli::agent::Harness; -use galaxy_core::features::FeatureFlag; -use galaxy_core::user_preferences::GetUserPreferences; use warp_managed_secrets::client::SecretOwner; use warp_managed_secrets::{ManagedSecretManager, ManagedSecretValue}; use warpui::{Entity, ModelContext, RequestState, SingletonEntity}; diff --git a/app/src/ai/harness_display.rs b/app/src/ai/harness_display.rs index b7587052..2c287618 100644 --- a/app/src/ai/harness_display.rs +++ b/app/src/ai/harness_display.rs @@ -5,9 +5,9 @@ //! icon, and brand color from here so the two surfaces cannot drift. use galaxy_cli::agent::Harness; -use pathfinder_color::ColorU; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::{Fill as WarpThemeFill, WarpTheme}; +use pathfinder_color::ColorU; use crate::ai::agent::conversation::AIAgentHarness; use crate::ai::blocklist::CLAUDE_ORANGE; diff --git a/app/src/ai/llms.rs b/app/src/ai/llms.rs index e8c976eb..308f684c 100644 --- a/app/src/ai/llms.rs +++ b/app/src/ai/llms.rs @@ -1,25 +1,30 @@ +#![allow(dead_code)] + use std::collections::{HashMap, HashSet}; use std::sync::{Arc, OnceLock}; use ai::api_keys::{ApiKeyManager, ApiKeyManagerEvent, CustomEndpoint, CustomEndpointModel}; pub use ai::LLMId; -use parking_lot::FairMutex; -use serde::{de, Deserialize, Serialize}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::icons::Icon; use galaxy_core::user_preferences::GetUserPreferences; -use warp_multi_agent_api as api; use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity}; +use parking_lot::FairMutex; +use serde::{de, Deserialize, Serialize}; +use settings::Setting; +use warp_multi_agent_api as api; use super::custom_model_routers::{self, CustomModelRouter, ModelConfigError}; use super::execution_profiles::profiles::AIExecutionProfilesModel; +use crate::ai::bedrock::models::get_effective_models; use crate::auth::auth_manager::{AuthManager, AuthManagerEvent}; use crate::auth::AuthStateProvider; use crate::network::{NetworkStatus, NetworkStatusEvent, NetworkStatusKind}; -use crate::report_error; use crate::server::server_api::ServerApiProvider; +use crate::settings::{BedrockModelConfig, OpenAIModelConfig, OpenAIProviderConfig}; use crate::user_config::{WarpConfig, WarpConfigUpdateEvent}; use crate::workspaces::user_workspaces::{UserWorkspaces, UserWorkspacesEvent}; +use crate::{report_error, AISettings}; /// Checks if a user's' API key is being used for the given provider. /// Returns `true` if BYO API key is enabled and a key exists for the provider. @@ -36,12 +41,13 @@ pub fn is_using_api_key_for_provider(provider: &LLMProvider, app: &AppContext) - LLMProvider::Anthropic => manager.keys().anthropic.is_some(), LLMProvider::Google => manager.keys().google.is_some(), LLMProvider::Xai => manager.grok_tokens().is_some(), + LLMProvider::Bedrock | LLMProvider::LiteLLM => false, LLMProvider::Unknown => false, } } pub fn should_show_bedrock_icon_for_model(llm: &LLMInfo, app: &AppContext) -> bool { - UserWorkspaces::as_ref(app).is_aws_bedrock_credentials_enabled(app) + UserWorkspaces::as_ref(app).is_bedrock_enabled(app) && llm .host_configs .get(&LLMModelHost::AwsBedrock) @@ -142,6 +148,8 @@ impl LLMProvider { LLMProvider::Anthropic => "Anthropic", LLMProvider::Google => "Google", LLMProvider::Xai => "xAI", + LLMProvider::Bedrock => "AWS Bedrock", + LLMProvider::LiteLLM => "LiteLLM", LLMProvider::Unknown => "this provider", } } @@ -591,6 +599,8 @@ pub struct LLMPreferences { custom_llms: Vec, /// All custom model routers, including both local and cloud-backed. custom_model_routers: Vec, + #[cfg(not(target_family = "wasm"))] + openai_provider_routing: HashMap, } impl LLMPreferences { @@ -656,6 +666,8 @@ impl LLMPreferences { base_llm_for_terminal_view, custom_llms, custom_model_routers: Vec::new(), + #[cfg(not(target_family = "wasm"))] + openai_provider_routing: HashMap::new(), }; // Seed from any already-loaded local config (the async load emits @@ -698,7 +710,6 @@ impl LLMPreferences { model_id: default.model_id.to_string(), display_name: default.display_name.to_string(), vision_supported: default.vision_supported, - context_size: default.context_size, }); added = true; } @@ -803,6 +814,7 @@ impl LLMPreferences { }, )]), discount_percentage: None, + context_window: LLMContextWindow::default(), }; self.models_by_feature .agent_mode @@ -997,6 +1009,7 @@ impl LLMPreferences { }, )]), discount_percentage: None, + context_window: LLMContextWindow::default(), }; self.models_by_feature .agent_mode diff --git a/app/src/ai/llms_tests.rs b/app/src/ai/llms_tests.rs index 93ead232..bef4ec42 100644 --- a/app/src/ai/llms_tests.rs +++ b/app/src/ai/llms_tests.rs @@ -239,6 +239,7 @@ fn custom_endpoint_usage_display_label_resolves_alias_name_and_generic_fallback( base_llm_for_terminal_view: HashMap::new(), custom_llms: build_custom_llm_infos(&keys), custom_model_routers: Vec::new(), + openai_provider_routing: HashMap::new(), }; assert_eq!( diff --git a/app/src/ai/mcp/file_based_manager.rs b/app/src/ai/mcp/file_based_manager.rs index fe988e90..1807009b 100644 --- a/app/src/ai/mcp/file_based_manager.rs +++ b/app/src/ai/mcp/file_based_manager.rs @@ -2,12 +2,12 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; -use itertools::Itertools as _; -use repo_metadata::repositories::DetectedRepositories; -use uuid::Uuid; use galaxy_core::features::FeatureFlag; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; +use itertools::Itertools as _; +use repo_metadata::repositories::DetectedRepositories; +use uuid::Uuid; use super::{FileMCPWatcher, FileMCPWatcherEvent, MCPProvider}; use crate::ai::mcp::templatable_installation::TemplatableMCPServerInstallation; diff --git a/app/src/ai/mcp/file_based_manager_tests.rs b/app/src/ai/mcp/file_based_manager_tests.rs index 888adca5..44401002 100644 --- a/app/src/ai/mcp/file_based_manager_tests.rs +++ b/app/src/ai/mcp/file_based_manager_tests.rs @@ -1,6 +1,8 @@ use std::collections::HashSet; use std::path::PathBuf; +use galaxy_core::features::FeatureFlag; +use galaxyui::{App, Entity, ModelHandle, SingletonEntity}; use repo_metadata::repositories::DetectedRepositories; use repo_metadata::watcher::DirectoryWatcher; use repo_metadata::RepoMetadataModel; @@ -21,7 +23,7 @@ fn setup_app(app: &mut App) -> galaxyui::ModelHandle { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); app.add_singleton_model(FileMCPWatcher::new); app.add_singleton_model(AISettings::new_with_defaults); app.add_singleton_model(|_| AuthStateProvider::new_for_test()); diff --git a/app/src/ai/mcp/file_mcp_watcher.rs b/app/src/ai/mcp/file_mcp_watcher.rs index af05e16b..35d38f3c 100644 --- a/app/src/ai/mcp/file_mcp_watcher.rs +++ b/app/src/ai/mcp/file_mcp_watcher.rs @@ -6,6 +6,8 @@ use std::sync::LazyLock; use async_channel::Sender; use futures::Future; +use galaxy_core::safe_warn; +use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity}; use regex::Regex; use repo_metadata::repositories::{ DetectedRepositories, DetectedRepositoriesEvent, RepoDetectionSource, @@ -13,14 +15,12 @@ use repo_metadata::repositories::{ use repo_metadata::repository::{Repository, RepositorySubscriber, SubscriberId}; use repo_metadata::watcher::{DirectoryWatcher, RepositoryUpdate}; use strum::IntoEnumIterator; -use galaxy_core::safe_warn; -use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity}; use watcher::HomeDirectoryWatcherEvent; use crate::ai::mcp::parsing::normalize_codex_toml_to_json; use crate::ai::mcp::{home_config_file_path, MCPProvider, ParsedTemplatableMCPServerResult}; use crate::warp_managed_paths_watcher::{ - warp_managed_mcp_config_path, WarpManagedPathsWatcher, WarpManagedPathsWatcherEvent, + galaxy_managed_mcp_config_path, GalaxyManagedPathsWatcherEvent, WarpManagedPathsWatcher, }; use crate::HomeDirectoryWatcher; diff --git a/app/src/ai/mcp/mod.rs b/app/src/ai/mcp/mod.rs index 8359cc92..995d5069 100644 --- a/app/src/ai/mcp/mod.rs +++ b/app/src/ai/mcp/mod.rs @@ -7,13 +7,13 @@ use std::path::{Path, PathBuf}; #[cfg(not(target_family = "wasm"))] use diesel::{QueryDsl, RunQueryDsl, SqliteConnection}; +use galaxy_core::ui::appearance::Appearance; +use galaxy_core::ui::Icon; use strum::IntoEnumIterator; use strum_macros::EnumIter; #[cfg(not(target_family = "wasm"))] pub use templatable_manager::McpIntegration; pub use templatable_manager::TemplatableMCPServerManager; -use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::Icon; use crate::cloud_object::model::generic_string_model::StringModel; use crate::cloud_object::model::json_model::JsonModel; @@ -48,7 +48,7 @@ cfg_if::cfg_if! { } pub mod gallery; -use galaxyui::{AppContext, SingletonEntity as _}; +use galaxyui::AppContext; pub use gallery::MCPGalleryManager; pub mod templatable; #[cfg(not(target_family = "wasm"))] @@ -487,7 +487,7 @@ pub enum MCPServerUpdate { pub(crate) fn home_config_file_path(provider: MCPProvider) -> Option { match provider { - MCPProvider::Warp => galaxy_core::paths::warp_home_mcp_config_file_path(), + MCPProvider::Warp => galaxy_core::paths::galaxy_home_mcp_config_file_path(), _ => dirs::home_dir().map(|home_dir| home_dir.join(provider.home_config_path())), } } diff --git a/app/src/ai/mcp/mod_test.rs b/app/src/ai/mcp/mod_test.rs deleted file mode 100644 index 55376683..00000000 --- a/app/src/ai/mcp/mod_test.rs +++ /dev/null @@ -1,1100 +0,0 @@ -#[cfg(test)] -mod tests { - #[cfg(not(target_family = "wasm"))] - use crate::ai::mcp::parsing::normalize_codex_toml_to_json; - use crate::ai::mcp::parsing::resolve_json; - use crate::ai::mcp::{ - CLIServer, JsonTemplate, MCPServer, ParsedTemplatableMCPServerResult, ServerSentEvents, - StaticEnvVar, StaticHeader, TemplatableMCPServer, TemplatableMCPServerInstallation, - TemplateVariable, TransportType, VariableType, VariableValue, - }; - use galaxy_managed_secrets::ManagedSecretValue; - use serde_json; - use std::collections::HashMap; - - #[test] - fn test_mcp_server_config_serialization_excludes_secret_env_values() { - // Create a CLI server with environment variables containing secrets - let cli_server = CLIServer { - command: "npx".to_string(), - args: vec!["@modelcontextprotocol/server-postgres".to_string()], - cwd_parameter: Some("/tmp".to_string()), - static_env_vars: vec![ - StaticEnvVar { - name: "API_KEY".to_string(), - value: "SOME_LEAKED_SECRET".to_string(), - }, - StaticEnvVar { - name: "DATABASE_URL".to_string(), - value: "postgresql://user:password@localhost/db".to_string(), - }, - StaticEnvVar { - name: "PUBLIC_CONFIG".to_string(), - value: "not-secret-value".to_string(), - }, - ], - }; - - let mcp_server = MCPServer { - transport_type: TransportType::CLIServer(cli_server), - name: "test-server".to_string(), - uuid: uuid::Uuid::new_v4(), - }; - - // Test direct serde serialization - let serialized = - serde_json::to_string(&mcp_server).expect("Failed to serialize MCP server"); - - // The serialized config should NOT contain the secret values - assert!( - !serialized.contains("SOME_LEAKED_SECRET"), - "Serialized config contains leaked secret value: {serialized}", - ); - assert!( - !serialized.contains("password"), - "Serialized config contains password: {serialized}", - ); - assert!( - !serialized.contains("not-secret-value"), - "Serialized config contains env var value: {serialized}", - ); - - // But should contain the environment variable names/keys - assert!( - serialized.contains("API_KEY"), - "Serialized config should contain env var key 'API_KEY': {serialized}", - ); - assert!( - serialized.contains("DATABASE_URL"), - "Serialized config should contain env var key 'DATABASE_URL': {serialized}", - ); - assert!( - serialized.contains("PUBLIC_CONFIG"), - "Serialized config should contain env var key 'PUBLIC_CONFIG': {serialized}", - ); - } - - /// Helper function to create a test TemplatableMCPServerInstallation with custom values - fn create_test_installation( - name: &str, - template_json: &str, - variables: Vec<(&str, &str)>, - ) -> TemplatableMCPServerInstallation { - let template_variables = variables - .iter() - .map(|(key, _)| TemplateVariable { - key: key.to_string(), - allowed_values: None, - }) - .collect(); - - let variable_values = variables - .into_iter() - .map(|(key, value)| { - ( - key.to_string(), - VariableValue { - variable_type: VariableType::Text, - value: value.to_string(), - }, - ) - }) - .collect(); - - let templatable_mcp_server = TemplatableMCPServer { - uuid: uuid::Uuid::new_v4(), - name: name.to_string(), - description: None, - template: JsonTemplate { - json: template_json.to_string(), - variables: template_variables, - }, - version: 1234567890, - gallery_data: None, - }; - - TemplatableMCPServerInstallation::new( - uuid::Uuid::new_v4(), - templatable_mcp_server, - variable_values, - ) - } - - #[test] - fn test_static_env_var_direct_serialization() { - // Test direct serialization of StaticEnvVar to ensure skip_serializing works - let env_var = StaticEnvVar { - name: "TEST_SECRET".to_string(), - value: "SOME_LEAKED_SECRET".to_string(), - }; - - let serialized = serde_json::to_string(&env_var).expect("Failed to serialize env var"); - - // Should contain the name but not the value due to skip_serializing - assert!( - serialized.contains("TEST_SECRET"), - "Serialized env var should contain name: {serialized}", - ); - assert!( - !serialized.contains("SOME_LEAKED_SECRET"), - "Serialized env var should not contain value due to skip_serializing: {serialized}", - ); - } - - #[test] - fn test_static_env_var_deserialization_with_default() { - // Test that StaticEnvVar can be deserialized properly with default value - let json = r#"{"name": "API_KEY"}"#; - - let env_var: StaticEnvVar = - serde_json::from_str(json).expect("Failed to deserialize env var"); - - assert_eq!(env_var.name, "API_KEY"); - assert_eq!(env_var.value, ""); // Should default to empty string - } - - #[test] - fn test_sse_server_serialization() { - // Test that ServerSentEvents transport type serializes correctly - let sse_server = ServerSentEvents { - url: "https://example.com/sse".to_string(), - headers: Default::default(), - }; - - let mcp_server = MCPServer { - transport_type: TransportType::ServerSentEvents(sse_server), - name: "sse-server".to_string(), - uuid: uuid::Uuid::new_v4(), - }; - - let serialized = - serde_json::to_string(&mcp_server).expect("Failed to serialize MCP server"); - - // Should contain the URL since it's not a secret field - assert!( - serialized.contains("https://example.com/sse"), - "Serialized SSE server should contain URL: {serialized}", - ); - assert!( - serialized.contains("sse-server"), - "Serialized SSE server should contain name: {serialized}", - ); - } - - #[test] - fn test_sse_server_with_headers() { - // Test that ServerSentEvents transport type with headers serializes correctly - let static_headers = vec![ - StaticHeader { - name: "Authorization".to_string(), - value: "Bearer token123".to_string(), - }, - StaticHeader { - name: "X-Custom-Header".to_string(), - value: "custom-value".to_string(), - }, - ]; - - let sse_server = ServerSentEvents { - url: "https://example.com/sse".to_string(), - headers: static_headers, - }; - - let mcp_server = MCPServer { - transport_type: TransportType::ServerSentEvents(sse_server), - name: "sse-server-with-headers".to_string(), - uuid: uuid::Uuid::new_v4(), - }; - - // Test to_user_json includes headers - let user_json = mcp_server.to_user_json(); - assert!( - user_json.contains("Bearer token123"), - "User JSON should contain Authorization header value: {user_json}", - ); - assert!( - user_json.contains("X-Custom-Header"), - "User JSON should contain custom header name: {user_json}", - ); - assert!( - user_json.contains("custom-value"), - "User JSON should contain custom header value: {user_json}", - ); - - // Test from_user_json can parse headers - let parsed_servers = MCPServer::from_user_json(&user_json) - .expect("Failed to parse MCP server from user JSON"); - assert_eq!(parsed_servers.len(), 1); - let parsed_server = &parsed_servers[0]; - - if let TransportType::ServerSentEvents(parsed_sse) = &parsed_server.transport_type { - assert_eq!(parsed_sse.url, "https://example.com/sse"); - assert_eq!(parsed_sse.headers.len(), 2); - assert!(parsed_sse - .headers - .iter() - .any(|h| h.name == "Authorization" && h.value == "Bearer token123")); - assert!(parsed_sse - .headers - .iter() - .any(|h| h.name == "X-Custom-Header" && h.value == "custom-value")); - } else { - panic!("Expected ServerSentEvents transport type"); - } - } - - #[test] - fn test_sse_server_headers_default() { - // Test that headers default to empty map when not specified - let json = r#"{ - "test-server": { - "url": "https://example.com/sse" - } - }"#; - - let servers = MCPServer::from_user_json(json).expect("Failed to parse MCP servers"); - assert_eq!(servers.len(), 1); - - if let TransportType::ServerSentEvents(sse_server) = &servers[0].transport_type { - assert_eq!(sse_server.url, "https://example.com/sse"); - assert!( - sse_server.headers.is_empty(), - "Headers should default to empty" - ); - } else { - panic!("Expected ServerSentEvents transport type"); - } - } - - #[test] - fn test_hash_consistency() { - // Create two identical installations and verify they produce the same hash - let installation1 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - let installation2 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - assert_eq!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Identical installations should produce the same hash" - ); - } - - #[test] - fn test_hash_different_names() { - // Verify that different names produce different hashes - let installation1 = create_test_installation( - "server-one", - r#"{"server-one":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - let installation2 = create_test_installation( - "server-two", - r#"{"server-two":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - assert_ne!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Installations with different names should produce different hashes" - ); - } - - #[test] - fn test_hash_different_variable_values() { - // Verify that different variable values produce different hashes - let installation1 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - let installation2 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "different-secret")], - ); - - assert_ne!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Installations with different variable values should produce different hashes" - ); - } - - #[test] - fn test_hash_different_json_templates() { - // Verify that different JSON templates produce different hashes - let installation1 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - let installation2 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"python","args":["server.py"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - assert_ne!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Installations with different JSON templates should produce different hashes" - ); - } - - #[test] - fn test_hash_different_variables() { - // Verify that different variables produce different hashes - let installation1 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - let installation2 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"TOKEN":"{{TOKEN}}"}}}"#, - vec![("TOKEN", "secret123")], - ); - - assert_ne!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Installations with different variables should produce different hashes" - ); - } - - #[test] - fn test_hash_multiple_variables_order_independent() { - // Verify that variable order doesn't affect hash (BTreeMap ensures consistent ordering) - let installation1 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"API_KEY":"{{API_KEY}}","TOKEN":"{{TOKEN}}"}}}"#, - vec![("API_KEY", "secret123"), ("TOKEN", "token456")], - ); - - let installation2 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"API_KEY":"{{API_KEY}}","TOKEN":"{{TOKEN}}"}}}"#, - vec![("TOKEN", "token456"), ("API_KEY", "secret123")], - ); - - assert_eq!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Hash should be order-independent for multiple variables" - ); - } - - #[test] - fn test_hash_ignores_installation_uuid() { - // Verify that installation UUID doesn't affect hash (only name, template, and variable values) - let installation1 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - let installation2 = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","args":["server"],"env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "secret123")], - ); - - // Even though these have different UUIDs (created separately), hashes should be the same - assert_ne!( - installation1.uuid(), - installation2.uuid(), - "UUIDs should be different" - ); - assert_eq!( - installation1.hash().expect("hash should succeed"), - installation2.hash().expect("hash should succeed"), - "Hash should not depend on installation UUID" - ); - } - - #[test] - fn test_to_parsed_templatable_mcp_server_result() { - let mcp_server = MCPServer { - transport_type: TransportType::CLIServer(CLIServer { - command: "npx".to_string(), - args: vec!["@modelcontextprotocol/server-postgres".to_string()], - cwd_parameter: None, - static_env_vars: vec![StaticEnvVar { - name: "API_KEY".to_string(), - value: "SOME_SECRET".to_string(), - }], - }), - name: "test-server".to_string(), - uuid: uuid::Uuid::new_v4(), - }; - - let parsed_result = mcp_server.to_parsed_templatable_mcp_server_result(); - let actual_json_value = serde_json::from_str::( - parsed_result.templatable_mcp_server.template.json.as_str(), - ) - .unwrap(); - let expected_json_value = serde_json::from_str::(r#"{"test-server":{"command":"npx","args":["@modelcontextprotocol/server-postgres"],"env":{"API_KEY":"{{API_KEY}}"},"working_directory":null}}"#).unwrap(); - - assert_eq!(parsed_result.templatable_mcp_server.name, "test-server"); - assert_eq!(actual_json_value, expected_json_value); - assert_eq!( - parsed_result - .templatable_mcp_server - .template - .variables - .len(), - 1 - ); - assert_eq!( - parsed_result.templatable_mcp_server.template.variables[0].key, - "API_KEY" - ); - - let variable_values = parsed_result - .templatable_mcp_server_installation - .as_ref() - .unwrap() - .variable_values(); - assert_eq!(variable_values.len(), 1); - assert_eq!(variable_values["API_KEY"].variable_type, VariableType::Text); - assert_eq!(variable_values["API_KEY"].value, "SOME_SECRET"); - } - - #[test] - fn test_to_parsed_templatable_mcp_server_result_sse_headers() { - let mcp_server = MCPServer { - transport_type: TransportType::ServerSentEvents(ServerSentEvents { - url: "https://example.com/sse".to_string(), - headers: vec![ - StaticHeader { - name: "Authorization".to_string(), - value: "Bearer token123".to_string(), - }, - StaticHeader { - name: "X-Custom-Header".to_string(), - value: "custom-value".to_string(), - }, - ], - }), - name: "sse-server".to_string(), - uuid: uuid::Uuid::new_v4(), - }; - - let parsed_result = mcp_server.to_parsed_templatable_mcp_server_result(); - let actual_json_value = serde_json::from_str::( - parsed_result.templatable_mcp_server.template.json.as_str(), - ) - .unwrap(); - let expected_json_value = serde_json::from_str::( - r#"{"sse-server":{"url":"https://example.com/sse","headers":{"Authorization":"{{Authorization}}","X-Custom-Header":"{{X-Custom-Header}}"}}}"#, - ) - .unwrap(); - - assert_eq!(actual_json_value, expected_json_value); - - let mut variable_keys = parsed_result - .templatable_mcp_server - .template - .variables - .iter() - .map(|v| v.key.as_str()) - .collect::>(); - variable_keys.sort(); - assert_eq!(variable_keys, vec!["Authorization", "X-Custom-Header"]); - - let variable_values = parsed_result - .templatable_mcp_server_installation - .as_ref() - .unwrap() - .variable_values(); - assert_eq!(variable_values["Authorization"].value, "Bearer token123"); - assert_eq!( - variable_values["Authorization"].variable_type, - VariableType::Text - ); - assert_eq!(variable_values["X-Custom-Header"].value, "custom-value"); - assert_eq!( - variable_values["X-Custom-Header"].variable_type, - VariableType::Text - ); - } - - #[test] - fn test_parse_cli_server_without_args() { - // MCP configs should work without an explicit "args" field. - // The args field should default to an empty array. - let json = r#"{ - "my-server": { - "command": "uvx", - "env": { - "API_KEY": "secret123" - } - } - }"#; - - let servers = MCPServer::from_user_json(json).expect("Failed to parse MCP servers"); - assert_eq!(servers.len(), 1); - - if let TransportType::CLIServer(cli_server) = &servers[0].transport_type { - assert_eq!(cli_server.command, "uvx"); - assert!( - cli_server.args.is_empty(), - "Args should default to empty when not specified" - ); - } else { - panic!("Expected CLIServer transport type"); - } - } - - #[test] - fn test_parse_cli_server_preserves_explicit_working_directory() { - // An explicitly-set `working_directory` in a `.mcp.json`-style config must - // round-trip into `CLIServer.cwd_parameter` so the file-based spawner does - // not overwrite it with the discovery-root default. - let json = r#"{ - "my-server": { - "command": "node", - "args": ["./tooling/mcp/server.js"], - "working_directory": "/explicit/override/path" - } - }"#; - - let servers = MCPServer::from_user_json(json).expect("Failed to parse MCP servers"); - assert_eq!(servers.len(), 1); - - let TransportType::CLIServer(cli_server) = &servers[0].transport_type else { - panic!("Expected CLIServer transport type"); - }; - assert_eq!( - cli_server.cwd_parameter.as_deref(), - Some("/explicit/override/path"), - "Explicit working_directory must be preserved through parsing" - ); - } - - #[test] - fn test_parse_templatable_cli_server_without_args_and_resolve_json() { - // Templatable MCP configs should work without an explicit "args" field. - let json = r#"{ - "my-server": { - "command": "uvx", - "env": { - "API_KEY": "secret123" - } - } - }"#; - - let parsed = ParsedTemplatableMCPServerResult::from_user_json(json) - .expect("Failed to parse templatable MCP server JSON"); - assert_eq!(parsed.len(), 1); - - let installation = parsed[0] - .templatable_mcp_server_installation - .as_ref() - .expect("Installation should be present when all variables are provided"); - - // The resolved JSON should parse successfully via MCPServer::from_user_json - let resolved = resolve_json(installation); - let servers = - MCPServer::from_user_json(&resolved).expect("Failed to parse resolved MCP JSON"); - assert_eq!(servers.len(), 1); - - if let TransportType::CLIServer(cli_server) = &servers[0].transport_type { - assert_eq!(cli_server.command, "uvx"); - assert!( - cli_server.args.is_empty(), - "Args should default to empty when not specified" - ); - } else { - panic!("Expected CLIServer transport type"); - } - } - - // ── Codex TOML normalizer tests ──────────────────────────────────────── - - /// Basic STDIO server: `command` + `args` round-trips cleanly. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_basic_stdio_server() { - let toml = r#" - [mcp_servers.context7] - command = "npx" - args = ["-y", "@upstash/context7-mcp"] - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let parsed = ParsedTemplatableMCPServerResult::from_user_json(&json) - .expect("from_user_json should succeed"); - assert_eq!(parsed.len(), 1); - let server = &parsed[0].templatable_mcp_server; - assert_eq!(server.name, "context7"); - // No env vars → installation should still be present (no missing variables) - assert!( - parsed[0].templatable_mcp_server_installation.is_some(), - "installation should be present when there are no template variables" - ); - } - - /// `env_vars` entries are lowered to `${NAME}` placeholders in the env map. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_env_vars_become_placeholders() { - let toml = r#" - [mcp_servers.my_stdio] - command = "npx" - args = ["-y", "@example/mcp-server"] - env_vars = ["MY_API_KEY"] - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - let env = &value["mcp_servers"]["my_stdio"]["env"]; - assert_eq!( - env["MY_API_KEY"].as_str(), - Some("${MY_API_KEY}"), - "env_vars entry should become a ${{NAME}} placeholder" - ); - } - - /// Explicit `env` values win over `env_vars` placeholders on collision. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_explicit_env_wins_over_env_vars_on_collision() { - let toml = r#" - [mcp_servers.my_stdio] - command = "npx" - args = ["-y", "@example/mcp-server"] - env_vars = ["MY_API_KEY"] - - [mcp_servers.my_stdio.env] - MY_API_KEY = "literal-value" - LOG_LEVEL = "info" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - let env = &value["mcp_servers"]["my_stdio"]["env"]; - // Explicit env wins: literal value, not the placeholder - assert_eq!( - env["MY_API_KEY"].as_str(), - Some("literal-value"), - "explicit env entry should override env_vars placeholder" - ); - assert_eq!( - env["LOG_LEVEL"].as_str(), - Some("info"), - "non-colliding explicit env entry should be present" - ); - } - - /// `cwd` is mapped to `working_directory` in the output JSON. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_cwd_maps_to_working_directory() { - let toml = r#" - [mcp_servers.my_stdio] - command = "npx" - args = ["-y", "@example/mcp-server"] - cwd = "/home/user/project" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - assert_eq!( - value["mcp_servers"]["my_stdio"]["working_directory"].as_str(), - Some("/home/user/project"), - "cwd should be mapped to working_directory" - ); - } - - /// A TOML with one STDIO and one HTTP server produces both in the output. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_mixed_stdio_and_http_servers() { - let toml = r#" - [mcp_servers.my_stdio] - command = "npx" - args = ["-y", "@example/mcp-server"] - - [mcp_servers.my_http] - url = "https://example.com/mcp" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - let servers = value["mcp_servers"] - .as_object() - .expect("mcp_servers should be an object"); - assert!( - servers.contains_key("my_stdio"), - "STDIO server should be present" - ); - assert!( - servers.contains_key("my_http"), - "HTTP server should be present" - ); - } - - /// An HTTP server with only a `url` field round-trips correctly. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_http_url_only() { - let toml = r#" - [mcp_servers.my_http] - url = "https://example.com/mcp" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - let server = &value["mcp_servers"]["my_http"]; - assert_eq!( - server["url"].as_str(), - Some("https://example.com/mcp"), - "url should be present in output" - ); - } - - /// `bearer_token_env_var` is lowered to `Authorization: "Bearer ${VAR}"`. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_http_bearer_token_env_var() { - let toml = r#" - [mcp_servers.my_http] - url = "https://example.com/mcp" - bearer_token_env_var = "MCP_TOKEN" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - assert_eq!( - value["mcp_servers"]["my_http"]["headers"]["Authorization"].as_str(), - Some("Bearer ${MCP_TOKEN}"), - "bearer_token_env_var should produce Authorization: Bearer ${{VAR}}" - ); - } - - /// `env_http_headers` entries become `header: "${VAR}"` placeholders. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_http_env_http_headers() { - let toml = r#" - [mcp_servers.my_http] - url = "https://example.com/mcp" - env_http_headers = { "X-Api-Key" = "MCP_API_KEY" } - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - assert_eq!( - value["mcp_servers"]["my_http"]["headers"]["X-Api-Key"].as_str(), - Some("${MCP_API_KEY}"), - "env_http_headers entry should become a ${{VAR}} placeholder" - ); - } - - /// `http_headers` static values are passed through verbatim. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_http_static_headers() { - let toml = r#" - [mcp_servers.my_http] - url = "https://example.com/mcp" - http_headers = { "X-Client" = "codex" } - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - assert_eq!( - value["mcp_servers"]["my_http"]["headers"]["X-Client"].as_str(), - Some("codex"), - "http_headers static value should pass through verbatim" - ); - } - - /// `http_headers` wins over `env_http_headers` on collision. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_http_static_headers_win_over_env_headers_on_collision() { - let toml = r#" - [mcp_servers.my_http] - url = "https://example.com/mcp" - env_http_headers = { "X-Api-Key" = "MCP_API_KEY" } - http_headers = { "X-Api-Key" = "static-override" } - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - assert_eq!( - value["mcp_servers"]["my_http"]["headers"]["X-Api-Key"].as_str(), - Some("static-override"), - "http_headers should override env_http_headers on collision" - ); - } - - /// Entries with neither `command` nor `url` are skipped. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_unknown_entry_skipped() { - let toml = r#" - [mcp_servers.my_stdio] - command = "npx" - - [mcp_servers.mystery] - some_unknown_field = "value" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let value: serde_json::Value = - serde_json::from_str(&json).expect("normalized output should be valid JSON"); - let servers = value["mcp_servers"] - .as_object() - .expect("mcp_servers should be an object"); - assert!( - servers.contains_key("my_stdio"), - "STDIO server should be present" - ); - assert!( - !servers.contains_key("mystery"), - "entry with neither command nor url should be skipped" - ); - } - - /// Full round-trip: TOML with env + env_vars parses into a working installation - /// whose resolved JSON is consumable by `MCPServer::from_user_json`. - #[cfg(not(target_family = "wasm"))] - #[test] - fn test_codex_toml_round_trip_through_from_user_json() { - let toml = r#" - [mcp_servers.my_stdio] - command = "npx" - args = ["-y", "@example/mcp-server"] - - [mcp_servers.my_stdio.env] - LOG_LEVEL = "info" - "#; - let json = normalize_codex_toml_to_json(toml).expect("normalization should succeed"); - let parsed = ParsedTemplatableMCPServerResult::from_user_json(&json) - .expect("from_user_json should succeed"); - assert_eq!(parsed.len(), 1); - - let installation = parsed[0] - .templatable_mcp_server_installation - .as_ref() - .expect("installation should be present when all variables have values"); - - // The installation's variable values should contain LOG_LEVEL - let variable_values = installation.variable_values(); - assert_eq!( - variable_values["LOG_LEVEL"].value, "info", - "explicit env value should be stored in installation" - ); - - // Resolved JSON should parse as a valid MCPServer - let resolved = resolve_json(installation); - let servers = - MCPServer::from_user_json(&resolved).expect("resolved JSON should parse as MCPServer"); - assert_eq!(servers.len(), 1); - if let TransportType::CLIServer(cli) = &servers[0].transport_type { - assert_eq!(cli.command, "npx"); - assert_eq!(cli.args, vec!["-y", "@example/mcp-server"]); - } else { - panic!("Expected CLIServer transport type"); - } - } - - #[test] - fn test_parse_templatable_sse_headers_and_resolve_json() { - let json = r#"{ - "sse-server": { - "url": "https://example.com/sse", - "headers": { - "Authorization": "Bearer token123", - "X-Custom-Header": "custom-value" - } - } - }"#; - - let parsed = ParsedTemplatableMCPServerResult::from_user_json(json) - .expect("Failed to parse templatable MCP server JSON"); - assert_eq!(parsed.len(), 1); - - let templatable = &parsed[0].templatable_mcp_server; - let installation = parsed[0] - .templatable_mcp_server_installation - .as_ref() - .expect("Installation should be present when all variables are provided"); - - let template_value = - serde_json::from_str::(templatable.template.json.as_str()).unwrap(); - let expected_template_value = serde_json::from_str::( - r#"{"sse-server":{"url":"https://example.com/sse","headers":{"Authorization":"{{Authorization}}","X-Custom-Header":"{{X-Custom-Header}}"}}}"#, - ) - .unwrap(); - assert_eq!(template_value, expected_template_value); - - let variable_values = installation.variable_values(); - assert_eq!(variable_values["Authorization"].value, "Bearer token123"); - assert_eq!(variable_values["X-Custom-Header"].value, "custom-value"); - - let resolved_value = - serde_json::from_str::(&resolve_json(installation)).unwrap(); - let expected_resolved_value = serde_json::from_str::( - r#"{"sse-server":{"url":"https://example.com/sse","headers":{"Authorization":"Bearer token123","X-Custom-Header":"custom-value"}}}"#, - ) - .unwrap(); - assert_eq!(resolved_value, expected_resolved_value); - } - - // --- Runtime handlebars secret resolution tests --- - - fn make_secrets(pairs: Vec<(&str, &str)>) -> HashMap { - pairs - .into_iter() - .map(|(k, v)| { - ( - k.to_string(), - ManagedSecretValue::RawValue { - value: v.to_string(), - }, - ) - }) - .collect() - } - - #[test] - fn test_apply_secrets_resolves_explicit_handlebars_in_env_value() { - // Parser templatizes "API_KEY": "{{secret_one}}" → template has {{API_KEY}}, - // variable value is API_KEY = "{{secret_one}}". apply_secrets renders - // the explicit {{...}} ref against the secrets map. - let mut installation = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "{{secret_one}}")], - ); - - let secrets = make_secrets(vec![("secret_one", "real_api_key_value")]); - installation.apply_secrets(&secrets); - - assert_eq!( - installation.variable_values()["API_KEY"].value, - "real_api_key_value" - ); - } - - #[test] - fn test_apply_secrets_resolves_bearer_header_with_handlebars() { - // "Authorization": "Bearer {{my_token}}" → variable value is - // Authorization = "Bearer {{my_token}}". apply_secrets renders the - // embedded ref while keeping the Bearer prefix. - let mut installation = create_test_installation( - "sse-server", - r#"{"sse-server":{"url":"https://example.com","headers":{"Authorization":"{{Authorization}}"}}}"#, - vec![("Authorization", "Bearer {{my_token}}")], - ); - - let secrets = make_secrets(vec![("my_token", "tok_abc123")]); - installation.apply_secrets(&secrets); - - assert_eq!( - installation.variable_values()["Authorization"].value, - "Bearer tok_abc123" - ); - } - - #[test] - fn test_apply_secrets_skips_plain_values() { - // Plain values like "info" contain no {{...}} and should be left unchanged - // when no secret matches the key name. - let mut installation = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"LOG_LEVEL":"{{LOG_LEVEL}}"}}}"#, - vec![("LOG_LEVEL", "info")], - ); - - let secrets = make_secrets(vec![("some_secret", "value")]); - installation.apply_secrets(&secrets); - - assert_eq!(installation.variable_values()["LOG_LEVEL"].value, "info"); - } - - #[test] - fn test_apply_secrets_explicit_refs_take_priority_over_key_match() { - // If a value contains {{secret_one}} and a secret named API_KEY also exists, - // the explicit {{secret_one}} should win. - let mut installation = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "{{secret_one}}")], - ); - - let secrets = make_secrets(vec![ - ("secret_one", "correct_value"), - ("API_KEY", "wrong_value_from_key_match"), - ]); - installation.apply_secrets(&secrets); - - assert_eq!( - installation.variable_values()["API_KEY"].value, - "correct_value" - ); - } - - #[test] - fn test_apply_secrets_mixed_explicit_and_implicit() { - // Mixed case: one variable uses explicit {{...}} ref, another uses - // implicit key-name matching. - let mut installation = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"API_KEY":"{{API_KEY}}","LOG_LEVEL":"{{LOG_LEVEL}}"}}}"#, - vec![("API_KEY", "{{secret_one}}"), ("LOG_LEVEL", "info")], - ); - - let secrets = make_secrets(vec![ - ("secret_one", "resolved_secret"), - ("LOG_LEVEL", "debug_from_secret"), - ]); - installation.apply_secrets(&secrets); - - // API_KEY resolved via explicit handlebars - assert_eq!( - installation.variable_values()["API_KEY"].value, - "resolved_secret" - ); - // LOG_LEVEL resolved via implicit key-name matching - assert_eq!( - installation.variable_values()["LOG_LEVEL"].value, - "debug_from_secret" - ); - } - - #[test] - fn test_apply_secrets_missing_secret_leaves_placeholder() { - // If the referenced secret doesn't exist, the {{...}} placeholder - // should remain in the value. - let mut installation = create_test_installation( - "test-server", - r#"{"test-server":{"command":"npx","env":{"API_KEY":"{{API_KEY}}"}}}"#, - vec![("API_KEY", "{{nonexistent_secret}}")], - ); - - let secrets = make_secrets(vec![]); - installation.apply_secrets(&secrets); - - assert_eq!( - installation.variable_values()["API_KEY"].value, - "{{nonexistent_secret}}" - ); - } -} diff --git a/app/src/ai/mcp/mod_tests.rs b/app/src/ai/mcp/mod_tests.rs index 08acda35..2f5b6e86 100644 --- a/app/src/ai/mcp/mod_tests.rs +++ b/app/src/ai/mcp/mod_tests.rs @@ -15,10 +15,11 @@ use crate::ai::mcp::{ #[test] fn mcp_provider_from_file_path_recognizes_warp_home_path() { - if let Some(warp_home_mcp_config_file_path) = galaxy_core::paths::warp_home_mcp_config_file_path() + if let Some(galaxy_home_mcp_config_file_path) = + galaxy_core::paths::galaxy_home_mcp_config_file_path() { assert_eq!( - mcp_provider_from_file_path(&warp_home_mcp_config_file_path), + mcp_provider_from_file_path(&galaxy_home_mcp_config_file_path), Some(MCPProvider::Warp) ); } diff --git a/app/src/ai/mcp/templatable_manager.rs b/app/src/ai/mcp/templatable_manager.rs index 2ae9c7b8..fc19c17d 100644 --- a/app/src/ai/mcp/templatable_manager.rs +++ b/app/src/ai/mcp/templatable_manager.rs @@ -11,6 +11,9 @@ use std::sync::Arc; use diesel::SqliteConnection; use futures_util::stream::AbortHandle; #[cfg(not(target_family = "wasm"))] +use galaxyui::ModelSpawner; +use galaxyui::{Entity, SingletonEntity}; +#[cfg(not(target_family = "wasm"))] use mcp::oauth; use mcp::TemplatableMCPServerInfo; #[cfg(not(target_family = "wasm"))] @@ -18,9 +21,6 @@ pub use native::McpIntegration; #[cfg(not(target_family = "wasm"))] use parking_lot::Mutex; use uuid::Uuid; -#[cfg(not(target_family = "wasm"))] -use galaxyui::ModelSpawner; -use galaxyui::{Entity, SingletonEntity}; #[cfg(not(target_family = "wasm"))] use crate::ai::mcp::templatable::CloudTemplatableMCPServer; diff --git a/app/src/ai/mcp/templatable_manager/native.rs b/app/src/ai/mcp/templatable_manager/native.rs index 06228bef..05418b68 100644 --- a/app/src/ai/mcp/templatable_manager/native.rs +++ b/app/src/ai/mcp/templatable_manager/native.rs @@ -3,6 +3,12 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use async_compat::CompatExt as _; +use galaxy_core::execution_mode::AppExecutionMode; +use galaxy_core::features::FeatureFlag; +use galaxy_core::safe_error; +use galaxy_core::settings::Setting as _; +use galaxyui::windowing::WindowManager; +use galaxyui::{AppContext, ModelContext, SingletonEntity}; use mcp::oauth::{ self, load_credentials_from_secure_storage, write_to_secure_storage, AuthContext, CallbackResult, FileBasedPersistedCredentialsMap, PersistedCredentials, @@ -13,12 +19,6 @@ use parking_lot::Mutex; use simple_logger::manager::LogManager; use url::Url; use uuid::Uuid; -use galaxy_core::execution_mode::AppExecutionMode; -use galaxy_core::features::FeatureFlag; -use galaxy_core::safe_error; -use galaxy_core::settings::Setting as _; -use galaxyui::windowing::WindowManager; -use galaxyui::{AppContext, ModelContext, SingletonEntity}; use super::{ MCPServerState, SpawnedServerInfo, TemplatableMCPServerInfo, TemplatableMCPServerManager, diff --git a/app/src/ai/mcp/templatable_manager/wasm.rs b/app/src/ai/mcp/templatable_manager/wasm.rs index 8eae0105..fcc3bbe9 100644 --- a/app/src/ai/mcp/templatable_manager/wasm.rs +++ b/app/src/ai/mcp/templatable_manager/wasm.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, HashSet}; -use uuid::Uuid; use galaxyui::{AppContext, ModelContext}; +use uuid::Uuid; use super::TemplatableMCPServerManager; use crate::ai::mcp::templatable::{CloudTemplatableMCPServer, TemplatableMCPServer}; diff --git a/app/src/ai/mod.rs b/app/src/ai/mod.rs index eb0e4116..c1aa7a06 100644 --- a/app/src/ai/mod.rs +++ b/app/src/ai/mod.rs @@ -17,6 +17,8 @@ pub mod auth_secret_types; #[cfg(not(target_family = "wasm"))] pub mod aws_credentials; #[cfg(not(target_family = "wasm"))] +pub mod bedrock; +#[cfg(not(target_family = "wasm"))] pub(crate) mod bedrock_credentials; pub(crate) mod block_context; pub(crate) mod blocklist; @@ -44,6 +46,7 @@ pub mod onboarding; pub mod openai; pub(crate) mod persisted_workspace; pub(crate) mod predict; +pub mod provider; #[cfg(all(not(target_family = "wasm"), feature = "local_fs"))] pub(crate) mod remote_agent_context; pub(crate) mod remote_context_files; diff --git a/app/src/ai/openai/response_translator.rs b/app/src/ai/openai/response_translator.rs index 21fc7780..6359f856 100644 --- a/app/src/ai/openai/response_translator.rs +++ b/app/src/ai/openai/response_translator.rs @@ -286,6 +286,7 @@ fn build_user_query_message(task_id: &str, query_text: &str) -> ResponseEvent { timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::UserQuery(api::message::UserQuery { query: query_text.to_string(), ..Default::default() @@ -322,6 +323,7 @@ fn build_add_agent_output_message( timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::AgentOutput( api::message::AgentOutput { text: initial_text.to_string(), @@ -355,6 +357,7 @@ fn build_append_text(task_id: &str, message_id: &str, text_delta: &str) -> Respo timestamp: None, server_message_data: String::new(), citations: vec![], + fetched_memories: vec![], message: Some(api::message::Message::AgentOutput( api::message::AgentOutput { text: text_delta.to_string(), @@ -443,10 +446,14 @@ fn build_stream_finished( context_window_usage: context_usage, summarized: false, credits_spent: 0.0, + platform_credits_spent: 0.0, + total_input_tokens: input_tokens as u32, token_usage: vec![], tool_usage_metadata: None, warp_token_usage: std::collections::HashMap::new(), byok_token_usage, + custom_endpoint_token_usage: std::collections::HashMap::new(), + context_window_segments: vec![], }); ResponseEvent { diff --git a/app/src/ai/openai/translator.rs b/app/src/ai/openai/translator.rs index b59508da..5b0fed1a 100644 --- a/app/src/ai/openai/translator.rs +++ b/app/src/ai/openai/translator.rs @@ -2,14 +2,13 @@ use std::sync::{Arc, Mutex}; use warp_multi_agent_api as api; -use crate::ai::agent::api::ResponseStream; -use crate::ai::bedrock::request_translator; -use crate::ai::provider::types::{ConversationMessage, MessageContent, MessageRole}; - use super::client::{OpenAIClient, OpenAIClientConfig, OpenAIError}; use super::convert::build_openai_request; use super::request_translator::sanitize_messages_for_openai; use super::response_translator::openai_stream_to_response_events; +use crate::ai::agent::api::ResponseStream; +use crate::ai::bedrock::request_translator; +use crate::ai::provider::types::{ConversationMessage, MessageContent, MessageRole}; pub struct TranslatorRequest { pub config: OpenAIClientConfig, diff --git a/app/src/ai/persisted_workspace.rs b/app/src/ai/persisted_workspace.rs index cde95243..1dc17b9d 100644 --- a/app/src/ai/persisted_workspace.rs +++ b/app/src/ai/persisted_workspace.rs @@ -10,8 +10,12 @@ use ai::project_context::model::{ProjectContextModel, ProjectContextModelEvent}; use ai::workspace::{WorkspaceMetadata, WorkspaceMetadataEvent}; use anyhow::Context; use chrono::Utc; +#[cfg(feature = "local_fs")] +use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; #[cfg(feature = "local_fs")] +use galaxy_util::{local_or_remote_path::LocalOrRemotePath, standardized_path::StandardizedPath}; +#[cfg(feature = "local_fs")] use galaxyui::windowing::WindowManager; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; use itertools::Itertools; @@ -26,12 +30,8 @@ use repo_metadata::repositories::{DetectedRepositories, DetectedRepositoriesEven #[cfg(feature = "local_fs")] use repo_metadata::RepoMetadataModel; use serde::{Deserialize, Serialize}; -#[cfg(feature = "local_fs")] -use galaxy_core::channel::ChannelState; -#[cfg(feature = "local_fs")] -use galaxy_util::{local_or_remote_path::LocalOrRemotePath, standardized_path::StandardizedPath}; -#[cfg(feature = "local_fs")] +#[cfg(feature = "local_fs")] use crate::ai::blocklist::{BlocklistAIHistoryEvent, BlocklistAIHistoryModel}; #[cfg(feature = "local_fs")] use crate::ai::codebase_auto_indexing::{ diff --git a/app/src/ai/predict/next_command_model.rs b/app/src/ai/predict/next_command_model.rs index e349af90..9ca3a77c 100644 --- a/app/src/ai/predict/next_command_model.rs +++ b/app/src/ai/predict/next_command_model.rs @@ -19,11 +19,6 @@ use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity}; use itertools::Itertools; #[cfg_attr(not(feature = "local_fs"), allow(unused_imports))] use parking_lot::{FairMutex, Mutex}; -use galaxy_completer::completer::{ - self, expand_command_aliases, AliasExpansionResult, CompleterOptions, - CompletionsFallbackStrategy, MatchStrategy, -}; -#[cfg(feature = "local_fs")] use super::generate_ai_input_suggestions::{ create_generate_ai_input_suggestions_request, get_context_messages, @@ -772,11 +767,10 @@ pub async fn is_command_valid( // We assume the command is valid on parse error because // 1. Our completion specs are not always comprehensive (unknown args/options cause parse error) // 2. Our parsing logic has some bugs that need to be investigated (INT-816) - if classified_command.error.is_some() { + if let Some(err) = &classified_command.error { log::debug!( - "Assuming command `{}` is valid because it failed to parse: {:?}", + "Assuming command `{}` is valid because it failed to parse: {err:?}", expanded_command_line, - classified_command.error.unwrap() ); return true; } diff --git a/app/src/ai/predict/next_command_model_tests.rs b/app/src/ai/predict/next_command_model_tests.rs index 6e5fa1da..baa0a130 100644 --- a/app/src/ai/predict/next_command_model_tests.rs +++ b/app/src/ai/predict/next_command_model_tests.rs @@ -1,8 +1,8 @@ -use typed_path::TypedPathBuf; use galaxy_completer::meta::SpannedItem; use galaxy_completer::parsers::ParsedToken; use galaxy_completer::signatures::CommandRegistry; use galaxyui::App; +use typed_path::TypedPathBuf; use super::*; use crate::completer::SessionContext; diff --git a/app/src/ai/provider/mod.rs b/app/src/ai/provider/mod.rs index 6b3245d7..64ba6486 100644 --- a/app/src/ai/provider/mod.rs +++ b/app/src/ai/provider/mod.rs @@ -3,6 +3,7 @@ pub mod types; use crate::ai::bedrock::client::BedrockClientConfig; use crate::ai::openai::client::OpenAIClientConfig; +#[allow(dead_code)] pub enum ProviderConfig { Bedrock(BedrockClientConfig), OpenAI(OpenAIClientConfig), diff --git a/app/src/ai/remote_agent_context.rs b/app/src/ai/remote_agent_context.rs index 59827dca..86838637 100644 --- a/app/src/ai/remote_agent_context.rs +++ b/app/src/ai/remote_agent_context.rs @@ -2,12 +2,12 @@ use ::ai::project_context::model::{ProjectContextModel, ProjectRule}; use ::ai::skills::{ get_provider_for_path, parse_skill_content_at_location, ParsedSkill, SkillProvider, SkillScope, }; +use galaxy_core::features::FeatureFlag; +use galaxy_core::safe_warn; use remote_server::manager::{RemoteServerManager, RemoteServerManagerEvent}; use remote_server::proto::{ remote_skill_proto, RemoteAgentContextSnapshot, RemoteContextFileProto, RemoteSkillProto, }; -use galaxy_core::features::FeatureFlag; -use galaxy_core::safe_warn; use warp_util::host_id::HostId; use warp_util::local_or_remote_path::LocalOrRemotePath; use warp_util::remote_path::RemotePath; diff --git a/app/src/ai/request_usage_model.rs b/app/src/ai/request_usage_model.rs index 455a6638..05b2a2e0 100644 --- a/app/src/ai/request_usage_model.rs +++ b/app/src/ai/request_usage_model.rs @@ -2,12 +2,12 @@ use std::sync::Arc; use ai::api_keys::ApiKeyManager; use chrono::{DateTime, Local, Utc}; -use instant::Instant; -use serde::{Deserialize, Serialize}; use galaxy_core::user_preferences::GetUserPreferences as _; pub use galaxy_graphql::billing::BonusGrantType; use galaxy_graphql::scalars::time::ServerTimestamp; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; +use instant::Instant; +use serde::{Deserialize, Serialize}; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::AIAgentExchangeId; diff --git a/app/src/ai/restored_conversations.rs b/app/src/ai/restored_conversations.rs index 21253e74..772d7f58 100644 --- a/app/src/ai/restored_conversations.rs +++ b/app/src/ai/restored_conversations.rs @@ -1,8 +1,8 @@ //! A singleton model for storing conversations by ID to enable restoration across terminal views. -use galaxyui::{Entity, SingletonEntity}; use std::collections::HashMap; +use galaxyui::{Entity, SingletonEntity}; use crate::ai::agent::conversation::{AIConversation, AIConversationId}; use crate::ai::blocklist::history_model::convert_persisted_conversation_to_ai_conversation_with_metadata; diff --git a/app/src/ai/skills/file_watchers/skill_watcher.rs b/app/src/ai/skills/file_watchers/skill_watcher.rs index 550743dd..58a278ef 100644 --- a/app/src/ai/skills/file_watchers/skill_watcher.rs +++ b/app/src/ai/skills/file_watchers/skill_watcher.rs @@ -27,8 +27,8 @@ use crate::ai::remote_context_files::{ read_remote_text_file_contents, REMOTE_CONTEXT_MAX_BATCH_BYTES, REMOTE_CONTEXT_MAX_FILE_BYTES, }; use crate::warp_managed_paths_watcher::{ - filter_repository_update_by_prefix, warp_managed_skill_dirs, WarpManagedPathsWatcher, - WarpManagedPathsWatcherEvent, + filter_repository_update_by_prefix, galaxy_managed_skill_dirs, GalaxyManagedPathsWatcherEvent, + WarpManagedPathsWatcher, }; #[derive(Debug, PartialEq)] diff --git a/app/src/ai/skills/file_watchers/skill_watcher_tests.rs b/app/src/ai/skills/file_watchers/skill_watcher_tests.rs index 1383ced1..c6e2f231 100644 --- a/app/src/ai/skills/file_watchers/skill_watcher_tests.rs +++ b/app/src/ai/skills/file_watchers/skill_watcher_tests.rs @@ -3,6 +3,11 @@ use std::fs; use std::path::PathBuf; use ai::skills::{ParsedSkill, SkillProvider, SkillScope}; +use galaxy_util::host_id::HostId; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; +use galaxyui::App; use repo_metadata::entry::{DirectoryEntry, Entry, FileMetadata}; use repo_metadata::file_tree_store::FileTreeState; use repo_metadata::repositories::DetectedRepositories; @@ -11,11 +16,6 @@ use repo_metadata::{ StandingQueryContent, StandingQueryResults, StandingQueryResultsDelta, TargetFile, }; use tempfile::TempDir; -use galaxy_util::host_id::HostId; -use galaxy_util::local_or_remote_path::LocalOrRemotePath; -use galaxy_util::remote_path::RemotePath; -use galaxy_util::standardized_path::StandardizedPath; -use galaxyui::App; use super::super::subscribers::SkillRepositoryMessage; use super::{parse_project_skill_contents, SkillWatcher}; diff --git a/app/src/ai/skills/file_watchers/subscribers.rs b/app/src/ai/skills/file_watchers/subscribers.rs index 01b90472..d81868c7 100644 --- a/app/src/ai/skills/file_watchers/subscribers.rs +++ b/app/src/ai/skills/file_watchers/subscribers.rs @@ -3,9 +3,9 @@ use std::pin::Pin; use ai::skills::{read_skills, ParsedSkill, SKILL_PROVIDER_DEFINITIONS}; use async_channel::Sender; use futures::Future; +use galaxyui::ModelContext; use repo_metadata::repository::RepositorySubscriber; use repo_metadata::{Repository, RepositoryUpdate}; -use galaxyui::ModelContext; /// Messages sent from [`RepositorySubscriber`]s to [`SkillManager`]. pub enum SkillRepositoryMessage { diff --git a/app/src/ai/skills/file_watchers/utils.rs b/app/src/ai/skills/file_watchers/utils.rs index e2b4bd78..05e93667 100644 --- a/app/src/ai/skills/file_watchers/utils.rs +++ b/app/src/ai/skills/file_watchers/utils.rs @@ -5,12 +5,12 @@ use ai::skills::{ ParsedSkill, SkillProvider, SKILL_PROVIDER_DEFINITIONS, }; use anyhow::Error; -use repo_metadata::{RepoMetadataModel, RepositoryIdentifier}; -use walkdir::{DirEntry, WalkDir}; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxy_util::remote_path::RemotePath; use galaxy_util::standardized_path::StandardizedPath; use galaxyui::AppContext; +use repo_metadata::{RepoMetadataModel, RepositoryIdentifier}; +use walkdir::{DirEntry, WalkDir}; use crate::galaxy_managed_paths_watcher::galaxy_managed_skill_dirs; diff --git a/app/src/ai/skills/file_watchers/utils_tests.rs b/app/src/ai/skills/file_watchers/utils_tests.rs index 3ef021bd..d13066dc 100644 --- a/app/src/ai/skills/file_watchers/utils_tests.rs +++ b/app/src/ai/skills/file_watchers/utils_tests.rs @@ -1,3 +1,8 @@ +use galaxy_util::host_id::HostId; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; +use galaxyui::App; use repo_metadata::entry::{DirectoryEntry, Entry, FileMetadata}; use repo_metadata::file_tree_store::FileTreeState; use repo_metadata::file_tree_update::{ @@ -9,11 +14,6 @@ use repo_metadata::{ StandingQueryContent, StandingQueryResults, StandingQueryResultsDelta, }; use virtual_fs::{Stub, VirtualFS}; -use galaxy_util::host_id::HostId; -use galaxy_util::local_or_remote_path::LocalOrRemotePath; -use galaxy_util::remote_path::RemotePath; -use galaxy_util::standardized_path::StandardizedPath; -use galaxyui::App; use super::{ extract_skill_parent_directory, find_project_skill_files_in_tree, is_home_provider_path, @@ -390,7 +390,7 @@ fn extract_skill_parent_directory_returns_home_dir_for_warp_home_skill() { return; }; - let skill_path = warp_home_skills_dir.join("test-skill").join("SKILL.md"); + let skill_path = galaxy_home_skills_dir.join("test-skill").join("SKILL.md"); let result = extract_skill_parent_directory(&LocalOrRemotePath::Local(skill_path)); assert_eq!(result.ok(), Some(LocalOrRemotePath::Local(home_dir))); } @@ -548,8 +548,10 @@ fn find_skill_files_in_tree_finds_root_skills() { let model_handle = app.add_singleton_model(RepoMetadataModel::new); model_handle.update(&mut app, |model, ctx| { let key = - galaxy_util::standardized_path::StandardizedPath::from_local_canonicalized(&repo) - .unwrap(); + galaxy_util::standardized_path::StandardizedPath::from_local_canonicalized( + &repo, + ) + .unwrap(); model.insert_test_state(key.clone(), state, ctx); model.insert_test_standing_results( key, @@ -717,8 +719,10 @@ fn find_skill_files_in_tree_finds_subdirectory_skills() { let model_handle = app.add_singleton_model(RepoMetadataModel::new); model_handle.update(&mut app, |model, ctx| { let key = - galaxy_util::standardized_path::StandardizedPath::from_local_canonicalized(&repo) - .unwrap(); + galaxy_util::standardized_path::StandardizedPath::from_local_canonicalized( + &repo, + ) + .unwrap(); model.insert_test_state(key.clone(), state, ctx); model.insert_test_standing_results( key, diff --git a/app/src/ai/skills/resolve_skill_spec.rs b/app/src/ai/skills/resolve_skill_spec.rs index 8ca3a60f..7d2293ba 100644 --- a/app/src/ai/skills/resolve_skill_spec.rs +++ b/app/src/ai/skills/resolve_skill_spec.rs @@ -23,7 +23,7 @@ use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui::{AppContext, SingletonEntity as _}; use super::SkillManager; -use crate::galaxy_managed_paths_watcher::galaxy_managed_skill_dirs; +use crate::galaxy_managed_paths_watcher::warp_managed_skill_dirs as galaxy_managed_skill_dirs; const SKILL_FILE_NAME: &str = "SKILL.md"; diff --git a/app/src/ai/skills/skill_manager_tests.rs b/app/src/ai/skills/skill_manager_tests.rs index 582e54f5..1f745ba8 100644 --- a/app/src/ai/skills/skill_manager_tests.rs +++ b/app/src/ai/skills/skill_manager_tests.rs @@ -3,9 +3,6 @@ use std::fs; use std::path::Path; use ai::skills::{get_provider_for_path, ParsedSkill, SkillProvider, SkillReference, SkillScope}; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::{DirectoryWatcher, RepoMetadataModel}; -use tempfile::TempDir; use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; use galaxy_util::host_id::HostId; @@ -13,6 +10,9 @@ use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxy_util::remote_path::RemotePath; use galaxy_util::standardized_path::StandardizedPath; use galaxyui::App; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::{DirectoryWatcher, RepoMetadataModel}; +use tempfile::TempDir; use watcher::HomeDirectoryWatcher; use super::*; @@ -87,7 +87,7 @@ fn get_skills_for_working_directory_scopes_subdirectory_skills() { let repo_handle = app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); let skill_manager_handle = app.add_singleton_model(SkillManager::new); // Register the repo root so get_root_for_path returns Some. @@ -373,7 +373,7 @@ fn get_skills_for_working_directory_name_collision_returns_both() { let repo_handle = app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); let skill_manager_handle = app.add_singleton_model(SkillManager::new); // Register the repo root so get_root_for_path returns Some. @@ -477,7 +477,7 @@ fn cloud_environment_skills_always_included() { let repo_handle = app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); let skill_manager_handle = app.add_singleton_model(SkillManager::new); let canonical_repo_a = @@ -1443,7 +1443,7 @@ fn best_supported_provider_fast_path_returns_deduped_provider() { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); let handle = app.add_singleton_model(SkillManager::new); let claude_skill = make_skill("deploy", ".claude"); @@ -1469,7 +1469,7 @@ fn best_supported_provider_remaps_to_supported_provider() { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); let handle = app.add_singleton_model(SkillManager::new); let agents_skill = make_skill("deploy", ".agents"); @@ -1500,7 +1500,7 @@ fn best_supported_provider_falls_back_when_no_match() { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(RepoMetadataModel::new); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); let handle = app.add_singleton_model(SkillManager::new); let agents_skill = make_skill("deploy", ".agents"); diff --git a/app/src/ai/skills/skill_utils.rs b/app/src/ai/skills/skill_utils.rs index 0748d67a..9877c43e 100644 --- a/app/src/ai/skills/skill_utils.rs +++ b/app/src/ai/skills/skill_utils.rs @@ -8,11 +8,11 @@ use ai::skills::{ provider_parent_directory_for_skills_root, provider_rank, ParsedSkill, SkillPathOrigin, SkillProvider, }; -use lazy_static::lazy_static; -use siphasher::sip::SipHasher; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::Icon; +use lazy_static::lazy_static; +use siphasher::sip::SipHasher; use warp_util::local_or_remote_path::LocalOrRemotePath; use warpui::prelude::MouseStateHandle; use warpui::{AppContext, Element, EventContext, SingletonEntity}; diff --git a/app/src/ai_assistant/mod.rs b/app/src/ai_assistant/mod.rs index 115c4197..e6580ca1 100644 --- a/app/src/ai_assistant/mod.rs +++ b/app/src/ai_assistant/mod.rs @@ -2,16 +2,16 @@ use std::collections::HashSet; use std::sync::Arc; -use itertools::Itertools; -use lazy_static::lazy_static; -use pathfinder_color::ColorU; -use serde::{Deserialize, Serialize}; use galaxy_core::command::ExitCode; use galaxy_graphql::ai::{ RequestLimitInfo as RequestLimitInfoGraphql, RequestLimitRefreshDuration as RequestLimitRefreshDurationGraphql, }; use galaxy_graphql::mutations::generate_commands::{GenerateCommandsFailureType, GeneratedCommand}; +use itertools::Itertools; +use lazy_static::lazy_static; +use pathfinder_color::ColorU; +use serde::{Deserialize, Serialize}; use crate::ai::{RequestLimitInfo, RequestLimitRefreshDuration}; use crate::server::telemetry::OpenedWarpAISource; diff --git a/app/src/ai_assistant/panel.rs b/app/src/ai_assistant/panel.rs index e2b9f394..b66cb883 100644 --- a/app/src/ai_assistant/panel.rs +++ b/app/src/ai_assistant/panel.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use std::time::Duration; use chrono::Local; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_editor::editor::NavigationKey; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ @@ -23,6 +22,7 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::execution_context::WarpAiExecutionContext; use super::requests::{Event as RequestsEvent, RequestStatus, Requests}; diff --git a/app/src/ai_assistant/requests.rs b/app/src/ai_assistant/requests.rs index d5b08b62..575c034f 100644 --- a/app/src/ai_assistant/requests.rs +++ b/app/src/ai_assistant/requests.rs @@ -5,7 +5,6 @@ use std::sync::Arc; use anyhow::Result; use chrono::{OutOfRangeError, Utc}; use futures::stream::AbortHandle; - use galaxy_core::user_preferences::GetUserPreferences as _; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; diff --git a/app/src/ai_assistant/transcript.rs b/app/src/ai_assistant/transcript.rs index 960cc40f..b84d2bb6 100644 --- a/app/src/ai_assistant/transcript.rs +++ b/app/src/ai_assistant/transcript.rs @@ -1,7 +1,3 @@ -use markdown_parser::markdown_parser::RUNNABLE_BLOCK_MARKDOWN_LANG; -use markdown_parser::CodeBlockText; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::builder::AnimatedButtonOptions; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ @@ -19,6 +15,10 @@ use galaxyui::{ AppContext, BlurContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, WeakViewHandle, }; +use markdown_parser::markdown_parser::RUNNABLE_BLOCK_MARKDOWN_LANG; +use markdown_parser::CodeBlockText; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use super::panel::{HEADER_HEIGHT, HEXAGON_ALERT_SVG_PATH}; use super::requests::{RequestStatus, Requests}; diff --git a/app/src/ai_assistant/utils.rs b/app/src/ai_assistant/utils.rs index 2dc449cd..6b72609d 100644 --- a/app/src/ai_assistant/utils.rs +++ b/app/src/ai_assistant/utils.rs @@ -1,6 +1,3 @@ -/// Common functionality used across different AI Assistant components. -use markdown_parser::{parse_markdown, CodeBlockText, FormattedText, FormattedTextLine}; -use pathfinder_color::ColorU; use galaxyui::elements::{ ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, HighlightedHyperlink, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Text, @@ -9,6 +6,9 @@ use galaxyui::platform::Cursor; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, ModelHandle}; +/// Common functionality used across different AI Assistant components. +use markdown_parser::{parse_markdown, CodeBlockText, FormattedText, FormattedTextLine}; +use pathfinder_color::ColorU; use super::panel::AIAssistantAction; use super::requests::Requests; diff --git a/app/src/app_menus.rs b/app/src/app_menus.rs index 14385d21..132bbdb6 100644 --- a/app/src/app_menus.rs +++ b/app/src/app_menus.rs @@ -5,10 +5,10 @@ use std::path::PathBuf; use ai::workspace::WorkspaceMetadata; use csv::Writer; use enclose::enclose; +use galaxy_core::context_flag::ContextFlag; use itertools::Itertools; use settings::manager::SettingsManager; use settings::Setting as _; -use galaxy_core::context_flag::ContextFlag; use warp_util::path::user_friendly_path; use warpui::actions::StandardAction; use warpui::keymap::{Keystroke, Trigger}; diff --git a/app/src/app_services/linux/mod.rs b/app/src/app_services/linux/mod.rs index e65e4f9f..7ae230c1 100644 --- a/app/src/app_services/linux/mod.rs +++ b/app/src/app_services/linux/mod.rs @@ -1,10 +1,9 @@ use std::collections::HashMap; use futures_util::FutureExt as _; -use galaxyui::{r#async::executor::BackgroundTask, AppContext, SingletonEntity}; -use itertools::Itertools as _; use galaxyui::r#async::executor::BackgroundTask; use galaxyui::{AppContext, SingletonEntity}; +use itertools::Itertools as _; use zbus::{interface, proxy, zvariant}; use crate::channel::ChannelState; diff --git a/app/src/app_state.rs b/app/src/app_state.rs index 1441e830..1bcc06ce 100644 --- a/app/src/app_state.rs +++ b/app/src/app_state.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; -use pathfinder_geometry::rect::RectF; -use serde::{Deserialize, Serialize}; use galaxyui::platform::FullscreenState; use galaxyui::{AppContext, SingletonEntity as _}; +use pathfinder_geometry::rect::RectF; +use serde::{Deserialize, Serialize}; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent_conversations_model::AgentManagementFilters; diff --git a/app/src/appearance.rs b/app/src/appearance.rs index 3f905bc5..cf753475 100644 --- a/app/src/appearance.rs +++ b/app/src/appearance.rs @@ -1,27 +1,29 @@ -use settings::Setting as _; use galaxyui::fonts::FamilyId; -use galaxyui::{AddSingletonModel, AppContext, AssetProvider, Entity, ModelContext, SingletonEntity}; +use galaxyui::{ + AddSingletonModel, AppContext, AssetProvider, Entity, ModelContext, SingletonEntity, +}; +use settings::Setting as _; #[cfg(target_os = "macos")] mod macos_app_icon { + pub use galaxy_core::channel::{Channel, ChannelState}; pub use objc2::rc::autoreleasepool; pub use objc2::{AnyThread, MainThreadMarker}; pub use objc2_app_kit::{NSApplication, NSImage, NSWorkspace, NSWorkspaceIconCreationOptions}; pub use objc2_foundation::{ns_string, NSBundle, NSString}; - pub use galaxy_core::channel::{Channel, ChannelState}; pub use crate::settings::app_icon::{AppIcon, AppIconSettings, AppIconSettingsChangedEvent}; } use anyhow::anyhow; +pub use galaxy_core::ui::appearance::{Appearance, AppearanceEvent}; #[cfg(target_os = "macos")] use macos_app_icon::*; -pub use galaxy_core::ui::appearance::{Appearance, AppearanceEvent}; use crate::settings::{ active_theme_kind, FontSettings, FontSettingsChangedEvent, MonospaceFontSize, Settings, ThemeSettings, }; -use crate::themes::theme::{ThemeKind, WarpTheme}; +use crate::themes::theme::{GalaxyTheme, ThemeKind}; use crate::ASSETS; /// Manages the state of the app-wide Appearance settings, it is responsible diff --git a/app/src/auth/auth_manager.rs b/app/src/auth/auth_manager.rs index f618e552..2a1d29b6 100644 --- a/app/src/auth/auth_manager.rs +++ b/app/src/auth/auth_manager.rs @@ -3,18 +3,18 @@ use std::sync::Arc; use std::time::Duration; use anyhow::{anyhow, Result}; -use settings::Setting as _; -#[cfg(target_family = "wasm")] -use url::Url; -use uuid::Uuid; use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; use galaxy_graphql::mutations::create_anonymous_user::{ AnonymousUserType, CreateAnonymousUserResult, }; -use warp_server_auth::user::persistence::PersistedUser; use galaxyui::clipboard::ClipboardContent; use galaxyui::{Entity, ModelContext, SingletonEntity, UpdateModel}; +use settings::Setting as _; +#[cfg(target_family = "wasm")] +use url::Url; +use uuid::Uuid; +use warp_server_auth::user::persistence::PersistedUser; use super::auth_state::{AuthState, PersistAction}; use super::auth_view_modal::{AuthRedirectPayload, AuthViewVariant}; diff --git a/app/src/auth/auth_override_warning_body.rs b/app/src/auth/auth_override_warning_body.rs index d11d7bcc..0bd2aca0 100644 --- a/app/src/auth/auth_override_warning_body.rs +++ b/app/src/auth/auth_override_warning_body.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::color::darken; diff --git a/app/src/auth/auth_override_warning_modal.rs b/app/src/auth/auth_override_warning_modal.rs index fb63fd82..f26fa315 100644 --- a/app/src/auth/auth_override_warning_modal.rs +++ b/app/src/auth/auth_override_warning_modal.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ChildView, Container, Fill}; use galaxyui::ui_components::components::{Coords, UiComponentStyles}; @@ -6,6 +5,7 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use super::auth_manager::{AuthManager, AuthManagerEvent}; use super::auth_override_warning_body::AuthOverrideWarningBodyEvent; @@ -14,12 +14,6 @@ use crate::auth::auth_view_modal::AuthRedirectPayload; use crate::modal::Modal; use crate::root_view::unthemed_window_border; -pub struct AuthOverrideWarningModal { - auth_override_warning_modal: ViewHandle>, - interrupted_auth_payload: Option, - variant: AuthOverrideWarningModalVariant, -} - #[derive(Clone, Debug)] pub enum AuthOverrideWarningModalVariant { OnboardingView, diff --git a/app/src/auth/auth_view_body.rs b/app/src/auth/auth_view_body.rs index 05d7ec78..1618213a 100644 --- a/app/src/auth/auth_view_body.rs +++ b/app/src/auth/auth_view_body.rs @@ -1,8 +1,10 @@ +#![allow(dead_code)] + use anyhow::anyhow; -use lazy_static::lazy_static; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::DEFAULT_COMMAND_PALETTE_FONT_SIZE; use galaxy_core::ui::builder::UiBuilder; +use lazy_static::lazy_static; use warpui::accessibility::{AccessibilityContent, WarpA11yRole}; use warpui::clipboard::ClipboardContent; use warpui::color::ColorU; diff --git a/app/src/auth/auth_view_modal.rs b/app/src/auth/auth_view_modal.rs index c8da8af2..440c6fb8 100644 --- a/app/src/auth/auth_view_modal.rs +++ b/app/src/auth/auth_view_modal.rs @@ -1,66 +1,11 @@ -use std::collections::HashMap; +#![allow(dead_code)] use anyhow::{anyhow, Result}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; +use galaxyui::{AppContext, Element, Entity, TypedActionView, View, ViewContext}; use url::Url; -use galaxy_core::errors::ErrorExt; -use galaxy_core::features::FeatureFlag; -use galaxy_core::{safe_anyhow, safe_error}; -use galaxyui::actions::StandardAction; -use galaxyui::elements::{ - ChildAnchor, ChildView, Container, Fill, HighlightedHyperlink, MouseStateHandle, - OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Stack, -}; -use galaxyui::keymap::FixedBinding; -use galaxyui::ui_components::components::{Coords, UiComponentStyles}; -use galaxyui::{ - AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, - ViewHandle, -}; -use super::auth_manager::{AuthManager, AuthManagerEvent}; -use super::auth_view_body::{AuthStep, AuthViewBodyEvent}; use super::credentials::RefreshToken; -use super::login_failure_notification::{self, LoginFailureReason}; -use super::UserUid; -use crate::appearance::Appearance; -use crate::auth::auth_view_body::AuthViewBody; -use crate::modal::Modal; -use crate::root_view::unthemed_window_border; -use crate::server::server_api::auth::UserAuthenticationError; -use crate::util::bindings::CustomAction; - -pub fn init(app: &mut AppContext) { - use galaxyui::keymap::macros::*; - - app.register_fixed_bindings([ - // Bindings for paste require the StandardAction and CustomAction binding to work on all platforms. - FixedBinding::custom( - CustomAction::Paste, - AuthViewAction::PasteAuthUrl, - "Paste", - id!(AuthView::ui_name()), - ), - FixedBinding::standard( - StandardAction::Paste, - AuthViewAction::PasteAuthUrl, - id!(AuthView::ui_name()), - ), - ]); - - // For linux and Windows, default paste binding is ctrl+shift+v for PTY reasons. - // This can be confusing for users in some cases (and we might want - // to solve it in a more general way later). In the meantime, we - // add a basic ctrl+v binding for the auth view, since there is no - // terminal to interact with yet. - #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "windows"))] - app.register_fixed_bindings([FixedBinding::new( - "cmdorctrl-v", - AuthViewAction::PasteAuthUrl, - id!(AuthView::ui_name()), - )]); -} +use super::user_uid::UserUid; #[derive(Clone, Debug)] pub struct AuthRedirectPayload { @@ -71,38 +16,10 @@ pub struct AuthRedirectPayload { } impl AuthRedirectPayload { - /// Attempts to parse the `AuthRedirectPayload` from URL sent to Warp. To parse successfully, the URL - /// must be of format {scheme}://auth/desktop_redirect?refresh_token={token}. - pub fn from_url(url: Url) -> Result { - if url.host_str() != Some(AUTH_URL_HOST) { - return Err(safe_anyhow!( - safe: ("Auth redirect URL has unexpected host"), - full: ("Received URL with unexpected host: {} ", url) - )); - } - let query_params: HashMap<_, _> = url.query_pairs().into_owned().collect(); - if let Some(token) = query_params.get(AUTH_URL_REFRESH_TOKEN_QUERY_PARAM) { - let user_uid = query_params - .get(AUTH_URL_NEW_USER_UID_QUERY_PARAM) - .map(|uid| UserUid::new(uid)); - - Ok(Self { - refresh_token: RefreshToken::new(token), - user_uid, - deleted_anonymous_user: query_params - .get(AUTH_URL_DELETED_ANON_USER_QUERY_PARAM) - .map(|value| value == "true"), - state: query_params.get(AUTH_URL_STATE_QUERY_PARAM).cloned(), - }) - } else { - Err(safe_anyhow!( - safe: ("Auth redirect URL is missing required credential"), - full: ("Received URL without refresh token query param: {}", url) - )) - } + pub fn from_url(_url: Url) -> Result { + anyhow::bail!("Auth UI removed") } - /// Like [`from_url()`], except first parses the given [`raw_url`] into a [`Url`] struct. pub fn from_raw_url(raw_url: String) -> Result { match Url::parse(&raw_url) { Ok(parsed_url) => AuthRedirectPayload::from_url(parsed_url), @@ -115,181 +32,12 @@ impl AuthRedirectPayload { pub enum AuthViewVariant { Initial, RequireLoginCloseable, + HitDriveObjectLimitCloseable, ShareRequirementCloseable, } -impl AuthView { - pub fn new(variant: AuthViewVariant, ctx: &mut ViewContext) -> Self { - let auth_screen_view = ctx.add_typed_action_view(|ctx| AuthViewBody::new(variant, ctx)); - ctx.subscribe_to_view(&auth_screen_view, |me, _, event, ctx| match event { - AuthViewBodyEvent::Close => me.close(ctx), - AuthViewBodyEvent::SignUpButtonClicked => { - me.dismiss_error_notification(ctx); - } - AuthViewBodyEvent::AuthTokenEntered(token) => { - me.last_login_failure_reason = None; - me.handle_pasted_auth_url(token.clone(), ctx); - ctx.notify(); - } - AuthViewBodyEvent::LoginLaterClicked => { - me.handle_login_later(ctx); - } - }); - - let auth_screen_modal = ctx.add_typed_action_view(|ctx| { - Modal::new(None, auth_screen_view, ctx) - .with_body_style(UiComponentStyles { - padding: Some(Coords::uniform(0.)), - ..Default::default() - }) - .with_modal_style(UiComponentStyles { - width: Some(MODAL_WIDTH), - border_color: Some(Fill::from(ColorU::transparent_black())), // override default modal border color - ..Default::default() - }) - }); - - let auth_manager = AuthManager::handle(ctx); - ctx.subscribe_to_model(&auth_manager, |me, _, event, ctx| { - me.handle_auth_manager_event(event, ctx); - }); - - Self { - auth_screen_modal, - last_login_failure_reason: None, - close_login_notification_mouse_state: Default::default(), - highlighted_hyperlink_state: Default::default(), - auth_view_variant: variant, - } - } - - pub fn set_variant(&mut self, ctx: &mut ViewContext, variant: AuthViewVariant) { - self.auth_view_variant = variant; - self.update_auth_body( - ctx, - |body: &mut AuthViewBody, _: &mut ViewContext<'_, AuthViewBody>| { - body.set_variant(variant) - }, - ); - } - - fn set_auth_step(&mut self, ctx: &mut ViewContext, step: AuthStep) { - self.update_auth_body( - ctx, - |body: &mut AuthViewBody, _: &mut ViewContext<'_, AuthViewBody>| { - body.set_auth_step(step) - }, - ); - } - - pub fn skip_to_browser_open_step(&mut self, ctx: &mut ViewContext) { - self.set_auth_step(ctx, AuthStep::BrowserOpen); - } - - fn focus(&self, ctx: &mut ViewContext) { - ctx.focus(&self.auth_screen_modal); - ctx.notify(); - } - - fn dismiss_error_notification(&mut self, ctx: &mut ViewContext) { - self.last_login_failure_reason = None; - ctx.notify(); - } - - fn close(&mut self, ctx: &mut ViewContext) { - self.update_auth_body( - ctx, - |body: &mut AuthViewBody, ctx: &mut ViewContext<'_, AuthViewBody>| { - body.reset_login_screen(ctx) - }, - ); - self.dismiss_error_notification(ctx); - ctx.emit(AuthViewEvent::Close); - } - - /// Parses the given 'clipboard_content' string into a URL which is assumed to represent the - /// OAuth redirect URL containing the user's refresh token after the user authenticated Warp. - fn handle_pasted_auth_url(&mut self, pasted_url: String, ctx: &mut ViewContext) { - self.set_auth_token_input_editable(false, ctx); - match AuthRedirectPayload::from_raw_url(pasted_url) { - Ok(redirect_payload) => { - AuthManager::handle(ctx).update(ctx, |auth_manager, ctx| { - auth_manager.initialize_user_from_auth_payload(redirect_payload, true, ctx); - }); - } - Err(error) => { - safe_error!( - safe: ("Failed to parse AuthRedirectPayload from redirect URL"), - full: ("Failed to parse AuthRedirectPayload from redirect URL: {error:#}") - ); - self.last_login_failure_reason = - Some(LoginFailureReason::InvalidRedirectUrl { was_pasted: true }); - self.set_auth_token_input_editable(true, ctx); - } - } - } - - fn set_auth_token_input_editable(&mut self, is_editable: bool, ctx: &mut ViewContext) { - self.update_auth_body(ctx, |body, ctx| body.set_input_editable(is_editable, ctx)) - } - - fn update_auth_body(&mut self, ctx: &mut ViewContext, cb: F) -> S - where - F: FnOnce(&mut AuthViewBody, &mut ViewContext<'_, AuthViewBody>) -> S, - { - self.auth_screen_modal - .update(ctx, |modal, ctx| modal.body().update(ctx, cb)) - } - - pub fn handle_login_later(&mut self, ctx: &mut ViewContext) { - if FeatureFlag::SkipFirebaseAnonymousUser.is_enabled() { - AuthManager::handle(ctx).update(ctx, |_, ctx| { - ctx.emit(AuthManagerEvent::SkippedLogin); - }); - } else { - AuthManager::handle(ctx).update(ctx, |auth_manager, ctx| { - auth_manager.create_anonymous_user(None, ctx) - }); - } - } - - fn handle_auth_manager_event(&mut self, event: &AuthManagerEvent, ctx: &mut ViewContext) { - match event { - AuthManagerEvent::AuthComplete | AuthManagerEvent::SkippedLogin => { - self.close(ctx); - } - AuthManagerEvent::AuthFailed(err) => { - if err.is_actionable() { - log::error!("Failed to log in user: {err:#}"); - } - - if let UserAuthenticationError::InvalidStateParameter = err { - self.last_login_failure_reason = - Some(LoginFailureReason::InvalidStateParameter); - } else if let UserAuthenticationError::MissingStateParameter = err { - self.last_login_failure_reason = - Some(LoginFailureReason::MissingStateParameter); - } else { - self.last_login_failure_reason = - Some(LoginFailureReason::FailedUserAuthentication); - } - - self.set_auth_token_input_editable(true, ctx); - } - AuthManagerEvent::CreateAnonymousUserFailed => { - self.last_login_failure_reason = Some(LoginFailureReason::FailedUserAuthentication); - self.set_auth_token_input_editable(true, ctx); - } - AuthManagerEvent::MintCustomTokenFailed(_err) => { - self.last_login_failure_reason = Some(LoginFailureReason::FailedMintCustomToken); - } - _ => {} - } - ctx.notify(); - } -} - -#[derive(PartialEq, Eq)] +#[derive(Clone, Debug)] +#[allow(dead_code)] pub enum AuthViewEvent { Close, } diff --git a/app/src/auth/auth_view_shared_helpers.rs b/app/src/auth/auth_view_shared_helpers.rs index 127cf19f..9c78d8dc 100644 --- a/app/src/auth/auth_view_shared_helpers.rs +++ b/app/src/auth/auth_view_shared_helpers.rs @@ -1,10 +1,12 @@ -use pathfinder_color::ColorU; +#![allow(dead_code)] + use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::color::{darken, lighten}; use galaxy_core::ui::theme::ColorScheme; +use pathfinder_color::ColorU; use warpui::assets::asset_cache::AssetSource; use warpui::elements::{ Border, CacheOption, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Fill, Flex, diff --git a/app/src/auth/login_error_modal.rs b/app/src/auth/login_error_modal.rs index 71574789..65908be9 100644 --- a/app/src/auth/login_error_modal.rs +++ b/app/src/auth/login_error_modal.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use std::borrow::Cow; use pathfinder_color::ColorU; diff --git a/app/src/auth/login_slide.rs b/app/src/auth/login_slide.rs index 229e6e79..83495806 100644 --- a/app/src/auth/login_slide.rs +++ b/app/src/auth/login_slide.rs @@ -1,13 +1,7 @@ +#![allow(dead_code)] + use std::cell::Cell; -use onboarding::components::feature_optout_dialog::{ - render_feature_optout_dialog, FeatureOptOutDialog, -}; -use onboarding::slides::{layout, slide_content}; -use onboarding::{OnboardingIntention, WARP_DRIVE_FEATURES}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::features::FeatureFlag; use galaxy_core::safe_error; use galaxy_core::ui::theme::color::internal_colors; @@ -28,6 +22,14 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, UpdateModel, View, ViewContext, ViewHandle, }; +use onboarding::components::feature_optout_dialog::{ + render_feature_optout_dialog, FeatureOptOutDialog, +}; +use onboarding::slides::{layout, slide_content}; +use onboarding::{OnboardingIntention, WARP_DRIVE_FEATURES}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use ui_components::{button, Component as _, Options as _}; use crate::appearance::Appearance; use crate::auth::auth_manager::{AuthManager, AuthManagerEvent}; @@ -274,6 +276,10 @@ fn resolve_visual_path( } impl LoginSlideView { + pub fn is_auth_token_input_visible(&self) -> bool { + self.show_auth_token_input + } + pub fn new( ai_enabled: bool, uses_third_party_agents: bool, diff --git a/app/src/auth/mod.rs b/app/src/auth/mod.rs index 55c85d5b..c88b9378 100644 --- a/app/src/auth/mod.rs +++ b/app/src/auth/mod.rs @@ -1,4 +1,5 @@ pub mod auth_manager; +pub mod auth_override_warning_body; pub mod auth_override_warning_modal; mod auth_view_body; pub mod auth_view_modal; @@ -18,11 +19,11 @@ use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; pub use auth_manager::AuthManager; pub use auth_state::AuthStateProvider; pub use auth_view_modal::LoginFailureReason; +use galaxy_core::user_preferences::GetUserPreferences as _; use galaxyui::modals::{AlertDialogWithCallbacks, ModalButton}; +use galaxyui::{AppContext, SingletonEntity}; use itertools::Itertools; pub use user_uid::UserUid; -use galaxy_core::user_preferences::GetUserPreferences as _; -use galaxyui::{AppContext, SingletonEntity}; use crate::ai::agent_conversations_model::AgentConversationsModel; use crate::ai::blocklist::agent_view::orchestration_pill_bar_model::OrchestrationPillBarModel; diff --git a/app/src/auth/needs_sso_link_view.rs b/app/src/auth/needs_sso_link_view.rs index c1ad12b5..e5910a84 100644 --- a/app/src/auth/needs_sso_link_view.rs +++ b/app/src/auth/needs_sso_link_view.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use galaxyui::elements::{Align, MouseStateHandle, Shrinkable}; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; @@ -24,7 +26,10 @@ struct MouseStateHandles { impl NeedsSsoLinkView { pub fn new() -> Self { - Self + Self { + email: None, + mouse_state_handles: MouseStateHandles::default(), + } } pub fn set_email(&mut self, _email: String) {} diff --git a/app/src/auth/paste_auth_token_modal.rs b/app/src/auth/paste_auth_token_modal.rs index 0fb84d6b..4ea94e14 100644 --- a/app/src/auth/paste_auth_token_modal.rs +++ b/app/src/auth/paste_auth_token_modal.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! Modal shown when the user clicks "Click here to paste your token from //! the browser" on the onboarding agent-slide upgrade-prompt bar. Accepts a //! pasted auth redirect URL and routes it through @@ -6,8 +8,6 @@ //! This lives in the app crate (not the onboarding crate) because it reuses //! `EditorView` for the text input, which the onboarding crate doesn't //! depend on. -use pathfinder_color::ColorU; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::safe_error; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::actions::StandardAction; @@ -24,6 +24,8 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use ui_components::{button, Component as _}; use crate::appearance::Appearance; use crate::auth::auth_manager::{AuthManager, AuthManagerEvent}; @@ -88,7 +90,14 @@ pub enum PasteAuthTokenModalEvent { Cancelled, } -pub struct PasteAuthTokenModalView; +pub struct PasteAuthTokenModalView { + auth_token_input: ViewHandle, + cancel_button: button::Button, + continue_button: button::Button, + close_mouse_state: MouseStateHandle, + last_failure_reason: Option, + highlighted_hyperlink_state: HighlightedHyperlink, +} impl PasteAuthTokenModalView { pub fn new(ctx: &mut ViewContext) -> Self { diff --git a/app/src/autoupdate/linux.rs b/app/src/autoupdate/linux.rs index b6cbbd6e..286f3ce2 100644 --- a/app/src/autoupdate/linux.rs +++ b/app/src/autoupdate/linux.rs @@ -159,11 +159,11 @@ mod appimage { } mod package_manager { + use galaxyui::elements::{Container, FormattedTextElement, HighlightedHyperlink}; + use galaxyui::{Element, SingletonEntity as _}; use markdown_parser::{ FormattedText, FormattedTextFragment, FormattedTextHeader, FormattedTextLine, }; - use galaxyui::elements::{Container, FormattedTextElement, HighlightedHyperlink}; - use galaxyui::{Element, SingletonEntity as _}; use crate::appearance::Appearance; diff --git a/app/src/autoupdate/mac.rs b/app/src/autoupdate/mac.rs index 3e7535f9..e624abcd 100644 --- a/app/src/autoupdate/mac.rs +++ b/app/src/autoupdate/mac.rs @@ -14,12 +14,12 @@ use command::blocking; use command::r#async::Command; use futures::{StreamExt, TryStreamExt as _}; use futures_lite::future; -use instant::Instant; -use nix::errno::Errno; -use nix::unistd::{fchown, getgid, getuid}; use galaxy_core::macos::get_bundle_path; use galaxy_core::safe_error; use galaxyui::{AppContext, ModelContext, SingletonEntity}; +use instant::Instant; +use nix::errno::Errno; +use nix::unistd::{fchown, getgid, getuid}; use super::{release_assets_directory_url, DownloadReady}; use crate::appearance::AppearanceManager; diff --git a/app/src/autoupdate/mod.rs b/app/src/autoupdate/mod.rs index 80991088..6fcb6051 100644 --- a/app/src/autoupdate/mod.rs +++ b/app/src/autoupdate/mod.rs @@ -16,18 +16,13 @@ use ::channel_versions::{ParsedVersion, VersionInfo}; use anyhow::{anyhow, Context as _, Result}; use chrono::{DateTime, FixedOffset, NaiveDate}; use galaxy_core::execution_mode::AppExecutionMode; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::platform::TerminationMode; use galaxyui::r#async::Timer; use galaxyui::windowing::state::ApplicationStage; use galaxyui::windowing::{self, WindowManager}; -use galaxyui::{ - accessibility::{AccessibilityContent, GalaxyA11yRole}, - AppContext, -}; -use galaxyui::{Entity, ModelContext, SingletonEntity, ViewContext}; -use rand::Rng as _; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity, ViewContext}; +use rand::Rng as _; pub use self::changelog::get_current_changelog; use self::channel_versions::fetch_channel_versions; diff --git a/app/src/banner/view.rs b/app/src/banner/view.rs index 56c48295..55db1397 100644 --- a/app/src/banner/view.rs +++ b/app/src/banner/view.rs @@ -1,10 +1,6 @@ use std::marker::PhantomData; use std::rc::Rc; -use markdown_parser::{ - FormattedText, FormattedTextFragment, FormattedTextInline, FormattedTextLine, -}; -use pathfinder_geometry::vector::Vector2F; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, FormattedTextElement, HighlightedHyperlink, HyperlinkLens, HyperlinkUrl, MainAxisAlignment, MainAxisSize, @@ -20,6 +16,7 @@ use galaxyui::{ use markdown_parser::{ FormattedText, FormattedTextFragment, FormattedTextInline, FormattedTextLine, }; +use pathfinder_geometry::vector::Vector2F; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/bedrock_smoke_test.rs b/app/src/bedrock_smoke_test.rs index c4a8fe73..9778514f 100644 --- a/app/src/bedrock_smoke_test.rs +++ b/app/src/bedrock_smoke_test.rs @@ -1,8 +1,7 @@ use std::time::Duration; use galaxyui::r#async::Timer; -use galaxyui::ViewHandle; -use galaxyui::WindowId; +use galaxyui::{ViewHandle, WindowId}; use crate::ai::agent::{AIAgentOutputStatus, AIAgentTextSection, FinishedAIAgentOutput}; use crate::pane_group::PaneGroup; diff --git a/app/src/bin/generate_settings_schema.rs b/app/src/bin/generate_settings_schema.rs index 7fdaa3c7..dc33d9b3 100644 --- a/app/src/bin/generate_settings_schema.rs +++ b/app/src/bin/generate_settings_schema.rs @@ -8,6 +8,9 @@ use std::collections::HashSet; use std::io::Write; +use galaxy_core::features::{ + FeatureFlag, DEBUG_FLAGS, DOGFOOD_FLAGS, PREVIEW_FLAGS, RELEASE_FLAGS, +}; use schemars::SchemaGenerator; use serde_json::{Map, Value}; use settings::schema::SettingSchemaEntry; diff --git a/app/src/bin/integration.rs b/app/src/bin/integration.rs index e533b3a2..95f02ed5 100644 --- a/app/src/bin/integration.rs +++ b/app/src/bin/integration.rs @@ -1,6 +1,6 @@ use anyhow::Result; use clap::Parser; -use warp_cli::WorkerCommand; +use galaxy_cli::WorkerCommand; use galaxy_core::channel::{Channel, ChannelConfig, ChannelState, OzConfig, WarpServerConfig}; use galaxy_core::AppId; @@ -58,12 +58,12 @@ pub fn main() -> Result<()> { // GUI application), do so. This must occur before init_logging, as the // terminal server sets up its own logger, and attempting to set a second // logger leads to a panic. - warp::terminal::local_tty::server::run_terminal_server(args); + galaxy::terminal::local_tty::server::run_terminal_server(args); return Ok(()); } #[cfg(not(target_family = "wasm"))] WorkerCommand::RemoteServerProxy(_) | WorkerCommand::RemoteServerDaemon(_) => { - return warp::run(); + return galaxy::run(); } // This is a catch-all to handle the plugin host, which the integration test crate doesn't have a feature flag for. #[allow(unreachable_patterns)] @@ -71,5 +71,5 @@ pub fn main() -> Result<()> { } } - warp::run() + galaxy::run() } diff --git a/app/src/bin/stable.rs b/app/src/bin/stable.rs index fb849ce4..805bf822 100644 --- a/app/src/bin/stable.rs +++ b/app/src/bin/stable.rs @@ -3,10 +3,7 @@ #![cfg_attr(feature = "release_bundle", windows_subsystem = "windows")] use anyhow::Result; -use galaxy_core::{ - channel::{Channel, ChannelConfig, ChannelState, OzConfig, WarpServerConfig}, - AppId, -}; +use galaxy_core::channel::{Channel, ChannelState}; fn main() -> Result<()> { ChannelState::set(ChannelState::new( diff --git a/app/src/changelog_model.rs b/app/src/changelog_model.rs index 459fb1d0..8d072f46 100644 --- a/app/src/changelog_model.rs +++ b/app/src/changelog_model.rs @@ -3,11 +3,11 @@ use std::fmt; use std::sync::Arc; use channel_versions::{Changelog, MarkdownSection}; -use itertools::Itertools; -use markdown_parser::{parse_markdown, FormattedText}; use galaxyui::assets::asset_cache::{AssetCache, AssetSource}; use galaxyui::image_cache::ImageType; use galaxyui::{Entity, ModelContext, SingletonEntity}; +use itertools::Itertools; +use markdown_parser::{parse_markdown, FormattedText}; use crate::autoupdate::{self}; use crate::channel::{Channel, ChannelState}; diff --git a/app/src/chip_configurator/mod.rs b/app/src/chip_configurator/mod.rs index 531c79e8..361ab78c 100644 --- a/app/src/chip_configurator/mod.rs +++ b/app/src/chip_configurator/mod.rs @@ -5,12 +5,6 @@ //! and the agent input footer editor. pub(crate) mod modal_shell; -pub(crate) use modal_shell::{ - render_chip_editor_modal, render_chip_editor_sections, ChipEditorModalConfig, - ChipEditorMouseHandles, ChipEditorSectionsConfig, -}; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ Border, ConstrainedBox, Container, CrossAxisAlignment, Dash, DispatchEventResult, Draggable, @@ -21,6 +15,12 @@ use galaxyui::fonts::Properties; use galaxyui::platform::Cursor; use galaxyui::ui_components::components::UiComponent; use galaxyui::{Action, View, ViewContext}; +pub(crate) use modal_shell::{ + render_chip_editor_modal, render_chip_editor_sections, ChipEditorModalConfig, + ChipEditorMouseHandles, ChipEditorSectionsConfig, +}; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::vec2f; use crate::ai::blocklist::agent_view::toolbar_item::AgentToolbarItemKind; use crate::appearance::Appearance; diff --git a/app/src/cloud_object/mod.rs b/app/src/cloud_object/mod.rs index 5c4f0bf0..0c40c9a6 100644 --- a/app/src/cloud_object/mod.rs +++ b/app/src/cloud_object/mod.rs @@ -7,18 +7,14 @@ use anyhow::Result; use async_trait::async_trait; use chrono::{Duration, Utc}; use derivative::Derivative; -use galaxy_core::{channel::Channel, features::FeatureFlag}; -use galaxy_graphql::{ - queries::get_updated_cloud_objects::UpdatedObjectInput, scalars::time::ServerTimestamp, -}; -use galaxyui::{AppContext, SingletonEntity}; -use lazy_static::lazy_static; -use regex::Regex; -use url::Url; use galaxy_core::channel::Channel; use galaxy_core::features::FeatureFlag; use galaxy_graphql::queries::get_updated_cloud_objects::UpdatedObjectInput; use galaxy_graphql::scalars::time::ServerTimestamp; +use galaxyui::{AppContext, SingletonEntity}; +use lazy_static::lazy_static; +use regex::Regex; +use url::Url; use self::breadcrumbs::ContainingObject; use self::model::actions::ObjectActions; @@ -30,7 +26,9 @@ use crate::appearance::Appearance; use crate::auth::UserUid; use crate::channel::ChannelState; use crate::drive::items::WarpDriveItem; -use crate::drive::{CloudObjectTypeAndId, OpenWarpDriveObjectArgs, OpenWarpDriveObjectSettings}; +use crate::drive::{ + CloudObjectTypeAndId, OpenGalaxyDriveObjectArgs, OpenGalaxyDriveObjectSettings, +}; use crate::persistence::ModelEvent; use crate::server::cloud_objects::update_manager::InitiatedBy; use crate::server::ids::{HashableId, HashedSqliteId, ObjectUid, ServerId, SyncId, ToServerId}; diff --git a/app/src/cloud_object/model/model_tests.rs b/app/src/cloud_object/model/model_tests.rs index 1e202b67..59ca7a63 100644 --- a/app/src/cloud_object/model/model_tests.rs +++ b/app/src/cloud_object/model/model_tests.rs @@ -3,11 +3,11 @@ use std::time::Duration; use chrono::Utc; use cloud_object_client::MockObjectClient; +use galaxyui::{App, ModelHandle}; use lazy_static::lazy_static; use mockall::Sequence; use rand::Rng; -use settings::{RespectUserSyncSetting, SyncToCloud}; -use galaxyui::{App, ModelHandle}; +use settings::SyncToCloud; use super::*; use crate::auth::auth_manager::AuthManager; diff --git a/app/src/cloud_object/model/persistence.rs b/app/src/cloud_object/model/persistence.rs index 620cef55..25c1e63b 100644 --- a/app/src/cloud_object/model/persistence.rs +++ b/app/src/cloud_object/model/persistence.rs @@ -2,9 +2,9 @@ use std::collections::{HashMap, HashSet}; use std::sync::mpsc::SyncSender; use chrono::{DateTime, Duration, Utc}; +use galaxy_core::features::FeatureFlag; use itertools::Itertools; use rand::Rng; -use galaxy_core::features::FeatureFlag; use warp_graphql::scalars::time::ServerTimestamp; use warpui::{AppContext, Entity, ModelContext, SingletonEntity}; diff --git a/app/src/code/buffer_location_tests.rs b/app/src/code/buffer_location_tests.rs index 21a7d215..76d05ff6 100644 --- a/app/src/code/buffer_location_tests.rs +++ b/app/src/code/buffer_location_tests.rs @@ -1,9 +1,9 @@ +use galaxy_files::FileModel; use lsp::LspManagerModel; use remote_server::proto::TextEdit; use repo_metadata::repositories::DetectedRepositories; use repo_metadata::watcher::DirectoryWatcher; use repo_metadata::RepoMetadataModel; -use warp_files::FileModel; use warp_util::content_version::ContentVersion; use warp_util::host_id::HostId; use warp_util::standardized_path::StandardizedPath; diff --git a/app/src/code/code_actions.rs b/app/src/code/code_actions.rs index e1081d30..b47e7c82 100644 --- a/app/src/code/code_actions.rs +++ b/app/src/code/code_actions.rs @@ -21,7 +21,9 @@ const CODE_ACTIONS_MENU_WIDTH: f32 = 380.; const CODE_ACTIONS_MENU_MAX_HEIGHT: f32 = 250.; const MAX_VISIBLE_ACTIONS: usize = 12; +#[derive(Default)] pub(super) enum CodeActionsState { + #[default] Idle, Requesting { abort_handle: AbortHandle, @@ -34,12 +36,6 @@ pub(super) enum CodeActionsState { }, } -impl Default for CodeActionsState { - fn default() -> Self { - Self::Idle - } -} - impl CodeActionsState { pub fn dismiss(&mut self) -> bool { if matches!(self, Self::Idle) { diff --git a/app/src/code/completion.rs b/app/src/code/completion.rs index 50f15817..d0d35607 100644 --- a/app/src/code/completion.rs +++ b/app/src/code/completion.rs @@ -38,7 +38,9 @@ pub(super) struct ResolvedDocumentation { pub scroll_state: ClippedScrollStateHandle, } +#[derive(Default)] pub(super) enum CompletionState { + #[default] Idle, Requesting { abort_handle: AbortHandle, @@ -59,12 +61,6 @@ pub(super) enum CompletionState { }, } -impl Default for CompletionState { - fn default() -> Self { - Self::Idle - } -} - impl CompletionState { pub fn is_showing(&self) -> bool { matches!(self, Self::Showing { .. }) diff --git a/app/src/code/editor/comment_editor.rs b/app/src/code/editor/comment_editor.rs index 6cd598c7..eafd8249 100644 --- a/app/src/code/editor/comment_editor.rs +++ b/app/src/code/editor/comment_editor.rs @@ -1,9 +1,9 @@ use std::cell::RefCell; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; use warp_editor::render::element::VerticalExpansionBehavior; use warpui::elements::{ Border, ChildView, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, @@ -238,12 +238,11 @@ impl CommentEditor { EditorViewEvent::CmdEnter => { self.save_comment(ctx); } - EditorViewEvent::EscapePressed => { - // Dismiss the comment composer when pressing Escape on an empty draft. - if self.editor.as_ref(ctx).model().as_ref(ctx).is_empty(ctx) { - self.reset(ctx); - ctx.emit(CommentEditorEvent::CloseEditor); - } + EditorViewEvent::EscapePressed + if self.editor.as_ref(ctx).model().as_ref(ctx).is_empty(ctx) => + { + self.reset(ctx); + ctx.emit(CommentEditorEvent::CloseEditor); } _ => {} } diff --git a/app/src/code/editor/diff.rs b/app/src/code/editor/diff.rs index 0ca566e9..ec75d253 100644 --- a/app/src/code/editor/diff.rs +++ b/app/src/code/editor/diff.rs @@ -7,23 +7,17 @@ use std::rc::Rc; use std::sync::Arc; use futures::stream::AbortHandle; -use galaxy_core::ui::theme::Fill; -use galaxy_editor::{ - content::{edit::TemporaryBlock, version::BufferVersion}, - multiline::{AnyMultilineString, MultilineStr, MultilineString, LF}, - render::model::{Decoration, LineCount, LineDecoration}, -}; +use galaxy_core::ui::theme::{AnsiColorIdentifier, Fill}; +use galaxy_editor::content::edit::TemporaryBlock; +use galaxy_editor::content::version::BufferVersion; +use galaxy_editor::multiline::{AnyMultilineString, MultilineStr, MultilineString, LF}; +use galaxy_editor::render::model::{Decoration, LineCount, LineDecoration}; use galaxyui::{Entity, ModelContext}; use itertools::Itertools; use pathfinder_color::ColorU; use rangemap::RangeMap; use similar::{ChangeTag, DiffOp, TextDiff}; use string_offset::CharOffset; -use galaxy_core::ui::theme::{AnsiColorIdentifier, Fill}; -use galaxy_editor::content::edit::TemporaryBlock; -use galaxy_editor::content::version::BufferVersion; -use galaxy_editor::multiline::{AnyMultilineString, MultilineStr, MultilineString, LF}; -use galaxy_editor::render::model::{Decoration, LineCount, LineDecoration}; use super::super::DiffResult; use crate::appearance::Appearance; diff --git a/app/src/code/editor/diff_tests.rs b/app/src/code/editor/diff_tests.rs index e1a8f5a4..0e8ed1cc 100644 --- a/app/src/code/editor/diff_tests.rs +++ b/app/src/code/editor/diff_tests.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use galaxy_editor::multiline::{MultilineStr, MultilineString}; +use galaxyui::App; use rangemap::RangeMap; use unindent::Unindent as _; @@ -9,7 +10,6 @@ use crate::code::editor::diff::ChangeType; #[test] fn test_diff_generation() { - use galaxyui::App; App::test((), |_| async move { let (change_mapping, deletion_mapping) = DiffModel::compute_diff_internal( MultilineStr::try_new("Hello World\nThis is the second line.\nThis is the third.") diff --git a/app/src/code/editor/element.rs b/app/src/code/editor/element.rs index 927270e2..463d3f46 100644 --- a/app/src/code/editor/element.rs +++ b/app/src/code/editor/element.rs @@ -3,11 +3,6 @@ use std::ops::Range; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -pub use gutter_button::{AddAsContextButton, CommentButton, RevertHunkButton}; -use parking_lot::Mutex; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -32,10 +27,11 @@ use galaxyui::{ AfterLayoutContext, AppContext, ClipBounds, Element, Event, EventContext, LayoutContext, ModelHandle, PaintContext, SingletonEntity, SizeConstraint, }; -use pathfinder_geometry::{ - rect::RectF, - vector::{vec2f, Vector2F}, -}; +pub use gutter_button::{AddAsContextButton, CommentButton, RevertHunkButton}; +use parking_lot::Mutex; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::diff::{DiffHunkDisplay, DiffStatus}; use super::model::DiffNavigationState; @@ -1632,26 +1628,22 @@ impl Element for EditorWrapper { ctx.notify(); } } - Some(Event::LeftMouseDown { position, .. }) => { - if !gutter_handled { - let in_bound = self - .gutter_element_range_containing_position(*position, false) - .is_some(); - self.state_handle - .in_click - .store(in_bound, Ordering::Relaxed); - } + Some(Event::LeftMouseDown { position, .. }) if !gutter_handled => { + let in_bound = self + .gutter_element_range_containing_position(*position, false) + .is_some(); + self.state_handle + .in_click + .store(in_bound, Ordering::Relaxed); } - Some(Event::LeftMouseUp { position, .. }) => { - if !gutter_handled { - let was_clicking = self.state_handle.in_click.swap(false, Ordering::Relaxed); + Some(Event::LeftMouseUp { position, .. }) if !gutter_handled => { + let was_clicking = self.state_handle.in_click.swap(false, Ordering::Relaxed); - if was_clicking { - if let Some(gutter_range) = - self.gutter_element_range_containing_position(*position, false) - { - (self.click_handler)(gutter_range, ctx); - } + if was_clicking { + if let Some(gutter_range) = + self.gutter_element_range_containing_position(*position, false) + { + (self.click_handler)(gutter_range, ctx); } } } diff --git a/app/src/code/editor/embedded_comment.rs b/app/src/code/editor/embedded_comment.rs index 51db4aa3..3eb3716d 100644 --- a/app/src/code/editor/embedded_comment.rs +++ b/app/src/code/editor/embedded_comment.rs @@ -7,9 +7,6 @@ use galaxy_editor::content::markdown::MarkdownStyle; use galaxy_editor::editor::EmbeddedItemModel; use galaxy_editor::render::element::{RenderContext, RenderableBlock}; use galaxy_editor::render::layout::TextLayout; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -use serde_yaml::Mapping; -use uuid::Uuid; use galaxy_editor::render::model::viewport::ViewportItem; use galaxy_editor::render::model::{ BlockSpacing, EmbeddedItem, EmbeddedItemHTMLRepresentation, EmbeddedItemRichFormat, @@ -18,6 +15,9 @@ use galaxy_editor::render::model::{ use galaxyui::event::DispatchedEvent; use galaxyui::units::Pixels; use galaxyui::{AppContext, EntityId, EventContext, LayoutContext, ViewHandle, WindowId}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +use serde_yaml::Mapping; +use uuid::Uuid; use crate::code::editor::comment_editor::CommentEditor; use crate::code_review::comments::CommentId; diff --git a/app/src/code/editor/find/view.rs b/app/src/code/editor/find/view.rs index 6cfa1922..c507f526 100644 --- a/app/src/code/editor/find/view.rs +++ b/app/src/code/editor/find/view.rs @@ -4,7 +4,7 @@ use pathfinder_color::ColorU; use warp_editor::editor::NavigationKey; use warp_editor::search::{SearchEvent, Searcher}; -pub use warpui::accessibility::{AccessibilityContent, WarpA11yRole}; +pub use warpui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use warpui::elements::{ Align, Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Element, Flex, Hoverable, MainAxisAlignment, MouseStateHandle, @@ -318,11 +318,8 @@ impl CodeEditorFind { EditorEvent::Escape => { self.close_find_bar(ctx); } - EditorEvent::Navigate(NavigationKey::Tab) => { - // If replace editor is currently open and the user presses 'tab', focus on the find editor - if self.is_replace_open { - ctx.focus(&self.replace_editor); - } + EditorEvent::Navigate(NavigationKey::Tab) if self.is_replace_open => { + ctx.focus(&self.replace_editor); } _ => {} } diff --git a/app/src/code/editor/line.rs b/app/src/code/editor/line.rs index 3ae270e8..e0f6ea2d 100644 --- a/app/src/code/editor/line.rs +++ b/app/src/code/editor/line.rs @@ -1,6 +1,6 @@ -use galaxy_editor::render::model::{LineCount, RenderLineLocation}; use std::ops::Range; +use galaxy_editor::render::model::{LineCount, RenderLineLocation}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum EditorLineLocation { diff --git a/app/src/code/editor/model.rs b/app/src/code/editor/model.rs index d66d2eb8..364cbcd5 100644 --- a/app/src/code/editor/model.rs +++ b/app/src/code/editor/model.rs @@ -9,24 +9,6 @@ use std::sync::Arc; use std::{cmp, mem}; use ai::diff_validation::DiffDelta; -use itertools::Itertools; -use languages::{language_by_filename, language_by_local_filename, language_by_name, Language}; -use line_ending::LineEnding; -use num_traits::SaturatingSub; -use rangemap::{RangeMap, RangeSet}; -use string_offset::CharOffset; -use syntax_tree::{ColorMap, DecorationStateEvent, SyntaxTreeState}; -use vec1::{vec1, Vec1}; -use vim::vim::{ - BracketChar, CharacterMotion, Direction, FindCharMotion, FirstNonWhitespaceMotion, - InsertPosition, LineMotion, MotionType, TextObjectInclusion, TextObjectType, VimOperator, - VimTextObject, WordBound, WordMotion, WordType, -}; -use vim::{ - find_next_paragraph_end, find_previous_paragraph_start, vim_a_block, vim_a_paragraph, - vim_a_quote, vim_a_word, vim_find_char_on_line, vim_find_matching_bracket, vim_inner_block, - vim_inner_paragraph, vim_inner_quote, vim_inner_word, vim_word_iterator_from_offset, -}; use galaxy_core::platform::SessionPlatform; use galaxy_core::semantic_selection::SemanticSelection; use galaxy_core::ui::theme::Fill; @@ -62,6 +44,24 @@ use galaxyui::text::point::Point; use galaxyui::text::TextBuffer; use galaxyui::units::{IntoPixels, Pixels}; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity}; +use itertools::Itertools; +use languages::{language_by_filename, language_by_local_filename, language_by_name, Language}; +use line_ending::LineEnding; +use num_traits::SaturatingSub; +use rangemap::{RangeMap, RangeSet}; +use string_offset::CharOffset; +use syntax_tree::{ColorMap, DecorationStateEvent, SyntaxTreeState}; +use vec1::{vec1, Vec1}; +use vim::vim::{ + BracketChar, CharacterMotion, Direction, FindCharMotion, FirstNonWhitespaceMotion, + InsertPosition, LineMotion, MotionType, TextObjectInclusion, TextObjectType, VimOperator, + VimTextObject, WordBound, WordMotion, WordType, +}; +use vim::{ + find_next_paragraph_end, find_previous_paragraph_start, vim_a_block, vim_a_paragraph, + vim_a_quote, vim_a_word, vim_find_char_on_line, vim_find_matching_bracket, vim_inner_block, + vim_inner_paragraph, vim_inner_quote, vim_inner_word, vim_word_iterator_from_offset, +}; use super::super::DiffResult; use super::comments::{EditorCommentsModel, PendingComment, PendingCommentEvent}; diff --git a/app/src/code/editor/model_tests.rs b/app/src/code/editor/model_tests.rs index bfdb9ecd..28df70cd 100644 --- a/app/src/code/editor/model_tests.rs +++ b/app/src/code/editor/model_tests.rs @@ -1,6 +1,8 @@ use std::path::Path; use futures::channel::oneshot; +use galaxy_util::content_version::ContentVersion; +use galaxyui::App; use vec1::vec1; use super::*; diff --git a/app/src/code/editor/view.rs b/app/src/code/editor/view.rs index f2027661..0c557ff5 100644 --- a/app/src/code/editor/view.rs +++ b/app/src/code/editor/view.rs @@ -7,13 +7,6 @@ use std::path::Path; use std::rc::Rc; use ai::diff_validation::DiffDelta; -use lazy_static::lazy_static; -use num_traits::SaturatingSub; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; -use string_offset::CharOffset; -use vec1::{vec1, Vec1}; -use vim::vim::{Direction, InsertPosition, VimMode, VimModel, VimState, VimSubscriber}; use galaxy_core::platform::SessionPlatform; use galaxy_editor::content::buffer::{ Buffer, BufferEditAction, EditOrigin, InitialBufferState, ToBufferCharOffset as _, @@ -52,6 +45,13 @@ use galaxyui::{ AppContext, BlurContext, CursorInfo, Element, Entity, FocusContext, ModelHandle, SingletonEntity, View, ViewContext, ViewHandle, WeakViewHandle, WindowId, }; +use lazy_static::lazy_static; +use num_traits::SaturatingSub; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; +use string_offset::CharOffset; +use vec1::{vec1, Vec1}; +use vim::vim::{Direction, InsertPosition, VimMode, VimModel, VimState, VimSubscriber}; use crate::appearance::Appearance; use crate::code::editor::comment_editor::{CommentEditor, CommentEditorEvent}; diff --git a/app/src/code/editor/view/actions.rs b/app/src/code/editor/view/actions.rs index 08e91c5a..b89d4d61 100644 --- a/app/src/code/editor/view/actions.rs +++ b/app/src/code/editor/view/actions.rs @@ -5,9 +5,6 @@ use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::ops::Range; -use lazy_static::lazy_static; -use rangemap::RangeSet; -use string_offset::CharOffset; use galaxy_editor::content::version::BufferVersion; use galaxy_editor::editor::{EmbeddedItemModel, RunnableCommandModel, TextDecoration}; use galaxy_editor::model::{CoreEditorModel, PlainTextEditorModel}; @@ -21,6 +18,9 @@ use galaxyui::event::ModifiersState; use galaxyui::keymap::{EditableBinding, FixedBinding, Keystroke, PerPlatformKeystroke}; use galaxyui::units::Pixels; use galaxyui::{AppContext, TypedActionView, ViewContext, WeakViewHandle}; +use lazy_static::lazy_static; +use rangemap::RangeSet; +use string_offset::CharOffset; use crate::cmd_or_ctrl_shift; use crate::code::editor::line::EditorLineLocation; diff --git a/app/src/code/editor/view/vim_handler.rs b/app/src/code/editor/view/vim_handler.rs index 3410af2f..83cccd51 100644 --- a/app/src/code/editor/view/vim_handler.rs +++ b/app/src/code/editor/view/vim_handler.rs @@ -1,8 +1,3 @@ -use vim::vim::{ - BracketChar, CharacterMotion, Direction, FindCharMotion, FirstNonWhitespaceMotion, - InsertPosition, LineMotion, ModeTransition, MotionType, TextObjectType, VimHandler, VimMode, - VimMotion, VimOperand, VimOperator, VimTextObject, WordMotion, -}; use galaxy_editor::content::buffer::{ AutoScrollBehavior, BufferEditAction, EditOrigin, SelectionOffsets, ToBufferCharOffset as _, VimInsertPoint, @@ -13,6 +8,11 @@ use galaxy_editor::selection::{TextDirection, TextUnit}; use galaxyui::text::point::Point; use galaxyui::units::IntoPixels; use galaxyui::{SingletonEntity, ViewContext}; +use vim::vim::{ + BracketChar, CharacterMotion, Direction, FindCharMotion, FirstNonWhitespaceMotion, + InsertPosition, LineMotion, ModeTransition, MotionType, TextObjectType, VimHandler, VimMode, + VimMotion, VimOperand, VimOperator, VimTextObject, WordMotion, +}; use super::{CodeEditorEvent, CodeEditorView}; use crate::code::editor::find::view::Event as FindViewEvent; diff --git a/app/src/code/editor/view/vim_handler_tests.rs b/app/src/code/editor/view/vim_handler_tests.rs index a76cf8c2..43766d99 100644 --- a/app/src/code/editor/view/vim_handler_tests.rs +++ b/app/src/code/editor/view/vim_handler_tests.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -use pathfinder_geometry::vector::Vector2F; -use unindent::Unindent; -use vim::vim::{MotionType, VimMode}; use galaxy_core::features::FeatureFlag; use galaxy_core::settings::Setting; use galaxy_core::ui::appearance::Appearance; @@ -16,6 +13,9 @@ use galaxyui::platform::WindowStyle; use galaxyui::text::point::Point; use galaxyui::units::IntoPixels; use galaxyui::{App, SingletonEntity, TypedActionView, UpdateModel, ViewHandle}; +use pathfinder_geometry::vector::Vector2F; +use unindent::Unindent; +use vim::vim::{MotionType, VimMode}; use crate::auth::AuthStateProvider; use crate::cloud_object::model::persistence::CloudModel; diff --git a/app/src/code/file_tree/view.rs b/app/src/code/file_tree/view.rs index 0b4b7edf..846d58d0 100644 --- a/app/src/code/file_tree/view.rs +++ b/app/src/code/file_tree/view.rs @@ -4,22 +4,12 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use editing::sort_entries_for_file_tree; -use galaxy_util::path::LineAndColumnArg; -use galaxy_util::standardized_path::StandardizedPath; -use itertools::Itertools; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; -use render::RenderState; -use repo_metadata::file_tree_store::{ - FileTreeDirectoryEntryState, FileTreeEntryState, FileTreeFileMetadata, -}; -use repo_metadata::local_model::IndexedRepoState; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::{FileTreeEntry, RepoMetadataModel}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; use galaxy_core::{send_telemetry_from_ctx, HostId}; +use galaxy_util::path::LineAndColumnArg; +use galaxy_util::standardized_path::StandardizedPath; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ AcceptedByDropTarget, Align, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, @@ -37,6 +27,16 @@ use galaxyui::{ id, AppContext, BlurContext, Element, Entity, EventContext, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use itertools::Itertools; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; +use render::RenderState; +use repo_metadata::file_tree_store::{ + FileTreeDirectoryEntryState, FileTreeEntryState, FileTreeFileMetadata, +}; +use repo_metadata::local_model::IndexedRepoState; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::{FileTreeEntry, RepoMetadataModel}; use crate::appearance::Appearance; use crate::code::active_file::{ActiveFileEvent, ActiveFileModel}; @@ -371,8 +371,8 @@ impl FileTreeView { // workspace via `set_remote_root_directories`. let existing_remote_ids: Vec<_> = self .root_directories - .iter() - .filter_map(|(_, root_dir)| { + .values() + .filter_map(|root_dir| { let host_id = root_dir.remote_host_id.as_ref()?; Some(repo_metadata::RemoteRepositoryIdentifier::new( host_id.clone(), diff --git a/app/src/code/file_tree/view/editing.rs b/app/src/code/file_tree/view/editing.rs index 2f7351ff..ca494dec 100644 --- a/app/src/code/file_tree/view/editing.rs +++ b/app/src/code/file_tree/view/editing.rs @@ -7,11 +7,11 @@ mod tests; use std::cmp::Ordering; use std::sync::Arc; -use repo_metadata::file_tree_store::FileTreeEntryState; -use repo_metadata::{FileMetadata, FileTreeEntry}; use galaxy_util::standardized_path::StandardizedPath; use galaxyui::elements::MouseStateHandle; use galaxyui::ViewContext; +use repo_metadata::file_tree_store::FileTreeEntryState; +use repo_metadata::{FileMetadata, FileTreeEntry}; use super::{FileTreeIdentifier, FileTreeItem, FileTreeView}; use crate::code::file_tree::view::{PendingEdit, PendingEditKind}; @@ -29,7 +29,6 @@ pub(super) fn sort_entries_for_file_tree( entry_2: &StandardizedPath, entry_map: &FileTreeEntry, ) -> Ordering { - // Entries missing from the map sort before present entries, and compare // equal to each other. Using the same `Ordering` on both sides would // violate antisymmetry and cause `sorted_by` to panic with diff --git a/app/src/code/file_tree/view/view_tests.rs b/app/src/code/file_tree/view/view_tests.rs index f4fc8ae0..e6a694eb 100644 --- a/app/src/code/file_tree/view/view_tests.rs +++ b/app/src/code/file_tree/view/view_tests.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use galaxy_core::ui::appearance::Appearance; -use galaxyui::{platform::WindowStyle, App, ModelHandle}; +use galaxyui::platform::WindowStyle; +use galaxyui::{App, ModelHandle, SingletonEntity}; use repo_metadata::entry::{DirectoryEntry, Entry, FileMetadata}; use repo_metadata::file_tree_store::FileTreeState; use repo_metadata::local_model::IndexedRepoState; @@ -10,8 +11,6 @@ use repo_metadata::watcher::DirectoryWatcher; use repo_metadata::RepoMetadataModel; use settings::Setting; use virtual_fs::{Stub, VirtualFS}; -use galaxyui::platform::WindowStyle; -use galaxyui::{App, ModelHandle, SingletonEntity}; use super::FileTreeView; use crate::auth::AuthStateProvider; diff --git a/app/src/code/find_references_view.rs b/app/src/code/find_references_view.rs index f933e9da..410a198b 100644 --- a/app/src/code/find_references_view.rs +++ b/app/src/code/find_references_view.rs @@ -6,9 +6,6 @@ use std::collections::HashMap; use std::path::PathBuf; -use lsp::ReferenceLocation; -use pathfinder_geometry::vector::Vector2F; -use string_offset::CharOffset; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::icons::Icon as WarpIcon; use galaxy_core::ui::theme::color::internal_colors; @@ -28,6 +25,9 @@ use galaxyui::ui_components::components::UiComponent; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use lsp::ReferenceLocation; +use pathfinder_geometry::vector::Vector2F; +use string_offset::CharOffset; use super::editor::view::{CodeEditorRenderOptions, CodeEditorView}; use super::global_buffer_model::GlobalBufferModel; @@ -517,7 +517,7 @@ fn render_header( let icon_color = theme.sub_text_color(theme.background()); let close_button = Hoverable::new(back_mouse_state, move |state| { let close_icon = ConstrainedBox::new( - galaxyui::elements::Icon::new(GalaxyIcon::X.into(), icon_color).finish(), + galaxyui::elements::Icon::new(WarpIcon::X.into(), icon_color).finish(), ) .with_width(16.) .with_height(16.) diff --git a/app/src/code/footer.rs b/app/src/code/footer.rs index 6ab60717..cc67c42d 100644 --- a/app/src/code/footer.rs +++ b/app/src/code/footer.rs @@ -2,18 +2,9 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use galaxy_core::send_telemetry_from_ctx; -use lsp::supported_servers::LSPServerType; -use lsp::{ - LanguageId, LanguageServerId, LspManagerModel, LspManagerModelEvent, LspServerModel, - LspState as LspModelState, -}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -#[cfg(feature = "local_fs")] -use repo_metadata::repositories::DetectedRepositories; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::{AnsiColorIdentifier, Fill as ThemeFill, WarpTheme}; +use galaxy_core::ui::theme::{AnsiColorIdentifier, Fill as ThemeFill, GalaxyTheme}; use galaxy_core::ui::Icon; #[cfg(feature = "local_fs")] use galaxy_util::local_or_remote_path::LocalOrRemotePath; @@ -29,6 +20,15 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakModelHandle, }; +use lsp::supported_servers::LSPServerType; +use lsp::{ + LanguageId, LanguageServerId, LspManagerModel, LspManagerModelEvent, LspServerModel, + LspState as LspModelState, +}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +#[cfg(feature = "local_fs")] +use repo_metadata::repositories::DetectedRepositories; #[cfg(feature = "local_fs")] use crate::ai::persisted_workspace::PersistedWorkspaceEvent; diff --git a/app/src/code/global_buffer_model.rs b/app/src/code/global_buffer_model.rs index cd076920..ee870086 100644 --- a/app/src/code/global_buffer_model.rs +++ b/app/src/code/global_buffer_model.rs @@ -7,24 +7,23 @@ use std::time::Duration; use bimap::BiMap; use futures_util::stream::AbortHandle; use galaxy_core::features::FeatureFlag; -use galaxy_editor::content::buffer::Buffer; +use galaxy_core::safe_error; +use galaxy_editor::content::buffer::{Buffer, BufferEvent, ToBufferCharOffset}; use galaxy_editor::content::diff::{text_diff, TextDiff}; use galaxy_editor::content::edit::PreciseDelta; use galaxy_editor::content::version::BufferVersion; use galaxy_util::content_version::ContentVersion; use galaxy_util::file::{FileId, FileLoadError, FileSaveError}; +use galaxy_util::host_id::HostId; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; +use galaxyui::r#async::Timer; use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity, WeakModelHandle}; use lsp::types::TextDocumentContentChangeEvent; use lsp::{LspManagerModel, LspServerLogLevel, LspServerModel}; use remote_server::manager::RemoteServerManager; use string_offset::{ByteOffset, CharOffset}; use vec1::vec1; -use galaxy_core::safe_error; -use galaxy_editor::content::buffer::{Buffer, ToBufferCharOffset}; -use galaxy_util::host_id::HostId; -use galaxy_util::remote_path::RemotePath; -use galaxy_util::standardized_path::StandardizedPath; -use galaxyui::r#async::Timer; use super::buffer_location::{LocalOrRemotePath, SyncClock}; @@ -1208,7 +1207,6 @@ impl GlobalBufferModel { let path_clone = path.to_path_buf(); ctx.subscribe_to_model(&buffer, move |me, _, event, ctx| { - let Some(state) = me.buffers.get(&file_id) else { me.log_lsp_sync_debug( &path_clone, diff --git a/app/src/code/global_buffer_model_tests.rs b/app/src/code/global_buffer_model_tests.rs index df810c86..f8fc5626 100644 --- a/app/src/code/global_buffer_model_tests.rs +++ b/app/src/code/global_buffer_model_tests.rs @@ -1,9 +1,9 @@ +use galaxy_files::FileModel; use lsp::LspManagerModel; use remote_server::proto::TextEdit; use repo_metadata::repositories::DetectedRepositories; use repo_metadata::watcher::DirectoryWatcher; use repo_metadata::RepoMetadataModel; -use warp_files::FileModel; use warp_util::content_version::ContentVersion; use warp_util::host_id::HostId; use warp_util::standardized_path::StandardizedPath; diff --git a/app/src/code/inline_diff.rs b/app/src/code/inline_diff.rs index a2f3e568..9a93b8f5 100644 --- a/app/src/code/inline_diff.rs +++ b/app/src/code/inline_diff.rs @@ -81,11 +81,9 @@ impl InlineDiffView { CodeEditorEvent::UnifiedDiffComputed(diff) => { ctx.emit(InlineDiffViewEvent::DiffAccepted { diff: diff.clone() }); } - CodeEditorEvent::ContentChanged { origin } => { - if origin.from_user() && !me.was_edited { - me.was_edited = true; - ctx.emit(InlineDiffViewEvent::UserEdited); - } + CodeEditorEvent::ContentChanged { origin } if origin.from_user() && !me.was_edited => { + me.was_edited = true; + ctx.emit(InlineDiffViewEvent::UserEdited); } _ => {} }); diff --git a/app/src/code/language_server_extension.rs b/app/src/code/language_server_extension.rs index aa687174..bf4fc4b9 100644 --- a/app/src/code/language_server_extension.rs +++ b/app/src/code/language_server_extension.rs @@ -1,11 +1,7 @@ -use lsp::{HoverContents, LspServerLogLevel, MarkupKind}; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use num_traits::SaturatingSub; -use string_offset::CharOffset; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxy_editor::content::buffer::InitialBufferState; use galaxy_editor::render::element::VerticalExpansionBehavior; use galaxy_editor::render::model::Decoration; @@ -15,6 +11,10 @@ use galaxyui::elements::{ MouseStateHandle, ParentElement, Radius, Rect, ScrollbarWidth, }; use galaxyui::{AppContext, Element, SingletonEntity, ViewContext}; +use lsp::{HoverContents, LspServerLogLevel, MarkupKind}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use num_traits::SaturatingSub; +use string_offset::CharOffset; use super::editor::view::{CodeEditorRenderOptions, CodeEditorView}; use super::lsp_telemetry::LspTelemetryEvent; diff --git a/app/src/code/local_code_editor.rs b/app/src/code/local_code_editor.rs index b2158379..0d0130e0 100644 --- a/app/src/code/local_code_editor.rs +++ b/app/src/code/local_code_editor.rs @@ -11,23 +11,6 @@ use std::{ use ai::diff_validation::DiffType; use futures::stream::AbortHandle; -use lsp::types::FileLocation; -use lsp::{ - LanguageId, LanguageServerId, LspEvent, LspManagerModel, LspManagerModelEvent, LspServerModel, - ReferenceLocation, -}; -use lsp_types::FormattingOptions; -use markdown_parser::FormattedText; -use num_traits::SaturatingSub; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; -use remote_server::manager::RemoteServerManager; -#[cfg(feature = "local_fs")] -use repo_metadata::repositories::DetectedRepositories; -use string_offset::CharOffset; -use vec1::Vec1; -use vim::vim::{MotionType, VimMode}; use galaxy_core::features::FeatureFlag; use galaxy_core::r#async::debounce; use galaxy_core::ui::appearance::Appearance; @@ -57,9 +40,28 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use lsp::types::FileLocation; +use lsp::{ + LanguageId, LanguageServerId, LspEvent, LspManagerModel, LspManagerModelEvent, LspServerModel, + ReferenceLocation, +}; +use lsp_types::FormattingOptions; +use markdown_parser::FormattedText; +use num_traits::SaturatingSub; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; +use remote_server::manager::RemoteServerManager; +#[cfg(feature = "local_fs")] +use repo_metadata::repositories::DetectedRepositories; +use string_offset::CharOffset; +use vec1::Vec1; +use vim::vim::{MotionType, VimMode}; -use crate::ai::persisted_workspace::{PersistedWorkspace, PersistedWorkspaceEvent}; +use crate::ai::persisted_workspace::{LspTask, PersistedWorkspace, PersistedWorkspaceEvent}; use crate::code::buffer_location::LocalOrRemotePath as BufferFileLocation; +use crate::code::code_actions::{CodeActionsState, CODE_ACTIONS_DEBOUNCE_PERIOD}; +use crate::code::completion::{CompletionState, COMPLETION_DEBOUNCE_PERIOD}; use crate::code::editor::model::HoverableLink; use crate::code::editor::EditorReviewComment; use crate::code::footer::{CodeFooterView, CodeFooterViewEvent}; @@ -1165,7 +1167,7 @@ impl LocalCodeEditorView { } // Sort edits by start position in reverse order to avoid offset shifting issues - edits.sort_by(|a, b| b.1.start.cmp(&a.1.start)); + edits.sort_by_key(|b| std::cmp::Reverse(b.1.start)); if let Ok(edits) = Vec1::try_from_vec(edits) { editor.apply_edits(edits, ctx); @@ -1472,7 +1474,6 @@ impl LocalCodeEditorView { /// 5. Starting the LSP server via PersistedWorkspace #[cfg(feature = "local_fs")] fn enable_lsp_for_path(path: &Path, ctx: &mut ViewContext) { - // Get the language ID from the file path let Some(language_id) = LanguageId::from_path(path) else { log::warn!("Enable lsp for path should only work for supported file paths"); @@ -1516,7 +1517,6 @@ impl LocalCodeEditorView { /// and emits events that are handled by handle_persisted_workspace_event. #[cfg(feature = "local_fs")] fn install_and_enable_lsp_for_path(path: &Path, ctx: &mut ViewContext) { - let Some(language_id) = LanguageId::from_path(path) else { log::warn!("Install and enable lsp for path should only work for supported file paths"); return; diff --git a/app/src/code/mod.rs b/app/src/code/mod.rs index 857e3bfd..57d261ba 100644 --- a/app/src/code/mod.rs +++ b/app/src/code/mod.rs @@ -2,10 +2,10 @@ use std::any::Any; use std::fmt::Debug; use std::ops::AddAssign; -use pathfinder_geometry::rect::RectF; use galaxy_util::file::FileSaveError; use galaxyui::elements::DropTargetData; use galaxyui::AppContext; +use pathfinder_geometry::rect::RectF; #[cfg(not(target_family = "wasm"))] pub mod code_actions; diff --git a/app/src/code/opened_files.rs b/app/src/code/opened_files.rs index 22f73f38..872a9b1f 100644 --- a/app/src/code/opened_files.rs +++ b/app/src/code/opened_files.rs @@ -3,9 +3,9 @@ use std::collections::HashMap; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui::{Entity, ModelContext, SingletonEntity}; use instant::Instant; -use galaxy_util::local_or_remote_path::LocalOrRemotePath; /// Tracks opened files within a single repository. /// Keys are repo-relative file paths (e.g. `src/main.rs`). diff --git a/app/src/code/rename.rs b/app/src/code/rename.rs index 0e4ce794..38d569e7 100644 --- a/app/src/code/rename.rs +++ b/app/src/code/rename.rs @@ -6,11 +6,12 @@ use lsp::types::Location; use string_offset::CharOffset; use vec1::Vec1; +use super::local_code_editor::LocalCodeEditorView; use crate::editor::{EditorView, Event as EditorEvent, SingleLineEditorOptions, TextOptions}; -use super::local_code_editor::LocalCodeEditorView; - +#[derive(Default)] pub(super) enum RenameState { + #[default] Idle, Preparing { abort_handle: AbortHandle, @@ -24,12 +25,6 @@ pub(super) enum RenameState { }, } -impl Default for RenameState { - fn default() -> Self { - Self::Idle - } -} - impl RenameState { pub fn dismiss(&mut self) -> bool { match self { @@ -262,7 +257,7 @@ impl LocalCodeEditorView { return; } - edits_for_current_file.sort_by(|a, b| b.1.start.cmp(&a.1.start)); + edits_for_current_file.sort_by_key(|b| std::cmp::Reverse(b.1.start)); if let Ok(edits) = Vec1::try_from_vec(edits_for_current_file) { self.editor.update(ctx, |editor, ctx| { diff --git a/app/src/code/signature_help.rs b/app/src/code/signature_help.rs index 88cd5b00..2c365597 100644 --- a/app/src/code/signature_help.rs +++ b/app/src/code/signature_help.rs @@ -16,7 +16,9 @@ use super::local_code_editor::LocalCodeEditorView; const SIGNATURE_HELP_MAX_WIDTH: f32 = 500.; /// State for signature help display. +#[derive(Default)] pub(super) enum SignatureHelpState { + #[default] None, Loading(Option), Showing { @@ -25,12 +27,6 @@ pub(super) enum SignatureHelpState { }, } -impl Default for SignatureHelpState { - fn default() -> Self { - Self::None - } -} - impl SignatureHelpState { pub fn clear(&mut self) -> bool { if matches!(self, Self::None) { @@ -73,10 +69,8 @@ impl LocalCodeEditorView { Some('(') | Some(',') => { self.request_signature_help(cursor_offset, ctx); } - Some(')') => { - if self.signature_help_state.clear() { - ctx.notify(); - } + Some(')') if self.signature_help_state.clear() => { + ctx.notify(); } _ => {} } diff --git a/app/src/code/view.rs b/app/src/code/view.rs index 28f72eeb..891e40e5 100644 --- a/app/src/code/view.rs +++ b/app/src/code/view.rs @@ -1,10 +1,6 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; -use lsp::LspManagerModel; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::vec2f; use galaxy_core::channel::{Channel, ChannelState}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; @@ -30,6 +26,10 @@ use galaxyui::{ id, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use lsp::LspManagerModel; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::vec2f; use super::buffer_location::LocalOrRemotePath; use super::diff_viewer::DiffViewer; diff --git a/app/src/code_review/code_review_header/header_revamp.rs b/app/src/code_review/code_review_header/header_revamp.rs index 0d8af6eb..406a4e8c 100644 --- a/app/src/code_review/code_review_header/header_revamp.rs +++ b/app/src/code_review/code_review_header/header_revamp.rs @@ -5,7 +5,6 @@ //! //! Separated into its own module so the two codepaths are easy to distinguish. -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, CrossAxisAlignment, Flex, @@ -13,6 +12,7 @@ use galaxyui::elements::{ ParentOffsetBounds, Shrinkable, Stack, }; use galaxyui::{Element, ViewHandle}; +use pathfinder_geometry::vector::vec2f; use super::CodeReviewHeader; use crate::appearance::Appearance; diff --git a/app/src/code_review/code_review_header/mod.rs b/app/src/code_review/code_review_header/mod.rs index 140d1fbe..95040c21 100644 --- a/app/src/code_review/code_review_header/mod.rs +++ b/app/src/code_review/code_review_header/mod.rs @@ -1,6 +1,5 @@ mod header_revamp; -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ Align, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, CrossAxisAlignment, Flex, @@ -13,6 +12,7 @@ use galaxyui::platform::Cursor; use galaxyui::ui_components::button::{ButtonVariant, TextAndIcon, TextAndIconAlignment}; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, ModelHandle, ViewHandle}; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::code_review::code_review_view::{ diff --git a/app/src/code_review/code_review_view.rs b/app/src/code_review/code_review_view.rs index ab2130d1..45ecb40c 100644 --- a/app/src/code_review/code_review_view.rs +++ b/app/src/code_review/code_review_view.rs @@ -6,6 +6,11 @@ use std::sync::Arc; use std::time::Duration; use ai::project_context::model::ProjectContextModel; +use galaxy_core::channel::{Channel, ChannelState}; +use galaxy_core::features::FeatureFlag; +use galaxy_core::ui::theme::color::internal_colors; +use galaxy_core::ui::theme::GalaxyTheme; +use galaxy_core::{safe_error, safe_info, SessionId}; use indexmap::IndexMap; use itertools::Itertools; #[cfg(feature = "local_fs")] @@ -16,10 +21,6 @@ use rand::distributions::Alphanumeric; use rand::Rng; use string_offset::CharOffset; use vec1::Vec1; -use galaxy_core::channel::{Channel, ChannelState}; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::{safe_error, safe_info, SessionId}; use warp_editor::content::buffer::{AutoScrollBehavior, InitialBufferState, SelectionOffsets}; use warp_editor::model::CoreEditorModel; use warp_editor::render::element::VerticalExpansionBehavior; @@ -65,6 +66,7 @@ use crate::ai::agent::{ AIAgentAttachment, AgentReviewCommentBatch, CurrentHead, DiffBase, DiffSetHunk, }; use crate::ai::blocklist::agent_view::AgentViewEntryOrigin; +use crate::ai::persisted_workspace::{LspTask, PersistedWorkspace}; use crate::appearance::Appearance; use crate::code::buffer_location::LocalOrRemotePath; use crate::code::editor::comment_editor::DEFAULT_COMMENT_MAX_WIDTH; @@ -921,7 +923,6 @@ impl CodeReviewView { server_type: Option, ctx: &mut ViewContext, ) { - let server_type = server_type.or_else(|| lsp::LanguageId::from_path(path).map(|id| id.server_type())); let Some(server_type) = server_type else { @@ -5664,28 +5665,25 @@ impl CodeReviewView { ctx ); } - CodeEditorEvent::ContentChanged { origin, .. } => { - if origin.from_user() { - if let Some((view_handle, content_version)) = self.last_revert.take() { - let same_content_version = - content_version == editor.as_ref(ctx).version(ctx); + CodeEditorEvent::ContentChanged { origin, .. } if origin.from_user() => { + if let Some((view_handle, content_version)) = self.last_revert.take() { + let same_content_version = content_version == editor.as_ref(ctx).version(ctx); - // If the revert was for a different editor or the content version is the same, keep the revert. - if view_handle.id() != editor.id() || same_content_version { - self.last_revert = Some((view_handle, content_version)); - } else { - self.last_revert = None; - self.dismiss_revert_toast(ctx); - } + // If the revert was for a different editor or the content version is the same, keep the revert. + if view_handle.id() != editor.id() || same_content_version { + self.last_revert = Some((view_handle, content_version)); + } else { + self.last_revert = None; + self.dismiss_revert_toast(ctx); } + } - if self.find_model.as_ref(ctx).is_find_bar_open() - && FeatureFlag::CodeReviewFind.is_enabled() - { - self.find_model.update(ctx, |model, model_ctx| { - model.run_search(self.editor_handles(), model_ctx); - }); - } + if self.find_model.as_ref(ctx).is_find_bar_open() + && FeatureFlag::CodeReviewFind.is_enabled() + { + self.find_model.update(ctx, |model, model_ctx| { + model.run_search(self.editor_handles(), model_ctx); + }); } } _ => {} diff --git a/app/src/code_review/code_review_view_tests.rs b/app/src/code_review/code_review_view_tests.rs index 42068456..85adbe56 100644 --- a/app/src/code_review/code_review_view_tests.rs +++ b/app/src/code_review/code_review_view_tests.rs @@ -3,10 +3,10 @@ use std::sync::Arc; use ai::agent::action::InsertReviewComment; use chrono::Local; -use lsp::LspManagerModel; -use repo_metadata::repositories::DetectedRepositories; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; +use lsp::LspManagerModel; +use repo_metadata::repositories::DetectedRepositories; use warp_editor::content::buffer::InitialBufferState; use warp_editor::render::element::VerticalExpansionBehavior; use warp_editor::render::model::LineCount; diff --git a/app/src/code_review/comment_list_view.rs b/app/src/code_review/comment_list_view.rs index caccbf59..daf2e28a 100644 --- a/app/src/code_review/comment_list_view.rs +++ b/app/src/code_review/comment_list_view.rs @@ -1,10 +1,5 @@ use std::borrow::Cow; -use indexmap::IndexMap; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use string_offset::CharOffset; -use vec1::vec1; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::color::internal_colors::{ @@ -35,6 +30,11 @@ use galaxyui::{ AppContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use indexmap::IndexMap; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use string_offset::CharOffset; +use vec1::vec1; use crate::ai::request_usage_model::{AIRequestUsageModel, AIRequestUsageModelEvent}; use crate::appearance::Appearance; diff --git a/app/src/code_review/comment_rendering.rs b/app/src/code_review/comment_rendering.rs index 8d4b69ce..0b7e0f06 100644 --- a/app/src/code_review/comment_rendering.rs +++ b/app/src/code_review/comment_rendering.rs @@ -6,9 +6,9 @@ use std::rc::Rc; use chrono::{Duration, Local}; -use pathfinder_color::ColorU; use galaxy_core::ui::theme::color::internal_colors::{neutral_1, neutral_2, text_sub}; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; use warp_editor::content::buffer::InitialBufferState; use warp_editor::render::element::VerticalExpansionBehavior; use warpui::elements::new_scrollable::ScrollableAppearance; diff --git a/app/src/code_review/comments/flatten.rs b/app/src/code_review/comments/flatten.rs index b99c8ca1..e1cd5a27 100644 --- a/app/src/code_review/comments/flatten.rs +++ b/app/src/code_review/comments/flatten.rs @@ -131,7 +131,7 @@ fn collect_pending_imported_thread_dfs<'a>( // Get children of this comment. if let Some(children) = children_map.get(comment.github_comment_id()) { let mut sorted_children = children.to_vec(); - sorted_children.sort_by(|a, b| a.last_update_time.cmp(&b.last_update_time)); + sorted_children.sort_by_key(|a| a.last_update_time); for child in sorted_children { collect_pending_imported_thread_dfs(child, children_map, result); } diff --git a/app/src/code_review/diff_selector.rs b/app/src/code_review/diff_selector.rs index f61c87d9..34007f0e 100644 --- a/app/src/code_review/diff_selector.rs +++ b/app/src/code_review/diff_selector.rs @@ -1,6 +1,5 @@ //! Trigger button + [`CodeReviewDiffMenu`] overlay for picking the diff //! target in the code review header. -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element, @@ -17,6 +16,7 @@ use galaxyui::{ id, AppContext, Entity, FocusContext, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::code_review::diff_menu::{CodeReviewDiffMenu, CodeReviewDiffMenuEvent}; diff --git a/app/src/code_review/diff_state/mod.rs b/app/src/code_review/diff_state/mod.rs index 5a0196a9..1acf90cc 100644 --- a/app/src/code_review/diff_state/mod.rs +++ b/app/src/code_review/diff_state/mod.rs @@ -10,8 +10,8 @@ use std::sync::Arc; use std::time::Duration; use anyhow::Result; -use serde::{Deserialize, Serialize}; use galaxy_core::SessionId; +use serde::{Deserialize, Serialize}; use warp_util::remote_path::RemotePath; use warp_util::standardized_path::StandardizedPath; use warpui::{AppContext, ModelContext, ModelHandle}; diff --git a/app/src/code_review/diff_state/remote.rs b/app/src/code_review/diff_state/remote.rs index 967f230c..ca0e58d2 100644 --- a/app/src/code_review/diff_state/remote.rs +++ b/app/src/code_review/diff_state/remote.rs @@ -10,9 +10,9 @@ use std::sync::Arc; +use galaxy_core::{send_telemetry_from_ctx, HostId, SessionId}; use instant::Instant; use remote_server::manager::{RemoteServerManager, RemoteServerManagerEvent}; -use galaxy_core::{send_telemetry_from_ctx, HostId, SessionId}; use warp_util::remote_path::RemotePath; use warp_util::standardized_path::StandardizedPath; use warpui::{ModelContext, SingletonEntity}; diff --git a/app/src/code_review/find_model.rs b/app/src/code_review/find_model.rs index 8a23cb96..02f67ebe 100644 --- a/app/src/code_review/find_model.rs +++ b/app/src/code_review/find_model.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::ops::Range; -use string_offset::CharOffset; #[cfg(not(target_family = "wasm"))] use galaxy_core::channel::ChannelState; use galaxy_core::send_telemetry_from_ctx; @@ -12,6 +11,7 @@ use galaxy_editor::search::Searcher; use galaxy_editor::search::{RestorableSearchResults, SelectedResult}; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{AppContext, Entity, EntityId, ModelContext, ViewHandle, WeakViewHandle}; +use string_offset::CharOffset; use crate::code::local_code_editor::LocalCodeEditorView; use crate::code_review::code_review_view::CodeReviewView; diff --git a/app/src/code_review/find_model_tests.rs b/app/src/code_review/find_model_tests.rs index 4545a8ec..a66349a1 100644 --- a/app/src/code_review/find_model_tests.rs +++ b/app/src/code_review/find_model_tests.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; use std::sync::Arc; +use galaxy_core::ui::appearance::Appearance; use repo_metadata::repositories::DetectedRepositories; use string_offset::CharOffset; -use galaxy_core::ui::appearance::Appearance; use warp_editor::content::buffer::InitialBufferState; use warp_editor::render::element::VerticalExpansionBehavior; use warpui::elements::Empty; diff --git a/app/src/code_review/git_dialog/mod.rs b/app/src/code_review/git_dialog/mod.rs index 08017b47..d6186652 100644 --- a/app/src/code_review/git_dialog/mod.rs +++ b/app/src/code_review/git_dialog/mod.rs @@ -9,7 +9,6 @@ //! + confirm async, extend `GitDialogMode`, add the per-mode action and //! outcome variant, and wire up dispatch. -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; @@ -26,6 +25,7 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::code::buffer_location::LocalOrRemotePath; use crate::code::editor::{add_color, remove_color}; diff --git a/app/src/code_review/git_repo_model/local.rs b/app/src/code_review/git_repo_model/local.rs index cc4d06eb..c3e5c856 100644 --- a/app/src/code_review/git_repo_model/local.rs +++ b/app/src/code_review/git_repo_model/local.rs @@ -2,10 +2,10 @@ use std::path::{Path, PathBuf}; use std::time::Duration; use async_channel::Sender; -use repo_metadata::repository::{RepositorySubscriber, SubscriberId}; -use repo_metadata::{Repository, RepositoryUpdate}; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{Entity, ModelContext, ModelHandle}; +use repo_metadata::repository::{RepositorySubscriber, SubscriberId}; +use repo_metadata::{Repository, RepositoryUpdate}; use super::{GitRepoStatusEvent, GitStatusMetadata}; use crate::code_review::diff_state::diff_metadata_against_head; diff --git a/app/src/code_review/mod.rs b/app/src/code_review/mod.rs index 2f3019f2..bdba0127 100644 --- a/app/src/code_review/mod.rs +++ b/app/src/code_review/mod.rs @@ -24,12 +24,13 @@ pub(crate) mod diff_selector; #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub(crate) mod file_invalidation_queue; +use std::path::{Path, PathBuf}; + use code_review_view::CodeReviewAction; use galaxyui::keymap::{EditableBinding, FixedBinding}; use galaxyui::{ id, AppContext, Entity, EntityId, ModelContext, SingletonEntity, WeakViewHandle, WindowId, }; -use std::path::{Path, PathBuf}; use crate::code::buffer_location::LocalOrRemotePath; use crate::code_review::telemetry_event::CodeReviewPaneEntrypoint; diff --git a/app/src/code_review/telemetry_event.rs b/app/src/code_review/telemetry_event.rs index 9bd68c3a..86fa319e 100644 --- a/app/src/code_review/telemetry_event.rs +++ b/app/src/code_review/telemetry_event.rs @@ -1,6 +1,7 @@ use std::fmt::Display; use std::time::Duration; +use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; use serde::Serialize; use serde_json::json; use serde_with::SerializeDisplay; diff --git a/app/src/coding_entrypoints/glowing_editor.rs b/app/src/coding_entrypoints/glowing_editor.rs index fb7468eb..29e32c37 100644 --- a/app/src/coding_entrypoints/glowing_editor.rs +++ b/app/src/coding_entrypoints/glowing_editor.rs @@ -1,5 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::Icon; use galaxyui::elements::{ @@ -7,11 +5,15 @@ use galaxyui::elements::{ MainAxisAlignment, ParentElement as _, Radius, Shrinkable, }; use galaxyui::fonts::Weight; -use galaxyui::ui_components::components::{BorderStyle, Coords, UiComponent as _, UiComponentStyles}; +use galaxyui::ui_components::components::{ + BorderStyle, Coords, UiComponent as _, UiComponentStyles, +}; use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; use crate::editor::{EditorOptions, EditorView, Event as EditorEvent, TextOptions}; @@ -94,11 +96,9 @@ impl GlowingEditor { } EditorEvent::Escape => ctx.emit(GlowingEditorEvent::Cancel), // Clear error state when user types (since this is submit-only validation) - EditorEvent::Edited(_) => { - if self.has_error { - self.has_error = false; - ctx.notify(); - } + EditorEvent::Edited(_) if self.has_error => { + self.has_error = false; + ctx.notify(); } _ => (), } diff --git a/app/src/coding_entrypoints/project_buttons.rs b/app/src/coding_entrypoints/project_buttons.rs index 5b1589b1..f2dd941a 100644 --- a/app/src/coding_entrypoints/project_buttons.rs +++ b/app/src/coding_entrypoints/project_buttons.rs @@ -1,7 +1,5 @@ use std::borrow::Cow; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::blend::Blend as _; @@ -20,6 +18,8 @@ use galaxyui::ui_components::components::{UiComponent as _, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; use crate::util::bindings::{keybinding_name_to_display_string, BindingGroup, CustomAction}; diff --git a/app/src/completer/test.rs b/app/src/completer/test.rs index 83be6bcc..0f1a0d74 100644 --- a/app/src/completer/test.rs +++ b/app/src/completer/test.rs @@ -2,15 +2,13 @@ use std::collections::{HashMap, HashSet}; use std::iter::FromIterator; use std::sync::Arc; -use galaxy_completer::completer::PathCompletionContext; -use galaxy_completer::completer::{CompletionContext, EngineDirEntry}; +use galaxy_completer::completer::{CompletionContext, EngineDirEntry, PathCompletionContext}; use galaxy_completer::signatures::CommandRegistry; use galaxyui::App; use itertools::Itertools; use typed_path::TypedPathBuf; #[cfg(windows)] use typed_path::{UnixComponent, WindowsComponent, WindowsPrefix}; -use galaxy_completer::completer::{CompletionContext, EngineDirEntry, PathCompletionContext}; use crate::completer::SessionContext; use crate::terminal::model::session::command_executor::testing::TestCommandExecutor; diff --git a/app/src/context_chips/current_prompt.rs b/app/src/context_chips/current_prompt.rs index cc275f55..af89c7ce 100644 --- a/app/src/context_chips/current_prompt.rs +++ b/app/src/context_chips/current_prompt.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use std::time::Duration; use futures::{pin_mut, FutureExt as _}; -use itertools::Itertools; use galaxy_completer::completer::CommandExitStatus; use galaxy_core::r#async::debounce; use galaxy_core::user_preferences::GetUserPreferences; @@ -13,6 +12,7 @@ use galaxyui::{ AppContext, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity, ViewHandle, WeakModelHandle, }; +use itertools::Itertools; use super::context_chip::{ ChipAvailability, ChipFingerprintInput, ChipRuntimeCapabilities, ContextChip, Environment, diff --git a/app/src/context_chips/current_prompt_tests.rs b/app/src/context_chips/current_prompt_tests.rs index d0f25415..a7bf6263 100644 --- a/app/src/context_chips/current_prompt_tests.rs +++ b/app/src/context_chips/current_prompt_tests.rs @@ -3,6 +3,7 @@ use std::collections::{HashMap, VecDeque}; use std::sync::Arc; use async_trait::async_trait; +use galaxy_completer::completer::{CommandExitStatus, CommandOutput}; use galaxy_core::command::ExitCode; use galaxyui::{App, SingletonEntity}; use galaxyui_extras::user_preferences; @@ -11,7 +12,6 @@ use parking_lot::Mutex; #[cfg(feature = "local_fs")] use repo_metadata::DirectoryWatcher; use settings::Setting as _; -use galaxy_completer::completer::{CommandExitStatus, CommandOutput}; use super::{ChipUpdateStatus, CurrentPrompt, PromptContext}; use crate::auth::auth_manager::AuthManager; diff --git a/app/src/context_chips/directory_fetcher.rs b/app/src/context_chips/directory_fetcher.rs index 1657bf37..a3f13289 100644 --- a/app/src/context_chips/directory_fetcher.rs +++ b/app/src/context_chips/directory_fetcher.rs @@ -1,10 +1,10 @@ use std::cmp::Ordering; -use typed_path::TypedPathBuf; use galaxy_completer::completer::{EngineDirEntry, EngineFileType}; use galaxy_util::file_type::is_binary_file; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{AppContext, Entity, ModelContext}; +use typed_path::TypedPathBuf; use super::display_menu::GenericMenuItem; use crate::completer::SessionContext; diff --git a/app/src/context_chips/display_chip.rs b/app/src/context_chips/display_chip.rs index ff30fb4f..152ce7c4 100644 --- a/app/src/context_chips/display_chip.rs +++ b/app/src/context_chips/display_chip.rs @@ -2,11 +2,11 @@ use std::borrow::Cow; use std::path::PathBuf; use std::sync::Arc; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use warpui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, Hoverable, MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement, diff --git a/app/src/context_chips/display_menu.rs b/app/src/context_chips/display_menu.rs index be2b4d90..1c57c86e 100644 --- a/app/src/context_chips/display_menu.rs +++ b/app/src/context_chips/display_menu.rs @@ -5,8 +5,6 @@ use std::rc::Rc; use std::sync::Arc; use fuzzy_match::{match_indices_case_insensitive, FuzzyMatchResult}; -use instant::Instant; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::builder::MIN_FONT_SIZE; use galaxy_core::ui::theme::color::internal_colors; @@ -31,6 +29,8 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use instant::Instant; +use pathfinder_geometry::vector::vec2f; use crate::ai::cloud_environments::CloudAmbientAgentEnvironment; use crate::cloud_object::model::generic_string_model::StringModel; diff --git a/app/src/context_chips/mod.rs b/app/src/context_chips/mod.rs index 23a421c3..54acbe0b 100644 --- a/app/src/context_chips/mod.rs +++ b/app/src/context_chips/mod.rs @@ -19,11 +19,11 @@ use std::collections::HashMap; use std::time::Duration; use context_chip::PromptGenerator; -use serde::{Deserialize, Serialize}; -use smol_str::SmolStr; use galaxyui::color::ColorU; use galaxyui::elements::Text; use galaxyui::fonts::{Properties, Weight}; +use serde::{Deserialize, Serialize}; +use smol_str::SmolStr; #[allow(unused_imports)] pub use self::context_chip::{ @@ -629,11 +629,8 @@ pub fn chips_to_string(chips: impl Iterator) -> String { match (chip_kind, next_chip_kind) { // Omit the space between adjacent Svn chips. (ContextChipKind::SvnBranch, Some(ContextChipKind::SvnDirtyItems)) => (), - (_, Some(_)) => { - // Add padding after non-empty chips. - if !chip_display_value.is_empty() { - prompt.push(' '); - } + (_, Some(_)) if !chip_display_value.is_empty() => { + prompt.push(' '); } _ => (), } diff --git a/app/src/context_chips/node_version_popup.rs b/app/src/context_chips/node_version_popup.rs index 8482d425..7c773eed 100644 --- a/app/src/context_chips/node_version_popup.rs +++ b/app/src/context_chips/node_version_popup.rs @@ -1,4 +1,6 @@ -use pathfinder_color::ColorU; +use std::env; +use std::path::Path; + use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -12,6 +14,7 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use crate::menu::{self, Event as MenuEvent, Menu, MenuItemFields}; use crate::terminal::model_events::{ModelEvent, ModelEventDispatcher}; @@ -514,7 +517,6 @@ fn detect_nvm_installed() -> bool { // Enumerate installed Node versions managed by nvm (best-effort, cross-OS) fn list_nvm_versions() -> Vec { - let mut out: Vec = Vec::new(); #[cfg(windows)] diff --git a/app/src/context_chips/prompt.rs b/app/src/context_chips/prompt.rs index 478276e5..411f915d 100644 --- a/app/src/context_chips/prompt.rs +++ b/app/src/context_chips/prompt.rs @@ -1,9 +1,9 @@ -use itertools::Itertools; -use serde::{Deserialize, Serialize}; -use settings::Setting as _; use galaxyui::{ Entity, GetSingletonModelHandle, ModelContext, ModelHandle, SingletonEntity, UpdateModel, }; +use itertools::Itertools; +use serde::{Deserialize, Serialize}; +use settings::Setting as _; pub use super::ContextChipKind; use crate::settings::{ diff --git a/app/src/context_chips/renderer.rs b/app/src/context_chips/renderer.rs index 265c366d..15b700f1 100644 --- a/app/src/context_chips/renderer.rs +++ b/app/src/context_chips/renderer.rs @@ -1,7 +1,5 @@ //! The renderer for a single context chip. -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, DraggableState, Flex, Hoverable, @@ -11,6 +9,8 @@ use galaxyui::fonts::{Properties, Weight}; use galaxyui::platform::Cursor; use galaxyui::ui_components::components::UiComponent; use galaxyui::{Action, Element}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use super::context_chip::ContextChip; use super::display_chip::{chip_container, udi_font_size}; diff --git a/app/src/crash_reporting/mod.rs b/app/src/crash_reporting/mod.rs index 8ced059f..9e4df156 100644 --- a/app/src/crash_reporting/mod.rs +++ b/app/src/crash_reporting/mod.rs @@ -12,7 +12,11 @@ use std::ops::DerefMut; use std::sync::Arc; use galaxy_core::channel::Channel; -use galaxyui::{r#async::block_on, AppContext, SingletonEntity}; +use galaxyui::r#async::block_on; +use galaxyui::rendering::GPUDeviceInfo; +use galaxyui::windowing::state::ApplicationStage; +use galaxyui::windowing::{self, StateEvent, WindowManager}; +use galaxyui::{AppContext, SingletonEntity}; use lazy_static::lazy_static; use parking_lot::{Mutex, RwLock}; use regex::Regex; @@ -20,11 +24,6 @@ use sentry::{ClientInitGuard, IntoDsn, SessionMode}; #[cfg(linux_or_windows)] pub use sentry_minidump::run_server as run_minidump_server; use warp_server_auth::anonymous_id::get_or_create_anonymous_id; -use galaxyui::r#async::block_on; -use galaxyui::rendering::GPUDeviceInfo; -use galaxyui::windowing::state::ApplicationStage; -use galaxyui::windowing::{self, StateEvent, WindowManager}; -use galaxyui::{AppContext, SingletonEntity}; use crate::antivirus::{AntivirusInfo, AntivirusInfoEvent}; use crate::auth::{AuthStateProvider, UserUid}; diff --git a/app/src/default_terminal/mac.rs b/app/src/default_terminal/mac.rs index 0e557651..8cbd0ffb 100644 --- a/app/src/default_terminal/mac.rs +++ b/app/src/default_terminal/mac.rs @@ -1,8 +1,8 @@ use std::ptr::NonNull; +use galaxy_core::channel::{Channel, ChannelState}; use objc2_core_foundation::{CFRetained, CFString}; use objc2_foundation::NSBundle; -use galaxy_core::channel::{Channel, ChannelState}; // Launch Services constants type LSRolesMask = u32; diff --git a/app/src/drive/cloud_object_styling.rs b/app/src/drive/cloud_object_styling.rs index 406ba22f..08a5aac3 100644 --- a/app/src/drive/cloud_object_styling.rs +++ b/app/src/drive/cloud_object_styling.rs @@ -1,8 +1,8 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::contrast::MinimumAllowedContrast; use galaxy_core::ui::color::ContrastingColor; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; use super::DriveObjectType; use crate::ui_components::blended_colors; diff --git a/app/src/drive/drive_helpers.rs b/app/src/drive/drive_helpers.rs index e510e6be..5b9df400 100644 --- a/app/src/drive/drive_helpers.rs +++ b/app/src/drive/drive_helpers.rs @@ -1,7 +1,7 @@ +use galaxyui::{AppContext, SingletonEntity}; use warp_server_auth::auth_state::AuthState; use warp_server_auth::user::PersonalObjectLimits; use warp_server_auth::AuthStateProvider; -use galaxyui::{AppContext, SingletonEntity}; use crate::auth::auth_manager::AuthManager; use crate::cloud_object::model::persistence::CloudModel; diff --git a/app/src/drive/import/modal.rs b/app/src/drive/import/modal.rs index adff5eb4..694582f2 100644 --- a/app/src/drive/import/modal.rs +++ b/app/src/drive/import/modal.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ Align, Border, ChildAnchor, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, @@ -13,6 +12,7 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use super::modal_body::{ImportModalBody, ImportModalBodyAction, ImportModalBodyEvent}; use crate::appearance::Appearance; @@ -20,7 +20,7 @@ use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::{CloudObject, Owner}; use crate::server::ids::SyncId; use crate::server::sync_queue::SyncQueue; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::workspaces::user_workspaces::UserWorkspaces; const CLOSE_BUTTON_SIZE: f32 = 24.; diff --git a/app/src/drive/import/modal_body.rs b/app/src/drive/import/modal_body.rs index 42f0ba7c..15aa3fbd 100644 --- a/app/src/drive/import/modal_body.rs +++ b/app/src/drive/import/modal_body.rs @@ -1,7 +1,6 @@ use std::path::PathBuf; use futures_util::stream::AbortHandle; -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ Align, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, @@ -13,6 +12,7 @@ use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use pathfinder_geometry::vector::vec2f; use super::modal::BODY_HEIGHT; use super::nodes::{ diff --git a/app/src/drive/import/nodes.rs b/app/src/drive/import/nodes.rs index 007472af..2e4f7b74 100644 --- a/app/src/drive/import/nodes.rs +++ b/app/src/drive/import/nodes.rs @@ -6,11 +6,11 @@ use std::path::{Path, PathBuf}; use anyhow::Result; use async_recursion::async_recursion; use futures_lite::StreamExt; -use pathfinder_color::ColorU; use galaxyui::elements::{ Align, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Hoverable, MouseStateHandle, ParentElement, Radius, Shrinkable, }; +use pathfinder_color::ColorU; use warpui::platform::Cursor; use warpui::ui_components::components::{UiComponent, UiComponentStyles}; use warpui::Element; diff --git a/app/src/drive/index.rs b/app/src/drive/index.rs index 86eec834..7e78a0f0 100644 --- a/app/src/drive/index.rs +++ b/app/src/drive/index.rs @@ -3,10 +3,6 @@ use std::collections::HashMap; use std::sync::Arc; use futures::Future; -use itertools::Itertools; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -use url::Url; use galaxy_core::context_flag::ContextFlag; use galaxy_core::settings::Setting; use galaxy_core::ui::theme::color::internal_colors; @@ -31,7 +27,10 @@ use galaxyui::{ AppContext, BlurContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, UpdateView, View, ViewContext, ViewHandle, WindowId, }; -use std::{any::Any, collections::HashMap, sync::Arc}; +use itertools::Itertools; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +use url::Url; use super::cloud_object_naming_dialog::CloudObjectNamingDialog; use super::drive_helpers::{ @@ -406,6 +405,7 @@ impl DriveIndexAction { impl From<&DriveIndexAction> for LoginGatedFeature { fn from(val: &DriveIndexAction) -> LoginGatedFeature { + use DriveIndexAction::*; match val { OpenTeamSettingsPage => "Open Team Settings", ViewPlans { .. } => "View Plans", @@ -3306,16 +3306,16 @@ impl DriveIndex { return; } } - CloudObjectTypeAndId::Workflow(_) => { - if !UserWorkspaces::has_capacity_for_shared_workflows(team_uid, ctx, 1) { - // If team has reached the limit for workflows, show the modal - // and return early. - ctx.emit(DriveIndexEvent::OpenSharedObjectsCreationDeniedModal( - DriveObjectType::Workflow, - team_uid, - )); - return; - } + CloudObjectTypeAndId::Workflow(_) + if !UserWorkspaces::has_capacity_for_shared_workflows(team_uid, ctx, 1) => + { + // If team has reached the limit for workflows, show the modal + // and return early. + ctx.emit(DriveIndexEvent::OpenSharedObjectsCreationDeniedModal( + DriveObjectType::Workflow, + team_uid, + )); + return; } _ => (), } @@ -3630,19 +3630,17 @@ impl DriveIndex { return; } } - CloudObjectTypeAndId::Workflow(_) => { - if has_feature_gated_anonymous_user_reached_workflow_limit(ctx) { - return; - } + CloudObjectTypeAndId::Workflow(_) + if has_feature_gated_anonymous_user_reached_workflow_limit(ctx) => + { + return; } CloudObjectTypeAndId::GenericStringObject { object_type: GenericStringObjectFormat::Json(JsonObjectType::EnvVarCollection), id: _, - } => { - if has_feature_gated_anonymous_user_reached_env_var_limit(ctx) { - return; - } + } if has_feature_gated_anonymous_user_reached_env_var_limit(ctx) => { + return; } _ => {} }, diff --git a/app/src/drive/items/env_var_collection.rs b/app/src/drive/items/env_var_collection.rs index 8c859115..e8f7d428 100644 --- a/app/src/drive/items/env_var_collection.rs +++ b/app/src/drive/items/env_var_collection.rs @@ -1,9 +1,9 @@ -use itertools::Itertools; use galaxy_core::context_flag::ContextFlag; use galaxyui::elements::{Clipped, Container, Flex, MouseStateHandle, ParentElement}; use galaxyui::fonts::Weight; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use itertools::Itertools; use super::{WarpDriveItem, WarpDriveItemId}; use crate::appearance::Appearance; diff --git a/app/src/drive/items/item.rs b/app/src/drive/items/item.rs index 1e210574..9c1e5931 100644 --- a/app/src/drive/items/item.rs +++ b/app/src/drive/items/item.rs @@ -1,5 +1,3 @@ -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; use galaxyui::elements::{ AcceptedByDropTarget, Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Draggable, DraggableState, DropShadow, Empty, Flex, Hoverable, @@ -13,6 +11,8 @@ use galaxyui::presenter::PositionCache; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::ui_components::text::Span; use galaxyui::{AppContext, Element, SingletonEntity, ViewHandle}; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; use super::WarpDriveItemId; use crate::appearance::Appearance; diff --git a/app/src/drive/mod.rs b/app/src/drive/mod.rs index 626d11db..89c67eac 100644 --- a/app/src/drive/mod.rs +++ b/app/src/drive/mod.rs @@ -17,12 +17,14 @@ use std::cmp::Ordering; use std::fmt; pub use cloud_objects::drive::CloudObjectTypeAndId; +use galaxyui::AppContext; pub use index::DriveIndexVariant; pub use panel::{DrivePanel, DrivePanelEvent}; use serde::{Deserialize, Serialize}; use crate::cloud_object::model::view::{CloudViewModel, UpdateTimestamp}; use crate::cloud_object::{CloudObject, ObjectType}; +use crate::galaxy_core::user_preferences::GetUserPreferences; use crate::server::ids::ServerId; use crate::ui_components::icons::Icon; use crate::workflows::CloudWorkflow; @@ -44,6 +46,9 @@ pub struct OpenWarpDriveObjectArgs { pub settings: OpenWarpDriveObjectSettings, } +pub type OpenGalaxyDriveObjectSettings = OpenWarpDriveObjectSettings; +pub type OpenGalaxyDriveObjectArgs = OpenWarpDriveObjectArgs; + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum DriveObjectType { Workflow, diff --git a/app/src/drive/panel.rs b/app/src/drive/panel.rs index db8e17b4..7c26cd2a 100644 --- a/app/src/drive/panel.rs +++ b/app/src/drive/panel.rs @@ -379,17 +379,18 @@ impl DrivePanel { return; } } - CloudObjectTypeAndId::Workflow(_) => { - if !UserWorkspaces::has_capacity_for_shared_workflows(team_uid, ctx, 1) - { - // If team has reached the limit for workflows, show the modal - // and return early. - ctx.emit(DrivePanelEvent::OpenSharedObjectsCreationDeniedModal( - DriveObjectType::Workflow, - team_uid, - )); - return; - } + CloudObjectTypeAndId::Workflow(_) + if !UserWorkspaces::has_capacity_for_shared_workflows( + team_uid, ctx, 1, + ) => + { + // If team has reached the limit for workflows, show the modal + // and return early. + ctx.emit(DrivePanelEvent::OpenSharedObjectsCreationDeniedModal( + DriveObjectType::Workflow, + team_uid, + )); + return; } _ => (), } @@ -400,19 +401,17 @@ impl DrivePanel { return; } } - CloudObjectTypeAndId::Workflow(_) => { - if has_feature_gated_anonymous_user_reached_workflow_limit(ctx) { - return; - } + CloudObjectTypeAndId::Workflow(_) + if has_feature_gated_anonymous_user_reached_workflow_limit(ctx) => + { + return; } CloudObjectTypeAndId::GenericStringObject { object_type: GenericStringObjectFormat::Json(JsonObjectType::EnvVarCollection), id: _, - } => { - if has_feature_gated_anonymous_user_reached_env_var_limit(ctx) { - return; - } + } if has_feature_gated_anonymous_user_reached_env_var_limit(ctx) => { + return; } _ => {} }, diff --git a/app/src/drive/settings.rs b/app/src/drive/settings.rs index 98e115a5..b2f047c1 100644 --- a/app/src/drive/settings.rs +++ b/app/src/drive/settings.rs @@ -1,6 +1,6 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; use galaxy_core::features::FeatureFlag; +use settings::macros::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use super::DriveSortOrder; diff --git a/app/src/drive/sharing/dialog/mod.rs b/app/src/drive/sharing/dialog/mod.rs index 3950201e..339cc87c 100644 --- a/app/src/drive/sharing/dialog/mod.rs +++ b/app/src/drive/sharing/dialog/mod.rs @@ -1,13 +1,13 @@ use std::borrow::Cow; use email_address::EmailAddress; +use galaxy_core::ui::appearance::Appearance; +use galaxy_core::ui::theme::Fill as ThemeFill; use inheritance::{InheritanceDetails, InheritanceState}; use itertools::Itertools; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; use session_sharing_protocol::common::{Guest, PendingGuest, SessionId, TeamAclData}; -use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::theme::Fill as ThemeFill; use warp_editor::editor::NavigationKey; use warpui::clipboard::ClipboardContent; use warpui::elements::{ diff --git a/app/src/drive/sharing/mod.rs b/app/src/drive/sharing/mod.rs index 16b0567a..c503e7bb 100644 --- a/app/src/drive/sharing/mod.rs +++ b/app/src/drive/sharing/mod.rs @@ -1,12 +1,12 @@ use std::borrow::Cow; use chrono::{DateTime, Local}; -use session_sharing_protocol::common::SessionId; use galaxy_core::channel::ChannelState; use galaxy_core::ui::appearance::Appearance; use galaxyui::color::ColorU; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, SingletonEntity, WeakViewHandle}; +use session_sharing_protocol::common::SessionId; use crate::ai::agent::conversation::AIConversationId; use crate::ai::blocklist::BlocklistAIHistoryModel; diff --git a/app/src/drive/workflows/enum_creation_dialog.rs b/app/src/drive/workflows/enum_creation_dialog.rs index 525418c1..4f784770 100644 --- a/app/src/drive/workflows/enum_creation_dialog.rs +++ b/app/src/drive/workflows/enum_creation_dialog.rs @@ -1,7 +1,5 @@ use std::rc::Rc; -use strum::IntoEnumIterator; -use strum_macros::{EnumIter, IntoStaticStr}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_editor::editor::NavigationKey; @@ -17,6 +15,8 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use strum::IntoEnumIterator; +use strum_macros::{EnumIter, IntoStaticStr}; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::Revision; diff --git a/app/src/drive/workflows/modal.rs b/app/src/drive/workflows/modal.rs index cec9fc7d..21a3b628 100644 --- a/app/src/drive/workflows/modal.rs +++ b/app/src/drive/workflows/modal.rs @@ -2,9 +2,6 @@ use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::sync::Arc; -use itertools::Itertools; -use pathfinder_geometry::vector::vec2f; -use string_offset::CharOffset; use galaxy_core::ui::theme::Fill; use galaxy_editor::editor::NavigationKey; use galaxyui::clipboard::ClipboardContent; @@ -23,6 +20,9 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, UpdateView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; +use pathfinder_geometry::vector::vec2f; +use string_offset::CharOffset; use super::arguments::ArgumentsState; use super::enum_creation_dialog::{EnumCreationDialog, EnumCreationDialogEvent, WorkflowEnumData}; diff --git a/app/src/drive/workflows/workflow_arg_selector.rs b/app/src/drive/workflows/workflow_arg_selector.rs index fa1968c4..c6b353ad 100644 --- a/app/src/drive/workflows/workflow_arg_selector.rs +++ b/app/src/drive/workflows/workflow_arg_selector.rs @@ -1,9 +1,6 @@ use std::collections::HashMap; use std::rc::Rc; -use itertools::Itertools; -use strum::IntoEnumIterator; -use strum_macros::{EnumIter, IntoStaticStr}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxy_editor::editor::NavigationKey; @@ -23,7 +20,9 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; -use std::{collections::HashMap, rc::Rc}; +use itertools::Itertools; +use strum::IntoEnumIterator; +use strum_macros::{EnumIter, IntoStaticStr}; use super::enum_creation_dialog::WorkflowEnumData; use crate::editor::{ diff --git a/app/src/editor/accept_autosuggestion_keybinding_view.rs b/app/src/editor/accept_autosuggestion_keybinding_view.rs index 74d5eb2c..90a23874 100644 --- a/app/src/editor/accept_autosuggestion_keybinding_view.rs +++ b/app/src/editor/accept_autosuggestion_keybinding_view.rs @@ -1,8 +1,8 @@ //! This module contains the code for the editable accept autosuggestion keybinding //! shown inline in the input. +use galaxy_core::ui::theme::Fill; use lazy_static::lazy_static; use pathfinder_geometry::vector::vec2f; -use galaxy_core::ui::theme::Fill; use warpui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element, Flex, Hoverable, MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement, diff --git a/app/src/editor/autosuggestion_ignore_view.rs b/app/src/editor/autosuggestion_ignore_view.rs index 09ea9dc7..45298332 100644 --- a/app/src/editor/autosuggestion_ignore_view.rs +++ b/app/src/editor/autosuggestion_ignore_view.rs @@ -1,6 +1,5 @@ //! This module contains the code for the ignore button shown inline next to autosuggestions. -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, CornerRadius, Element, Hoverable, MouseStateHandle, @@ -9,6 +8,7 @@ use galaxyui::elements::{ use galaxyui::platform::Cursor; use galaxyui::ui_components::components::UiComponent; use galaxyui::{Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use pathfinder_geometry::vector::vec2f; use super::EditorElement; use crate::appearance::Appearance; diff --git a/app/src/editor/mod.rs b/app/src/editor/mod.rs index e49b824f..770411e5 100644 --- a/app/src/editor/mod.rs +++ b/app/src/editor/mod.rs @@ -6,12 +6,12 @@ mod view; use std::cmp; use std::ops::Range; +pub use galaxyui::text::point::Point; +use galaxyui::AppContext; /// Consumers of the editor should only interface with the view. /// They should _not_ be able to interface with the internal /// details of the editor (e.g. the [`Buffer`]). pub use view::*; -pub use galaxyui::text::point::Point; -use galaxyui::AppContext; // Re-exported for use by the `warp_tui` TUI front-end, which needs to // construct and subscribe to `CodeEditorModel` in char-cell mode. diff --git a/app/src/editor/soft_wrap.rs b/app/src/editor/soft_wrap.rs index b3be0517..1d11d884 100644 --- a/app/src/editor/soft_wrap.rs +++ b/app/src/editor/soft_wrap.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use anyhow::anyhow; -use parking_lot::Mutex; use galaxyui::text_layout; +use parking_lot::Mutex; use crate::editor::view::DisplayPoint; use crate::editor::Point; diff --git a/app/src/editor/view/element.rs b/app/src/editor/view/element.rs index 1f7011ce..88b3f146 100644 --- a/app/src/editor/view/element.rs +++ b/app/src/editor/view/element.rs @@ -4,14 +4,14 @@ use std::sync::{Arc, Mutex}; use std::time::Duration; use std::{cmp, mem}; +use galaxy_core::features::FeatureFlag; +use galaxy_core::ui::appearance::DEFAULT_UI_FONT_SIZE; use instant::Instant; use itertools::Itertools; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::{vec2f, Vector2F}; use smallvec::SmallVec; use vim::vim::{MotionType, VimMode}; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::appearance::DEFAULT_UI_FONT_SIZE; use warp_util::user_input::UserInput; use warpui::elements::{ AfterLayoutContext, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, diff --git a/app/src/editor/view/marked_text_tests.rs b/app/src/editor/view/marked_text_tests.rs index 18b20280..55a17a98 100644 --- a/app/src/editor/view/marked_text_tests.rs +++ b/app/src/editor/view/marked_text_tests.rs @@ -1,9 +1,8 @@ use galaxy_core::features::FeatureFlag; -use galaxyui::{keymap::Keystroke, platform::WindowStyle, App}; -use vim::vim::VimMode; use galaxyui::keymap::Keystroke; use galaxyui::platform::WindowStyle; use galaxyui::App; +use vim::vim::VimMode; use super::initialize_app; use crate::editor::{DisplayPoint, EditorOptions, EditorView}; diff --git a/app/src/editor/view/mod.rs b/app/src/editor/view/mod.rs index db01656b..daa45b0a 100644 --- a/app/src/editor/view/mod.rs +++ b/app/src/editor/view/mod.rs @@ -23,6 +23,8 @@ use base64::engine::general_purpose; use base64::Engine as _; use element::CommandXRayMouseStateHandle; use figma_utils::is_figma_png; +use galaxy_core::semantic_selection::SemanticSelection; +use galaxy_core::{safe_error, send_telemetry_from_ctx}; use itertools::{Either, Itertools}; use mime_guess::from_path; use model::{ @@ -49,12 +51,10 @@ use vim::{ vim_inner_quote, vim_inner_word, vim_word_iterator_from_offset, }; use warp_completer::completer::Description; -use galaxy_core::semantic_selection::SemanticSelection; -use galaxy_core::{safe_error, send_telemetry_from_ctx}; use warp_editor::editor::NavigationKey; use warp_util::path::ShellFamily; use warp_util::user_input::UserInput; -use warpui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use warpui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use warpui::actions::StandardAction; use warpui::clipboard::ClipboardContent; use warpui::elements::{ @@ -7482,11 +7482,8 @@ impl EditorView { } fn focused_in_active_window(&self, ctx: &AppContext) -> bool { - let active = self - .windowing_state_handle - .as_ref(ctx) - .state() - .active_window; + let manager = self.windowing_state_handle.as_ref(ctx); + let active = manager.state().active_window.or_else(|| manager.active_window()); Some(self.window_id) == active && self.focused } diff --git a/app/src/editor/view/mod_tests.rs b/app/src/editor/view/mod_tests.rs index 7eb1a6aa..fea47c90 100644 --- a/app/src/editor/view/mod_tests.rs +++ b/app/src/editor/view/mod_tests.rs @@ -1,13 +1,13 @@ use anyhow::Error; +use galaxyui::color::ColorU; +use galaxyui::platform::WindowStyle; +use galaxyui::text_layout::{LayoutCache, TextFrame}; +use galaxyui::windowing::WindowManager; +use galaxyui::{AddSingletonModel, App, UpdateModel, UpdateView}; use itertools::Itertools; use pathfinder_geometry::vector::vec2f; use settings::ToggleableSetting; use unindent::Unindent; -use warpui::color::ColorU; -use warpui::platform::WindowStyle; -use warpui::text_layout::TextFrame; -use warpui::windowing::WindowManager; -use warpui::{AddSingletonModel, App, UpdateModel, UpdateView}; use super::*; use crate::auth::AuthStateProvider; @@ -2317,7 +2317,6 @@ fn test_partial_autosuggestion() -> Result<()> { #[test] fn test_placeholder_text() { - App::test((), |mut app| async move { initialize_app(&mut app); diff --git a/app/src/editor/view/model/buffer/mod_tests.rs b/app/src/editor/view/model/buffer/mod_tests.rs index 9d1fa419..9cf36c7e 100644 --- a/app/src/editor/view/model/buffer/mod_tests.rs +++ b/app/src/editor/view/model/buffer/mod_tests.rs @@ -9,11 +9,10 @@ use std::pin::{pin, Pin}; use async_channel::Receiver; use enclose::enclose; use futures::StreamExt; -use galaxyui::{color::ColorU, App, ModelHandle}; -use rand::prelude::StdRng; -use test::Network; use galaxyui::color::ColorU; use galaxyui::{App, ModelHandle}; +use rand::prelude::StdRng; +use test::Network; use super::*; use crate::editor::soft_wrap::ClampDirection; diff --git a/app/src/editor/view/model/buffer/subword_boundaries.rs b/app/src/editor/view/model/buffer/subword_boundaries.rs index 3ff83f01..a4be6c7e 100644 --- a/app/src/editor/view/model/buffer/subword_boundaries.rs +++ b/app/src/editor/view/model/buffer/subword_boundaries.rs @@ -1,9 +1,9 @@ use std::iter::Peekable; -use itertools::Either; use galaxyui::text::word_boundaries::WordBoundariesApproach; use galaxyui::text::words::is_subword_boundary_char; use galaxyui::text::TextBuffer; +use itertools::Either; use super::{CharOffset, Point}; diff --git a/app/src/editor/view/model/display_map/fold_map.rs b/app/src/editor/view/model/display_map/fold_map.rs index 9de6cefc..31567ed4 100644 --- a/app/src/editor/view/model/display_map/fold_map.rs +++ b/app/src/editor/view/model/display_map/fold_map.rs @@ -3,8 +3,10 @@ use std::iter::Take; use std::ops::Range; use anyhow::{anyhow, Result}; +use galaxyui::{AppContext, ModelHandle}; use string_offset::CharOffset; use sum_tree::{self, Cursor, Dimension, SeekBias, SumTree}; +use warpui::text_layout::TextStyle; use super::super::buffer::{AnchorRangeExt, TextSummary}; use super::buffer::StylizedChar; diff --git a/app/src/editor/view/model/display_map/mod.rs b/app/src/editor/view/model/display_map/mod.rs index a99458ea..f1f45e33 100644 --- a/app/src/editor/view/model/display_map/mod.rs +++ b/app/src/editor/view/model/display_map/mod.rs @@ -6,9 +6,11 @@ use std::ops::Range; use anyhow::{Context, Result}; pub use fold_map::BufferRows; use fold_map::FoldMap; +use galaxyui::{AppContext, Entity, ModelContext, ModelHandle}; use string_offset::CharOffset; use super::buffer::{self, Anchor, Buffer, Edit, StylizedChar, ToCharOffset, ToPoint}; +use super::Point; use crate::editor::soft_wrap::{self, DisplayPointAndClampDirection, SoftWrapPoint, SoftWrapState}; #[derive(Copy, Clone)] diff --git a/app/src/editor/view/model/mod.rs b/app/src/editor/view/model/mod.rs index e8983bd8..6d3a887a 100644 --- a/app/src/editor/view/model/mod.rs +++ b/app/src/editor/view/model/mod.rs @@ -35,8 +35,8 @@ use vim::{ vim_a_quote, vim_a_word, vim_find_char_on_line, vim_find_matching_bracket, vim_inner_block, vim_inner_paragraph, vim_inner_quote, vim_inner_word, vim_word_iterator_from_offset, }; -use warpui::accessibility::{AccessibilityContent, WarpA11yRole}; -use warpui::text::point::Point; +use warpui::accessibility::{AccessibilityContent, GalaxyA11yRole}; +pub use warpui::text::point::Point; use warpui::text::word_boundaries::WordBoundariesPolicy; use warpui::text::TextBuffer; use warpui::text_layout::TextStyle; diff --git a/app/src/editor/view/model/mod_tests.rs b/app/src/editor/view/model/mod_tests.rs index 73d05072..e25d14fc 100644 --- a/app/src/editor/view/model/mod_tests.rs +++ b/app/src/editor/view/model/mod_tests.rs @@ -1,8 +1,7 @@ -use galaxyui::{text_layout::TextStyle, App}; -use string_offset::{ByteOffset, CharOffset}; -use vec1::vec1; use galaxyui::text_layout::TextStyle; use galaxyui::App; +use string_offset::{ByteOffset, CharOffset}; +use vec1::vec1; use super::{EditOrigin, EditorModel, Edits, InteractionState, UpdateBufferOption}; use crate::editor::{EditorSnapshot, PlainTextEditorViewAction, TextRun, ValidInputType}; diff --git a/app/src/editor/view/vim_handler_tests.rs b/app/src/editor/view/vim_handler_tests.rs index bed07862..5ab10a14 100644 --- a/app/src/editor/view/vim_handler_tests.rs +++ b/app/src/editor/view/vim_handler_tests.rs @@ -1,7 +1,7 @@ -use itertools::Itertools; -use unindent::Unindent; use galaxyui::platform::WindowStyle; use galaxyui::{App, EntityIdSet, ViewHandle}; +use itertools::Itertools; +use unindent::Unindent; use super::*; use crate::editor::EditorView; diff --git a/app/src/editor/view/voice.rs b/app/src/editor/view/voice.rs index 9c4dc0ea..9a90e203 100644 --- a/app/src/editor/view/voice.rs +++ b/app/src/editor/view/voice.rs @@ -1,8 +1,8 @@ -use settings::Setting as _; -use voice_input::{StartListeningError, VoiceInput, VoiceSessionResult}; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::AnsiColorIdentifier; +use settings::Setting as _; +use voice_input::{StartListeningError, VoiceInput, VoiceSessionResult}; use warpui::elements::{Container, CornerRadius, Icon, Radius}; use warpui::platform::Cursor; use warpui::r#async::SpawnedFutureHandle; diff --git a/app/src/env_vars/env_var_collection_block.rs b/app/src/env_vars/env_var_collection_block.rs index fdac8cf2..ae6be1cd 100644 --- a/app/src/env_vars/env_var_collection_block.rs +++ b/app/src/env_vars/env_var_collection_block.rs @@ -2,9 +2,6 @@ use std::borrow::Cow; use std::rc::Rc; use std::sync::Arc; -use lazy_static::lazy_static; -use parking_lot::RwLock; -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxy_core::semantic_selection::SemanticSelection; use galaxy_core::ui::Icon; @@ -18,6 +15,9 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, }; +use lazy_static::lazy_static; +use parking_lot::RwLock; +use settings::Setting as _; use crate::ai::agent::icons::{yellow_running_icon, yellow_stop_icon}; use crate::ai::blocklist::block::view_impl::{ diff --git a/app/src/env_vars/mod.rs b/app/src/env_vars/mod.rs index 6570b508..828cf691 100644 --- a/app/src/env_vars/mod.rs +++ b/app/src/env_vars/mod.rs @@ -1,8 +1,8 @@ pub use cloud_object_models::{ CloudEnvVarCollection, CloudEnvVarCollectionModel, EnvVar, EnvVarCollection, EnvVarValue, }; -use itertools::Itertools; use galaxy_util::path::ShellFamily; +use itertools::Itertools; pub mod active_env_var_collection_data; pub mod env_var_collection_block; diff --git a/app/src/env_vars/view/env_var_collection.rs b/app/src/env_vars/view/env_var_collection.rs index c64abcfd..d6f593d8 100644 --- a/app/src/env_vars/view/env_var_collection.rs +++ b/app/src/env_vars/view/env_var_collection.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_core::features::FeatureFlag; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ @@ -16,6 +15,7 @@ use galaxyui::{ id, AppContext, BlurContext, Element, Entity, FocusContext, ModelAsRef, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::command_dialog::EnvVarCommandDialog; use super::menus::Menus; diff --git a/app/src/env_vars/view/fixed_view_components.rs b/app/src/env_vars/view/fixed_view_components.rs index b0085e18..48ea12c1 100644 --- a/app/src/env_vars/view/fixed_view_components.rs +++ b/app/src/env_vars/view/fixed_view_components.rs @@ -1,5 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ Align, ConstrainedBox, Container, CrossAxisAlignment, Empty, Flex, MainAxisAlignment, @@ -9,6 +7,8 @@ use galaxyui::fonts::Weight; use galaxyui::ui_components::button::{ButtonVariant, TextAndIcon, TextAndIconAlignment}; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{Element, ViewContext}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; use crate::drive::sharing::{ContentEditability, SharingAccessLevel}; use crate::env_vars::active_env_var_collection_data::TrashStatus; diff --git a/app/src/env_vars/view/menus.rs b/app/src/env_vars/view/menus.rs index df312d79..4d776d91 100644 --- a/app/src/env_vars/view/menus.rs +++ b/app/src/env_vars/view/menus.rs @@ -1,8 +1,7 @@ use galaxy_core::context_flag::ContextFlag; -use galaxyui::{keymap::Trigger, SingletonEntity, ViewContext, ViewHandle}; -use pathfinder_geometry::vector::Vector2F; use galaxyui::keymap::Trigger; use galaxyui::{SingletonEntity, ViewContext, ViewHandle}; +use pathfinder_geometry::vector::Vector2F; use super::env_var_collection::{EnvVarCollectionAction, EnvVarCollectionView, VariableRowIndex}; use crate::cloud_object::{CloudObject, GenericStringObjectFormat, Space}; diff --git a/app/src/env_vars/view/secrets.rs b/app/src/env_vars/view/secrets.rs index 51f8bdc0..c06fbf63 100644 --- a/app/src/env_vars/view/secrets.rs +++ b/app/src/env_vars/view/secrets.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ @@ -12,6 +11,7 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; #[cfg(not(target_family = "wasm"))] use galaxyui::SingletonEntity; use galaxyui::{Element, ViewContext}; +use pathfinder_geometry::vector::vec2f; use super::env_var_collection::{ EnvVarCollectionAction, EnvVarCollectionView, VariableRowIndex, CORE_MAX_WIDTH, ROW_SPACING, diff --git a/app/src/experiments/improved_palette_search_layer.rs b/app/src/experiments/improved_palette_search_layer.rs index 81d636ad..0a16ef29 100644 --- a/app/src/experiments/improved_palette_search_layer.rs +++ b/app/src/experiments/improved_palette_search_layer.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use std::str::FromStr; -use lazy_static::lazy_static; use galaxyui::AppContext; +use lazy_static::lazy_static; use crate::experiments::{BucketRange, Experiment, Layer}; diff --git a/app/src/experiments/mod.rs b/app/src/experiments/mod.rs index 7da545d4..1cafaed9 100644 --- a/app/src/experiments/mod.rs +++ b/app/src/experiments/mod.rs @@ -18,11 +18,11 @@ use std::str::FromStr; use anyhow::Result; pub use block_onboarding_layer::{BlockOnboarding, BLOCK_ONBOARDING_LAYER}; use dashmap::DashMap; +use galaxy_core::user_preferences::GetUserPreferences as _; +use galaxyui::{AppContext, SingletonEntity}; pub use improved_palette_search_layer::{ImprovedPaletteSearch, IMPROVED_PALETTE_SEARCH_LAYER}; use lazy_static::lazy_static; pub use login_layer::{AuthFlowInstructions, LOGIN_LAYER}; -use galaxy_core::user_preferences::GetUserPreferences as _; -use galaxyui::{AppContext, SingletonEntity}; use crate::auth::auth_state::AuthStateProvider; use crate::channel::{Channel, ChannelState}; diff --git a/app/src/features.rs b/app/src/features.rs index 750e8f10..21771809 100644 --- a/app/src/features.rs +++ b/app/src/features.rs @@ -122,7 +122,7 @@ fn enabled_features() -> HashSet { #[cfg(all(not(windows), feature = "kitty_images"))] FeatureFlag::KittyImages, #[cfg(feature = "warp_packs")] - FeatureFlag::WarpPacks, + FeatureFlag::GalaxyPacks, #[cfg(feature = "global_ai_analytics_banner")] FeatureFlag::GlobalAIAnalyticsBanner, #[cfg(feature = "global_ai_analytics_collection")] diff --git a/app/src/galaxy_managed_paths_watcher.rs b/app/src/galaxy_managed_paths_watcher.rs index 9224b29f..fdbca2b9 100644 --- a/app/src/galaxy_managed_paths_watcher.rs +++ b/app/src/galaxy_managed_paths_watcher.rs @@ -52,8 +52,8 @@ pub(crate) fn galaxy_home_config_dir() -> Option { } #[cfg_attr(target_family = "wasm", allow(dead_code))] -pub(crate) fn warp_home_skills_dir() -> Option { - galaxy_core::paths::warp_home_skills_dir() +pub(crate) fn galaxy_home_skills_dir() -> Option { + galaxy_core::paths::galaxy_home_skills_dir() } #[cfg_attr(target_family = "wasm", allow(dead_code))] @@ -63,18 +63,18 @@ pub(crate) fn galaxy_home_mcp_config_file_path() -> Option { #[cfg_attr(target_family = "wasm", allow(dead_code))] #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct GalaxyMcpConfigPath { +pub struct GalaxyMcpConfigPath { pub(crate) root_path: PathBuf, pub(crate) config_path: PathBuf, } #[cfg_attr(target_family = "wasm", allow(dead_code))] -pub(crate) fn warp_managed_skill_dirs() -> Vec { - warp_home_skills_dir().into_iter().collect() +pub fn warp_managed_skill_dirs() -> Vec { + galaxy_home_skills_dir().into_iter().collect() } #[cfg_attr(target_family = "wasm", allow(dead_code))] -pub(crate) fn galaxy_managed_mcp_config_path() -> Option { +pub fn galaxy_managed_mcp_config_path() -> Option { Some(GalaxyMcpConfigPath { root_path: home_dir()?, config_path: galaxy_home_mcp_config_file_path()?, @@ -204,20 +204,20 @@ fn filesystem_event_to_repository_update(event: &BulkFilesystemWatcherEvent) -> #[cfg(target_family = "wasm")] #[allow(dead_code)] -pub(crate) enum GalaxyManagedPathsWatcherEvent {} +pub enum GalaxyManagedPathsWatcherEvent {} #[cfg(not(target_family = "wasm"))] -pub(crate) enum GalaxyManagedPathsWatcherEvent { +pub enum GalaxyManagedPathsWatcherEvent { FilesChanged(RepositoryUpdate), } #[cfg(not(target_family = "wasm"))] -pub(crate) struct GalaxyManagedPathsWatcher { +pub struct GalaxyManagedPathsWatcher { _watcher: ModelHandle, } #[cfg(target_family = "wasm")] -pub(crate) struct GalaxyManagedPathsWatcher; +pub struct GalaxyManagedPathsWatcher; #[cfg(not(target_family = "wasm"))] impl GalaxyManagedPathsWatcher { @@ -300,7 +300,7 @@ impl GalaxyManagedPathsWatcher { Self::register_path( ctx, &watcher, - warp_home_config_dir, + galaxy_home_config_dir, WatchFilter::with_filter(Arc::new(|_: &Path| true), emit), RecursiveMode::NonRecursive, "Galaxy home MCP config directory", @@ -366,6 +366,11 @@ impl Entity for GalaxyManagedPathsWatcher { impl SingletonEntity for GalaxyManagedPathsWatcher {} +pub type WarpManagedPathsWatcher = GalaxyManagedPathsWatcher; +pub type WarpManagedPathsWatcherEvent = GalaxyManagedPathsWatcherEvent; +pub use galaxy_managed_mcp_config_path as warp_managed_mcp_config_path; +pub use warp_managed_skill_dirs as galaxy_managed_skill_dirs; + #[cfg(test)] #[path = "warp_managed_paths_watcher_tests.rs"] mod tests; diff --git a/app/src/input_suggestions.rs b/app/src/input_suggestions.rs index ebc30998..6312ff5f 100644 --- a/app/src/input_suggestions.rs +++ b/app/src/input_suggestions.rs @@ -6,15 +6,12 @@ use std::{cmp, vec}; use async_channel::Sender; use chrono::{DateTime, Local}; use fuzzy_match::match_indices; -use itertools::Itertools; -use pathfinder_geometry::vector::vec2f; -use warp_command_signatures::IconType; use galaxy_completer::completer::{ MatchType, PathSeparators, Suggestion, SuggestionResults, SuggestionType, }; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::AnsiColorIdentifier; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ Align, AnchorPair, Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, DropShadow, Element, Empty, EventHandler, Expanded, @@ -29,7 +26,9 @@ use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles use galaxyui::{ AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, WeakViewHandle, }; -use std::{cmp, ops::Range, vec}; +use itertools::Itertools; +use pathfinder_geometry::vector::vec2f; +use warp_command_signatures::IconType; use crate::ai::blocklist::{render_ai_agent_mode_icon, AIQueryHistory, AIQueryHistoryOutputStatus}; use crate::appearance::Appearance; diff --git a/app/src/integration_testing/agent_mode/assertions.rs b/app/src/integration_testing/agent_mode/assertions.rs index 0d4eaf2a..38966b38 100644 --- a/app/src/integration_testing/agent_mode/assertions.rs +++ b/app/src/integration_testing/agent_mode/assertions.rs @@ -3,9 +3,9 @@ // `assert!` causes the app to crash before debug info can be exported. Use `integration_assert!` instead. #![deny(clippy::assertions_on_constants)] -use warp_multi_agent_api as api; use galaxyui::integration::{AssertionCallback, AssertionOutcome}; use galaxyui::{integration_assert, EntityId, SingletonEntity}; +use warp_multi_agent_api as api; use super::llm_judge::{LLMJudge, LLMJudgeConfig}; use crate::ai::agent::conversation::{AIConversation, AIConversationId, ConversationStatus}; diff --git a/app/src/integration_testing/agent_mode/mod.rs b/app/src/integration_testing/agent_mode/mod.rs index c9414a07..855f1add 100644 --- a/app/src/integration_testing/agent_mode/mod.rs +++ b/app/src/integration_testing/agent_mode/mod.rs @@ -8,6 +8,7 @@ use std::fs::File; use std::io::Write; pub use assertions::*; +use command::blocking::Command; use galaxyui::integration::PersistedDataMap; pub use galaxyui::integration::RUNTIME_TAG_FAILURE_REASON; use galaxyui::{App, SingletonEntity as _, WindowId}; @@ -95,7 +96,6 @@ pub fn output_code_diff_debug_info(app: &mut App, window_id: WindowId) { let mut output_file = open_debug_file_from_env(CODE_DIFF_OUTPUT_FILE_ENV_VAR); if let Some(output_file) = &mut output_file { - if edited_files.is_empty() { writeln!(output_file, "No files were edited for this test") .expect("Failed to write to code diff file"); diff --git a/app/src/integration_testing/agent_mode/step.rs b/app/src/integration_testing/agent_mode/step.rs index 008274fa..29c5559d 100644 --- a/app/src/integration_testing/agent_mode/step.rs +++ b/app/src/integration_testing/agent_mode/step.rs @@ -3,10 +3,9 @@ use std::io::Cursor; use std::path::Path; use std::time::Duration; -use galaxyui::{async_assert, integration::TestStep, SingletonEntity}; -use prost::Message; use galaxyui::integration::TestStep; use galaxyui::{async_assert, SingletonEntity}; +use prost::Message; use crate::ai::execution_profiles::profiles::AIExecutionProfilesModel; use crate::ai::execution_profiles::ActionPermission; diff --git a/app/src/integration_testing/block/assertions.rs b/app/src/integration_testing/block/assertions.rs index 3af91a79..e096de7b 100644 --- a/app/src/integration_testing/block/assertions.rs +++ b/app/src/integration_testing/block/assertions.rs @@ -1,7 +1,7 @@ -use settings::Setting as _; use galaxyui::integration::{AssertionCallback, AssertionOutcome}; use galaxyui::units::{IntoPixels, Lines}; use galaxyui::{async_assert, async_assert_eq, AppContext, SingletonEntity, WindowId}; +use settings::Setting as _; use crate::integration_testing::terminal::util::ExpectedOutput; use crate::integration_testing::view_getters::{ diff --git a/app/src/integration_testing/cloud_object/mod.rs b/app/src/integration_testing/cloud_object/mod.rs index c8a0eb68..3ac4ed33 100644 --- a/app/src/integration_testing/cloud_object/mod.rs +++ b/app/src/integration_testing/cloud_object/mod.rs @@ -6,8 +6,8 @@ use std::pin::Pin; pub use assertion::*; use futures::future::join_all; use futures::FutureExt; -use itertools::Itertools; use galaxyui::{App, SingletonEntity}; +use itertools::Itertools; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::Space; diff --git a/app/src/integration_testing/codebase_context/step.rs b/app/src/integration_testing/codebase_context/step.rs index 19b6c03d..5b392a26 100644 --- a/app/src/integration_testing/codebase_context/step.rs +++ b/app/src/integration_testing/codebase_context/step.rs @@ -2,9 +2,9 @@ use std::path::PathBuf; use std::time::Duration; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; -use settings::Setting; use galaxyui::integration::{AssertionOutcome, StepData, TestStep}; use galaxyui::{async_assert, App, ReadModel, SingletonEntity, UpdateModel, WindowId}; +use settings::Setting; use crate::integration_testing::step::new_step_with_default_assertions; use crate::settings::CodeSettings; diff --git a/app/src/integration_testing/goto_line.rs b/app/src/integration_testing/goto_line.rs index f080fe60..b739fd2e 100644 --- a/app/src/integration_testing/goto_line.rs +++ b/app/src/integration_testing/goto_line.rs @@ -1,7 +1,7 @@ -use settings::Setting as _; use galaxy_editor::content::buffer::ToBufferPoint; use galaxyui::integration::AssertionCallback; use galaxyui::{async_assert, async_assert_eq, App, SingletonEntity, ViewHandle, WindowId}; +use settings::Setting as _; use crate::code::editor::goto_line::view::GoToLineView; use crate::code::editor::view::CodeEditorView; diff --git a/app/src/integration_testing/input/step.rs b/app/src/integration_testing/input/step.rs index ea9839c0..33224328 100644 --- a/app/src/integration_testing/input/step.rs +++ b/app/src/integration_testing/input/step.rs @@ -1,8 +1,7 @@ use galaxyui::integration::TestStep; -use galaxyui::{windowing::WindowManager, SingletonEntity}; -use pathfinder_geometry::vector::Vector2F; use galaxyui::windowing::WindowManager; use galaxyui::SingletonEntity; +use pathfinder_geometry::vector::Vector2F; use crate::ai::blocklist::agent_view::AgentInputFooterEvent; use crate::ai::blocklist::{InputConfig, InputType}; diff --git a/app/src/integration_testing/notebook/assertion.rs b/app/src/integration_testing/notebook/assertion.rs index 736a663c..34fb889f 100644 --- a/app/src/integration_testing/notebook/assertion.rs +++ b/app/src/integration_testing/notebook/assertion.rs @@ -1,8 +1,8 @@ -use itertools::Itertools; -use string_offset::CharOffset; use galaxy_editor::render::model::BlockItem; use galaxyui::integration::{AssertionCallback, AssertionOutcome, AssertionWithDataCallback}; use galaxyui::{async_assert, async_assert_eq, App, ViewHandle}; +use itertools::Itertools; +use string_offset::CharOffset; use crate::cloud_object::model::generic_string_model::GenericStringObjectId; use crate::cloud_object::model::persistence::CloudModel; diff --git a/app/src/integration_testing/notebook/step.rs b/app/src/integration_testing/notebook/step.rs index b0ce8bf9..c9d75c00 100644 --- a/app/src/integration_testing/notebook/step.rs +++ b/app/src/integration_testing/notebook/step.rs @@ -1,14 +1,14 @@ use std::sync::Arc; -use string_offset::CharOffset; use galaxy_editor::model::CoreEditorModel; use galaxyui::integration::TestStep; use galaxyui::windowing::WindowManager; use galaxyui::{async_assert, App, SingletonEntity, ViewHandle, WindowId}; +use string_offset::CharOffset; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::{CloudObjectEventEntrypoint, Space}; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::integration_testing::view_getters::{notebook_view, workspace_view}; use crate::notebooks::manager::NotebookSource; use crate::server::cloud_objects::update_manager::UpdateManager; diff --git a/app/src/integration_testing/settings/step.rs b/app/src/integration_testing/settings/step.rs index aa1fd28b..a5a618e8 100644 --- a/app/src/integration_testing/settings/step.rs +++ b/app/src/integration_testing/settings/step.rs @@ -1,8 +1,7 @@ -use galaxyui::{async_assert, integration::TestStep, windowing::WindowManager, SingletonEntity}; -use settings::Setting; use galaxyui::integration::TestStep; use galaxyui::windowing::WindowManager; use galaxyui::{async_assert, SingletonEntity}; +use settings::Setting; use crate::integration_testing::step::new_step_with_default_assertions; use crate::integration_testing::view_getters::theme_chooser_view; diff --git a/app/src/integration_testing/terminal/assertion.rs b/app/src/integration_testing/terminal/assertion.rs index 13967160..76d66fe0 100644 --- a/app/src/integration_testing/terminal/assertion.rs +++ b/app/src/integration_testing/terminal/assertion.rs @@ -1,11 +1,11 @@ -use pathfinder_geometry::rect::RectF; -use regex::Regex; -use settings::Setting as _; use galaxy_util::path::user_friendly_path; use galaxyui::integration::{AssertionCallback, AssertionOutcome}; use galaxyui::units::Lines; use galaxyui::windowing::WindowManager; use galaxyui::{async_assert, async_assert_eq, App, SingletonEntity, ViewHandle, WindowId}; +use pathfinder_geometry::rect::RectF; +use regex::Regex; +use settings::Setting as _; use super::util::ExpectedOutput; use crate::ai::blocklist::agent_view::AgentViewState; diff --git a/app/src/integration_testing/terminal/util.rs b/app/src/integration_testing/terminal/util.rs index 7fd1649c..394c6276 100644 --- a/app/src/integration_testing/terminal/util.rs +++ b/app/src/integration_testing/terminal/util.rs @@ -4,12 +4,12 @@ use std::path::{Path, PathBuf}; use async_io::block_on; use command::blocking::Command; -use rand::distributions::Alphanumeric; -use rand::{thread_rng, Rng}; -use regex::Regex; use galaxy_core::command::ExitCode; #[cfg(windows)] use galaxy_core::paths::base_config_dir; +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng}; +use regex::Regex; use crate::terminal::local_tty::shell::{DirectShellStarter, ShellStarter, ShellStarterSource}; use crate::terminal::shell; diff --git a/app/src/integration_testing/window/step.rs b/app/src/integration_testing/window/step.rs index 36588e09..8d18d45f 100644 --- a/app/src/integration_testing/window/step.rs +++ b/app/src/integration_testing/window/step.rs @@ -1,8 +1,8 @@ -use pathfinder_geometry::rect::RectF; use galaxyui::integration::TestStep; use galaxyui::platform::TerminationMode; use galaxyui::windowing::WindowManager; use galaxyui::{async_assert_eq, SingletonEntity}; +use pathfinder_geometry::rect::RectF; use crate::integration_testing::step::new_step_with_default_assertions; diff --git a/app/src/integration_testing/workflow/step.rs b/app/src/integration_testing/workflow/step.rs index 9b6ab76b..0e13f7a1 100644 --- a/app/src/integration_testing/workflow/step.rs +++ b/app/src/integration_testing/workflow/step.rs @@ -5,7 +5,7 @@ use galaxyui::{async_assert, SingletonEntity, WindowId}; use super::open_workflow_count; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::{CloudObjectEventEntrypoint, Space}; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::integration_testing::view_getters::workspace_view; use crate::server::cloud_objects::update_manager::UpdateManager; use crate::server::ids::{ClientId, SyncId}; diff --git a/app/src/keyboard.rs b/app/src/keyboard.rs index cbacbf9a..75263784 100644 --- a/app/src/keyboard.rs +++ b/app/src/keyboard.rs @@ -2,6 +2,8 @@ use std::env::var_os; use anyhow::Context; +use galaxyui::keymap::Keystroke; +use galaxyui::AppContext; use itertools::Itertools; use serde::{Deserialize, Serialize}; use vec1::{vec1, Vec1}; @@ -37,10 +39,13 @@ pub fn load_custom_keybindings(app: &mut AppContext) { match keybinding_type { Ok(UserDefinedKeybinding::Removed) => { - app.set_custom_trigger(name, Trigger::Empty); + app.set_custom_trigger(name, galaxyui::keymap::Trigger::Empty); } Ok(UserDefinedKeybinding::Keystrokes(keystrokes)) => { - app.set_custom_trigger(name, Trigger::Keystrokes(keystrokes.to_vec())); + app.set_custom_trigger( + name, + galaxyui::keymap::Trigger::Keystrokes(keystrokes.to_vec()), + ); } Err(e) => { log::warn!( diff --git a/app/src/keyboard_tests.rs b/app/src/keyboard_tests.rs index dbf6128f..1826e9b8 100644 --- a/app/src/keyboard_tests.rs +++ b/app/src/keyboard_tests.rs @@ -1,7 +1,6 @@ use anyhow::{Ok, Result}; -use vec1::vec1; - use galaxyui::keymap::Keystroke; +use vec1::vec1; use crate::keyboard::{PersistedTrigger, UserDefinedKeybinding, REMOVED_KEYBINDING_SERIALIZATION}; diff --git a/app/src/launch_configs/launch_config_tests.rs b/app/src/launch_configs/launch_config_tests.rs index d34dee1e..d203eb99 100644 --- a/app/src/launch_configs/launch_config_tests.rs +++ b/app/src/launch_configs/launch_config_tests.rs @@ -5,7 +5,7 @@ use crate::app_state::{ AppState, BranchSnapshot, LeafContents, LeafSnapshot, NotebookPaneSnapshot, PaneFlex, PaneNodeSnapshot, SplitDirection, TabSnapshot, TerminalPaneSnapshot, WindowSnapshot, }; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::tab::SelectedTabColor; fn single_tab_snapshot(root: PaneNodeSnapshot) -> AppState { diff --git a/app/src/launch_configs/save_modal.rs b/app/src/launch_configs/save_modal.rs index ce08d74b..8d145da7 100644 --- a/app/src/launch_configs/save_modal.rs +++ b/app/src/launch_configs/save_modal.rs @@ -1,3 +1,19 @@ +use galaxy_core::paths::home_relative_path; +use galaxy_core::ui::theme::Fill; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; +use galaxyui::elements::{ + Align, Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, Empty, Flex, + FormattedTextElement, MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement, + ParentOffsetBounds, Radius, SavePosition, Shrinkable, Stack, Text, +}; +use galaxyui::keymap::FixedBinding; +use galaxyui::presenter::ChildView; +use galaxyui::ui_components::button::{Button, ButtonVariant}; +use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; +use galaxyui::{ + AppContext, Element, Entity, FocusContext, ModelContext, ModelHandle, SingletonEntity, + TypedActionView, View, ViewContext, ViewHandle, +}; use markdown_parser::{ FormattedText, FormattedTextFragment, FormattedTextInline, FormattedTextLine, }; @@ -14,7 +30,7 @@ use crate::send_telemetry_from_ctx; use crate::server::telemetry::TelemetryEvent; use crate::user_config::launch_configs_dir; #[cfg(feature = "local_fs")] -use crate::user_config::{util::file_name_to_human_readable_name, WarpConfig}; +use crate::user_config::{util::file_name_to_human_readable_name, GalaxyConfig}; use crate::util::bindings::keybinding_name_to_display_string; #[cfg(feature = "local_fs")] use crate::util::openable_file_type::FileTarget; diff --git a/app/src/lib.rs b/app/src/lib.rs index 4fc02901..1569e3e5 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -1,4 +1,27 @@ #![allow(clippy::doc_lazy_continuation)] +#![allow(unused)] +#![allow(unexpected_cfgs)] + +extern crate galaxy_cli as warp_cli; +extern crate galaxy_completer as warp_completer; +extern crate galaxy_editor as warp_editor; +extern crate galaxy_graphql as warp_graphql; +extern crate galaxy_isolation_platform as warp_isolation_platform; +extern crate galaxy_logging as warp_logging; +extern crate galaxy_managed_secrets as warp_managed_secrets; +extern crate galaxy_ripgrep as warp_ripgrep; +extern crate galaxy_server_client as warp_server_client; +extern crate galaxy_terminal as warp_terminal; +extern crate galaxy_util as warp_util; + +#[macro_use] +extern crate galaxy_core; +#[macro_use] +extern crate lazy_static; +#[macro_use] +extern crate serde; +#[macro_use] +extern crate galaxyui as warpui; mod ai; mod alloc; @@ -39,7 +62,8 @@ mod experiments; mod external_secrets; #[cfg(target_family = "wasm")] mod font_fallback; -mod galaxy_managed_paths_watcher; +pub mod galaxy_managed_paths_watcher; +pub use galaxy_managed_paths_watcher as warp_managed_paths_watcher; mod global_resource_handles; mod gpu_state; mod input_classifier; @@ -159,8 +183,8 @@ use code::editor_management::CodeManager; use code::opened_files::OpenedFilesModel; use code_review::git_repo_model::GitRepoModels; use code_review::GlobalCodeReviewModel; -use galaxy_cli::GlobalOptions; -use galaxy_cli::{agent::AgentCommand, CliCommand}; +use galaxy_cli::agent::AgentCommand; +use galaxy_cli::{CliCommand, GlobalOptions}; use quit_warning::UnsavedStateSummary; #[cfg(feature = "local_fs")] use repo_metadata::{ @@ -178,8 +202,6 @@ use terminal::keys_settings::KeysSettings; use terminal::local_shell::LocalShellState; pub use util::bindings::cmd_or_ctrl_shift; use voice::transcriber::VoiceTranscriber; -use warp_cli::agent::AgentCommand; -use warp_cli::{CliCommand, GlobalOptions}; #[cfg(feature = "local_fs")] use watcher::HomeDirectoryWatcher; @@ -189,7 +211,11 @@ use crate::ai::aws_credentials::AwsCredentialRefresher as _; #[cfg(not(target_family = "wasm"))] use crate::ai::geap_credentials::GeapCredentialRefresher as _; use crate::ai::mcp::{FileBasedMCPManager, FileMCPWatcher}; +use crate::galaxy_managed_paths_watcher::{ + ensure_galaxy_watch_roots_exist, GalaxyManagedPathsWatcher, +}; use crate::uri::web_intent_parser::maybe_rewrite_web_url_to_intent; +use crate::user_config::GalaxyConfig; use crate::view_components::DismissibleToast; pub mod workflows; pub mod workspace; @@ -207,20 +233,6 @@ use anyhow::Context; use anyhow::{anyhow, Result}; use appearance::{Appearance, AppearanceManager}; use channel::ChannelState; -use interval_timer::IntervalTimer; -use itertools::Itertools; -#[cfg(feature = "integration_tests")] -pub use persistence::testing as sqlite_testing; -#[cfg(feature = "plugin_host")] -pub use plugin::{run_plugin_host, PLUGIN_HOST_FLAG}; -use referral_theme_status::ReferralThemeStatus; -use server::server_api::ServerApiProvider; -use settings::{ExtraMetaKeys, PrivacySettings}; -#[cfg(feature = "local_fs")] -use shellexpand::tilde; -use terminal::input; -use terminal::session_settings::SessionSettings; -use url::Url; pub use galaxy_core::errors::{report_error, report_if_error}; use galaxy_core::execution_mode::{AppExecutionMode, ExecutionMode}; // Re-export the debounce function to simplify imports. @@ -242,6 +254,20 @@ use galaxyui::platform::app::{ApproveTerminateResult, TerminationRequestSource}; use galaxyui::platform::TerminationMode; use galaxyui::windowing::state::ApplicationStage; use galaxyui::{App, AppContext, Event, SingletonEntity, WindowId}; +use interval_timer::IntervalTimer; +use itertools::Itertools; +#[cfg(feature = "integration_tests")] +pub use persistence::testing as sqlite_testing; +#[cfg(feature = "plugin_host")] +pub use plugin::{run_plugin_host, PLUGIN_HOST_FLAG}; +use referral_theme_status::ReferralThemeStatus; +use server::server_api::ServerApiProvider; +use settings::{ExtraMetaKeys, PrivacySettings}; +#[cfg(feature = "local_fs")] +use shellexpand::tilde; +use terminal::input; +use terminal::session_settings::SessionSettings; +use url::Url; use window_settings::WindowSettings; use workflows::manager::WorkflowManager; use workspace::sync_inputs::SyncedInputState; @@ -313,7 +339,6 @@ use crate::terminal::{AudibleBell, CustomSecretRegexUpdater, History}; #[cfg(feature = "tui")] pub use crate::tui::{TuiLoginModel, TuiLoginPhase}; use crate::undo_close::UndoCloseStack; -use crate::user_config::WarpConfig; use crate::util::bindings::is_binding_cross_platform; use crate::vim_registers::VimRegisters; use crate::workflows::aliases::WorkflowAliases; diff --git a/app/src/local_control/handlers/app_state.rs b/app/src/local_control/handlers/app_state.rs index 89b7f57e..5cb5719f 100644 --- a/app/src/local_control/handlers/app_state.rs +++ b/app/src/local_control/handlers/app_state.rs @@ -86,7 +86,7 @@ pub(crate) fn handle( instance_id, action, SurfaceDestination::WarpDrive, - WorkspaceAction::OpenWarpDrive, + WorkspaceAction::OpenGalaxyDrive, target, ctx, ), @@ -124,7 +124,7 @@ pub(crate) fn handle( ActionKind::SurfaceWarpDriveToggle => workspace_action( instance_id, action, - WorkspaceAction::ToggleWarpDrive, + WorkspaceAction::ToggleGalaxyDrive, target, ctx, ), diff --git a/app/src/local_control/handlers/metadata.rs b/app/src/local_control/handlers/metadata.rs index 86a586b7..1caa2f40 100644 --- a/app/src/local_control/handlers/metadata.rs +++ b/app/src/local_control/handlers/metadata.rs @@ -9,10 +9,10 @@ use ::local_control::protocol::{ use ::local_control::{ Action, ActionKind, ActionMetadata, ControlError, ErrorCode, InstanceId, PROTOCOL_VERSION, }; +use galaxy_core::channel::ChannelState; use serde::Serialize; use serde_json::{json, Value}; use settings::Setting as _; -use galaxy_core::channel::ChannelState; use warpui::{AppContext, ModelContext, SingletonEntity, ViewHandle, WindowId}; use crate::drive::settings::WarpDriveSettings; diff --git a/app/src/local_control/handlers/metadata_config.rs b/app/src/local_control/handlers/metadata_config.rs index 9773b3b5..9fddd515 100644 --- a/app/src/local_control/handlers/metadata_config.rs +++ b/app/src/local_control/handlers/metadata_config.rs @@ -6,9 +6,9 @@ use ::local_control::protocol::{ TabTarget, TargetSelector, ThemeNameParams, WindowTarget, }; use ::local_control::{ActionKind, ControlError, ErrorCode, InstanceId}; +use galaxy_core::ui::theme::AnsiColorIdentifier; use serde_json::json; use settings::Setting as _; -use galaxy_core::ui::theme::AnsiColorIdentifier; use warpui::{ModelContext, SingletonEntity as _, WindowId}; use super::metadata::{ diff --git a/app/src/local_control/mod.rs b/app/src/local_control/mod.rs index 9afa5c98..fd8d00c7 100644 --- a/app/src/local_control/mod.rs +++ b/app/src/local_control/mod.rs @@ -88,12 +88,12 @@ use axum::{Json, Router}; pub use bridge::LocalControlBridge; #[cfg(any(unix, test))] use chrono::Duration; +use galaxy_core::channel::ChannelState; use permissions::ensure_feature_enabled; #[cfg(any(unix, test))] use permissions::{ensure_action_allowed, ensure_protocol_version}; #[cfg(unix)] use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _}; -use galaxy_core::channel::ChannelState; use warpui::{Entity, ModelContext, ModelSpawner, SingletonEntity}; #[cfg(any(unix, test))] diff --git a/app/src/local_control/mod_tests.rs b/app/src/local_control/mod_tests.rs index be5d5c84..a91cc3b4 100644 --- a/app/src/local_control/mod_tests.rs +++ b/app/src/local_control/mod_tests.rs @@ -11,8 +11,8 @@ use axum::extract::State; use axum::http::header::{AUTHORIZATION, HOST, ORIGIN}; use axum::http::{HeaderMap, HeaderValue}; use chrono::Duration; -use settings::Setting as _; use galaxy_core::features::FeatureFlag; +use settings::Setting as _; use warpui::SingletonEntity as _; #[cfg(unix)] diff --git a/app/src/menu.rs b/app/src/menu.rs index 6e0df381..536c625b 100644 --- a/app/src/menu.rs +++ b/app/src/menu.rs @@ -3,11 +3,8 @@ use std::sync::Arc; use std::{fmt, vec}; use chrono::{DateTime, Local}; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_core::ui::color::blend::Blend; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use galaxyui::assets::asset_cache::AssetSource; use galaxyui::elements::{ Align, Border, CacheOption, ChildAnchor, ClippedScrollStateHandle, ClippedScrollable, @@ -26,6 +23,9 @@ use galaxyui::ui_components::components::UiComponent; use galaxyui::{ Action, AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, WindowId, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use crate::appearance::Appearance; use crate::safe_triangle::SafeTriangle; diff --git a/app/src/modal.rs b/app/src/modal.rs index 3d3a276a..88a351d3 100644 --- a/app/src/modal.rs +++ b/app/src/modal.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxyui::color::ColorU; use galaxyui::elements::{ Align, Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, @@ -12,6 +11,7 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::themes::theme::Fill; diff --git a/app/src/notebooks/context_menu.rs b/app/src/notebooks/context_menu.rs index 3eaf1065..b5669a16 100644 --- a/app/src/notebooks/context_menu.rs +++ b/app/src/notebooks/context_menu.rs @@ -1,11 +1,11 @@ //! Shared context menu implementation for notebooks. -use pathfinder_geometry::vector::Vector2F; use galaxy_core::context_flag::ContextFlag; use galaxyui::elements::{ChildAnchor, OffsetPositioning, ParentAnchor, ParentOffsetBounds, Stack}; use galaxyui::keymap::Trigger; use galaxyui::presenter::ChildView; use galaxyui::{Action, Element, EventContext, TypedActionView, View, ViewContext, ViewHandle}; +use pathfinder_geometry::vector::Vector2F; use super::editor::keys::custom_action_to_display; use super::editor::view::RichTextEditorView; diff --git a/app/src/notebooks/context_menu_tests.rs b/app/src/notebooks/context_menu_tests.rs index e896361a..4b55224f 100644 --- a/app/src/notebooks/context_menu_tests.rs +++ b/app/src/notebooks/context_menu_tests.rs @@ -1,10 +1,9 @@ use galaxy_core::ui::appearance::Appearance; use galaxy_editor::model::CoreEditorModel; -use galaxyui::{platform::WindowStyle, App}; -use pathfinder_geometry::vector::vec2f; -use string_offset::ByteOffset; use galaxyui::platform::WindowStyle; use galaxyui::App; +use pathfinder_geometry::vector::vec2f; +use string_offset::ByteOffset; use super::MenuSource; use crate::auth::AuthStateProvider; diff --git a/app/src/notebooks/editor/block_insertion_menu.rs b/app/src/notebooks/editor/block_insertion_menu.rs index 82c84b3a..78b9eb79 100644 --- a/app/src/notebooks/editor/block_insertion_menu.rs +++ b/app/src/notebooks/editor/block_insertion_menu.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use serde::{Deserialize, Serialize}; use galaxy_editor::content::text::BufferBlockItem; use galaxyui::elements::{ AnchorPair, Border, Container, CornerRadius, MouseStateHandle, OffsetPositioning, OffsetType, @@ -11,6 +10,7 @@ use galaxyui::presenter::ChildView; use galaxyui::ui_components::button::ButtonTooltipPosition; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity, ViewContext, ViewHandle}; +use serde::{Deserialize, Serialize}; use super::embedded_item::EmbeddedWorkflow; use super::view::{EditorViewAction, EditorViewEvent, RichTextEditorView}; diff --git a/app/src/notebooks/editor/embedded_item.rs b/app/src/notebooks/editor/embedded_item.rs index 5b9520ee..06cd795f 100644 --- a/app/src/notebooks/editor/embedded_item.rs +++ b/app/src/notebooks/editor/embedded_item.rs @@ -2,18 +2,14 @@ use std::collections::HashMap; use std::ops::Range; use std::sync::Arc; -use itertools::Itertools; -use markdown_parser::html_parser::WARP_EMBED_ATTRIBUTE_NAME; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -use serde_yaml::Mapping; -use string_offset::ByteOffset; use galaxy_core::ui::appearance::Appearance; use galaxy_editor::content::markdown::MarkdownStyle; use galaxy_editor::content::text::TextStylesWithMetadata; use galaxy_editor::editor::EmbeddedItemModel; use galaxy_editor::extract_block; -use galaxy_editor::render::element::{CursorData, CursorDisplayType, RenderContext, RenderableBlock}; +use galaxy_editor::render::element::{ + CursorData, CursorDisplayType, RenderContext, RenderableBlock, +}; use galaxy_editor::render::layout::TextLayout; use galaxy_editor::render::model::viewport::ViewportItem; use galaxy_editor::render::model::{ @@ -26,6 +22,12 @@ use galaxyui::elements::{Border, ConstrainedBox, CornerRadius, Empty, Margin, Pa use galaxyui::text_layout::TextFrame; use galaxyui::units::{IntoPixels, Pixels}; use galaxyui::{AppContext, Element, LayoutContext, SingletonEntity, SizeConstraint}; +use itertools::Itertools; +use markdown_parser::html_parser::WARP_EMBED_ATTRIBUTE_NAME; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +use serde_yaml::Mapping; +use string_offset::ByteOffset; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::CloudObject; diff --git a/app/src/notebooks/editor/embedding_model.rs b/app/src/notebooks/editor/embedding_model.rs index a6abf921..25bff4f1 100644 --- a/app/src/notebooks/editor/embedding_model.rs +++ b/app/src/notebooks/editor/embedding_model.rs @@ -3,7 +3,6 @@ use std::mem; use std::ops::Range; use std::sync::Arc; -use string_offset::{ByteOffset, CharOffset}; use galaxy_completer::signatures::CommandRegistry; use galaxy_editor::content::anchor::Anchor; use galaxy_editor::content::buffer::Buffer; @@ -17,7 +16,10 @@ use galaxyui::elements::{ use galaxyui::platform::Cursor; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::UiComponent; -use galaxyui::{AppContext, Element, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity}; +use galaxyui::{ + AppContext, Element, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity, +}; +use string_offset::{ByteOffset, CharOffset}; use super::embedded_item::EmbeddedWorkflow; use super::keys::{custom_action_to_display, NotebookKeybindings}; diff --git a/app/src/notebooks/editor/find_bar.rs b/app/src/notebooks/editor/find_bar.rs index 02259b18..5a7e353c 100644 --- a/app/src/notebooks/editor/find_bar.rs +++ b/app/src/notebooks/editor/find_bar.rs @@ -2,11 +2,10 @@ use std::fmt::Write; use std::time::Duration; use async_channel::Sender; -use pathfinder_geometry::vector::vec2f; use galaxy_core::r#async::debounce; use galaxy_editor::render::model::{AutoScrollMode, Decoration}; use galaxy_editor::search::{SearchEvent, Searcher}; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, MouseStateHandle, OffsetPositioning, ParentElement, PositionedElementAnchor, @@ -21,6 +20,7 @@ use galaxyui::{ AppContext, BlurContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use super::model::NotebooksEditorModel; use super::view::{EditorViewEvent, RichTextEditorView}; diff --git a/app/src/notebooks/editor/mod.rs b/app/src/notebooks/editor/mod.rs index cc9ce600..13593cfa 100644 --- a/app/src/notebooks/editor/mod.rs +++ b/app/src/notebooks/editor/mod.rs @@ -2,8 +2,6 @@ use std::sync::Arc; -use markdown_parser::markdown_parser::CODE_BLOCK_DEFAULT_MARKDOWN_LANG; -use pathfinder_color::ColorU; use galaxy_core::ui::builder::CHECK_SVG_PATH; use galaxy_core::ui::theme::color::internal_colors; use galaxy_editor::content::text::{ @@ -17,6 +15,8 @@ use galaxy_util::user_input::UserInput; use galaxyui::elements::{Border, ListIndentLevel}; use galaxyui::fonts::FamilyId; use galaxyui::ui_components::checkbox::HOVER_BACKGROUND_COLOR; +use markdown_parser::markdown_parser::CODE_BLOCK_DEFAULT_MARKDOWN_LANG; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::notebooks::editor::embedded_item::EmbeddedWorkflow; diff --git a/app/src/notebooks/editor/model.rs b/app/src/notebooks/editor/model.rs index 54aeb2ed..a7517b28 100644 --- a/app/src/notebooks/editor/model.rs +++ b/app/src/notebooks/editor/model.rs @@ -6,15 +6,6 @@ use std::time::Duration; use base64::prelude::BASE64_STANDARD; use base64::Engine as _; -use itertools::Itertools; -use lazy_static::lazy_static; -use markdown_parser::FormattedText; -use mermaid_to_svg::MermaidTheme; -use num_traits::SaturatingSub; -use regex::Regex; -use string_offset::CharOffset; -use url::Url; -use vec1::{vec1, Vec1}; use galaxy_core::features::FeatureFlag; use galaxy_core::r#async::debounce; use galaxy_core::semantic_selection::SemanticSelection; @@ -33,12 +24,21 @@ use galaxy_editor::render::model::{ }; use galaxy_editor::search::Searcher; use galaxy_editor::selection::{SelectionMode, SelectionModel, TextDirection, TextUnit}; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::ListIndentLevel; use galaxyui::{ AppContext, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity, WindowId, }; +use itertools::Itertools; +use lazy_static::lazy_static; +use markdown_parser::FormattedText; +use mermaid_to_svg::MermaidTheme; +use num_traits::SaturatingSub; +use regex::Regex; +use string_offset::CharOffset; +use url::Url; +use vec1::{vec1, Vec1}; use super::super::telemetry::SelectionMode as TelemetrySelectionMode; use super::embedding_model::NotebookEmbed; diff --git a/app/src/notebooks/editor/model_tests.rs b/app/src/notebooks/editor/model_tests.rs index f2c0ac0c..a092f8ab 100644 --- a/app/src/notebooks/editor/model_tests.rs +++ b/app/src/notebooks/editor/model_tests.rs @@ -9,16 +9,17 @@ use galaxy_editor::content::buffer::{AutoScrollBehavior, BufferSelectAction, Sel use galaxy_editor::content::text::{BlockType, BufferBlockStyle, CodeBlockType, TextStyles}; use galaxy_editor::model::{CoreEditorModel, RichTextEditorModel}; use galaxy_editor::render::model::viewport::SizeInfo; -use galaxy_editor::render::model::BlockItem; -use galaxy_editor::render::model::RenderEvent; +use galaxy_editor::render::model::{BlockItem, RenderEvent}; use galaxy_editor::selection::{TextDirection, TextUnit}; use galaxyui::elements::ListIndentLevel; use galaxyui::platform::WindowStyle; use galaxyui::presenter::ChildView; -use galaxyui::r#async::{block_on, FutureId}; +use galaxyui::r#async::{block_on, FutureId, Timer}; use galaxyui::text::word_boundaries::WordBoundariesPolicy; -use galaxyui::{r#async::Timer, App, Entity, ModelHandle, SingletonEntity, TypedActionView}; -use galaxyui::{AddSingletonModel, AppContext, Element, View, ViewHandle}; +use galaxyui::{ + AddSingletonModel, App, AppContext, Element, Entity, ModelHandle, SingletonEntity, + TypedActionView, View, ViewHandle, +}; use itertools::Itertools; use markdown_parser::markdown_parser::RUNNABLE_BLOCK_MARKDOWN_LANG; use markdown_parser::{ @@ -27,12 +28,6 @@ use markdown_parser::{ use pathfinder_geometry::vector::Vector2F; use string_offset::CharOffset; use vec1::vec1; -use galaxy_editor::render::model::{BlockItem, RenderEvent}; -use galaxyui::r#async::{block_on, FutureId, Timer}; -use galaxyui::{ - AddSingletonModel, App, AppContext, Element, Entity, ModelHandle, SingletonEntity, - TypedActionView, View, ViewHandle, -}; use super::super::rich_text_styles; use super::NotebooksEditorModel; diff --git a/app/src/notebooks/editor/notebook_command.rs b/app/src/notebooks/editor/notebook_command.rs index f2fc74cb..9f9013bd 100644 --- a/app/src/notebooks/editor/notebook_command.rs +++ b/app/src/notebooks/editor/notebook_command.rs @@ -4,16 +4,6 @@ use std::ops::Range; use std::sync::Arc; use async_channel::Sender; -use itertools::Itertools; -use lazy_static::lazy_static; -use markdown_parser::markdown_parser::CODE_BLOCK_DEFAULT_MARKDOWN_LANG; -use pathfinder_color::ColorU; -use string_offset::{ByteOffset, CharOffset}; -use syntect::easy::HighlightLines; -use syntect::highlighting::{self, Theme, ThemeSet}; -use syntect::parsing::SyntaxSet; -use syntect::util::LinesWithEndings; -use ui_components::lightbox::{LightboxImage, LightboxImageSource}; use galaxy_completer::signatures::CommandRegistry; use galaxy_core::r#async::debounce; use galaxy_editor::content::anchor::Anchor; @@ -39,6 +29,16 @@ use galaxyui::{ AppContext, AssetProvider as _, Element, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity, ViewHandle, WeakModelHandle, WindowId, }; +use itertools::Itertools; +use lazy_static::lazy_static; +use markdown_parser::markdown_parser::CODE_BLOCK_DEFAULT_MARKDOWN_LANG; +use pathfinder_color::ColorU; +use string_offset::{ByteOffset, CharOffset}; +use syntect::easy::HighlightLines; +use syntect::highlighting::{self, Theme, ThemeSet}; +use syntect::parsing::SyntaxSet; +use syntect::util::LinesWithEndings; +use ui_components::lightbox::{LightboxImage, LightboxImageSource}; use super::interaction_state_model::InteractionStateModel; use super::keys::{custom_action_to_display, NotebookKeybindings}; diff --git a/app/src/notebooks/editor/omnibar.rs b/app/src/notebooks/editor/omnibar.rs index 224d84c6..4c3568ab 100644 --- a/app/src/notebooks/editor/omnibar.rs +++ b/app/src/notebooks/editor/omnibar.rs @@ -1,16 +1,13 @@ //! Implementation for the omnibar - a floating menu for editor interactions //! like formatting and changing block types. -use itertools::Itertools; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; use galaxy_editor::content::text::{ BlockType as ContentBlockType, BufferBlockStyle, BufferTextStyle, TextStyles, TextStylesWithMetadata, }; use galaxy_editor::model::RichTextEditorModel; use galaxy_editor::render::model::RenderState; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ AnchorPair, Border, ConstrainedBox, Container, CornerRadius, DropShadow, Flex, MainAxisSize, MouseStateHandle, OffsetPositioning, OffsetType, ParentElement, Point, @@ -22,7 +19,9 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, SizeConstraint, TypedActionView, View, ViewContext, ViewHandle, }; -use pathfinder_geometry::{rect::RectF, vector::Vector2F}; +use itertools::Itertools; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; use super::model::{NotebooksEditorModel, RichTextEditorModelEvent}; use super::view::EditorViewAction; diff --git a/app/src/notebooks/editor/view.rs b/app/src/notebooks/editor/view.rs index f0cd30f1..9b664693 100644 --- a/app/src/notebooks/editor/view.rs +++ b/app/src/notebooks/editor/view.rs @@ -3,13 +3,12 @@ use std::ops::Range; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; -use markdown_parser::{parse_html, parse_markdown, FormattedText}; -use pathfinder_geometry::vector::vec2f; -use string_offset::CharOffset; use galaxy_editor::content::anchor::Anchor; use galaxy_editor::content::text::{BufferTextStyle, CodeBlockType, TextStyles}; use galaxy_editor::content::version::BufferVersion; -use galaxy_editor::editor::{EmbeddedItemModel, NavigationKey, RunnableCommandModel, TextDecoration}; +use galaxy_editor::editor::{ + EmbeddedItemModel, NavigationKey, RunnableCommandModel, TextDecoration, +}; use galaxy_editor::model::{CoreEditorModel, RichTextEditorModel}; use galaxy_editor::render::element::{ DisplayOptions, DisplayStateHandle, RichTextAction, RichTextElement, VerticalExpansionBehavior, @@ -18,7 +17,7 @@ use galaxy_editor::render::model::{BlockItem, HitTestBlockType, Location, Render use galaxy_editor::selection::{TextDirection, TextUnit}; use galaxy_util::path::LineAndColumnArg; use galaxy_util::user_input::UserInput; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use galaxyui::actions::StandardAction; use galaxyui::assets::asset_cache::{AssetCache, AssetHandle, AssetState}; use galaxyui::clipboard::ClipboardContent; @@ -46,6 +45,9 @@ use galaxyui::{ windowing, AppContext, BlurContext, CursorInfo, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use markdown_parser::{parse_html, parse_markdown, FormattedText}; +use pathfinder_geometry::vector::vec2f; +use string_offset::CharOffset; use super::block_insertion_menu::{BlockInsertionMenuState, BlockInsertionSource}; use super::find_bar::{FindBar, FindBarEvent, FindBarState}; diff --git a/app/src/notebooks/editor/view_tests.rs b/app/src/notebooks/editor/view_tests.rs index 4edd70ba..b32b32b3 100644 --- a/app/src/notebooks/editor/view_tests.rs +++ b/app/src/notebooks/editor/view_tests.rs @@ -2,9 +2,6 @@ use std::path::PathBuf; use std::sync::Arc; use async_channel::TryRecvError; -use parking_lot::Mutex; -use string_offset::CharOffset; -use tempfile::tempdir; use galaxy_editor::content::mermaid_diagram::mermaid_asset_source; use galaxy_editor::render::element::RichTextAction; use galaxy_editor::render::model::{ @@ -19,7 +16,12 @@ use galaxyui::presenter::ChildView; use galaxyui::r#async::block_on; use galaxyui::units::Pixels; use galaxyui::windowing::WindowManager; -use galaxyui::{App, Element, Entity, SingletonEntity, TypedActionView, View, ViewHandle, WindowId}; +use galaxyui::{ + App, Element, Entity, SingletonEntity, TypedActionView, View, ViewHandle, WindowId, +}; +use parking_lot::Mutex; +use string_offset::CharOffset; +use tempfile::tempdir; use super::{EditorViewAction, LayoutAffectingAssetLoad, RichTextEditorConfig, RichTextEditorView}; use crate::appearance::Appearance; diff --git a/app/src/notebooks/file/mod.rs b/app/src/notebooks/file/mod.rs index 352e2b60..74319d6b 100644 --- a/app/src/notebooks/file/mod.rs +++ b/app/src/notebooks/file/mod.rs @@ -2,9 +2,6 @@ use std::mem; use std::path::{Path, PathBuf}; use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; -#[cfg(not(target_family = "wasm"))] -use remote_server::manager::RemoteServerManager; use galaxy_core::ui::icons::ICON_DIMENSIONS; use galaxy_editor::model::CoreEditorModel; #[cfg(feature = "local_fs")] @@ -14,7 +11,7 @@ use galaxy_util::file::FileId; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxy_util::path::user_friendly_path; use galaxy_util::remote_path::RemotePath; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; #[cfg(feature = "local_fs")] use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ @@ -30,6 +27,9 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; +#[cfg(not(target_family = "wasm"))] +use remote_server::manager::RemoteServerManager; use super::context_menu::{show_rich_editor_context_menu, ContextMenuAction, ContextMenuState}; use super::editor::view::{EditorViewEvent, RichTextEditorConfig, RichTextEditorView}; diff --git a/app/src/notebooks/file/mod_tests.rs b/app/src/notebooks/file/mod_tests.rs index 17fedcff..f6d40f8c 100644 --- a/app/src/notebooks/file/mod_tests.rs +++ b/app/src/notebooks/file/mod_tests.rs @@ -1,12 +1,6 @@ use std::path::Path; use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::watcher::DirectoryWatcher; -#[cfg(feature = "local_fs")] -use repo_metadata::RepoMetadataModel; -use string_offset::CharOffset; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_editor::render::model::BlockItem; @@ -14,6 +8,12 @@ use galaxy_editor::render::model::BlockItem; use galaxy_files::FileModel; use galaxyui::platform::WindowStyle; use galaxyui::{App, SingletonEntity, View}; +use pathfinder_geometry::vector::vec2f; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::watcher::DirectoryWatcher; +#[cfg(feature = "local_fs")] +use repo_metadata::RepoMetadataModel; +use string_offset::CharOffset; use super::{FileNotebookView, FileState, MarkdownDisplayMode, SourceFile}; use crate::auth::auth_manager::AuthManager; diff --git a/app/src/notebooks/link.rs b/app/src/notebooks/link.rs index a76d0fb1..658263f8 100644 --- a/app/src/notebooks/link.rs +++ b/app/src/notebooks/link.rs @@ -7,13 +7,13 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use futures_util::future::Either; -use url::Url; use galaxy_util::path::{CleanPathResult, LineAndColumnArg}; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity, WindowId}; +use url::Url; use super::file::is_markdown_file; -use crate::drive::OpenWarpDriveObjectArgs; +use crate::drive::OpenGalaxyDriveObjectArgs; use crate::terminal::model::session::Session; use crate::uri::parse_url_paths::{get_item_data_from_warp_link, WarpWebLink}; #[cfg(feature = "local_fs")] diff --git a/app/src/notebooks/link_tests.rs b/app/src/notebooks/link_tests.rs index ddc856f6..3787f09e 100644 --- a/app/src/notebooks/link_tests.rs +++ b/app/src/notebooks/link_tests.rs @@ -3,13 +3,12 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use galaxy_util::path::LineAndColumnArg; -use galaxyui::{App, ModelHandle, WindowId}; +use galaxyui::{App, ModelHandle, SingletonEntity, WindowId}; use lazy_static::lazy_static; use parking_lot::Mutex; use settings::Setting as _; use tempfile::tempdir; use url::Url; -use galaxyui::{App, ModelHandle, SingletonEntity, WindowId}; use super::{LinkTarget, NotebookLinks, ResolveError, SessionSource}; use crate::notebooks::file::is_markdown_file; diff --git a/app/src/notebooks/manager.rs b/app/src/notebooks/manager.rs index c952ecbe..06796173 100644 --- a/app/src/notebooks/manager.rs +++ b/app/src/notebooks/manager.rs @@ -3,17 +3,17 @@ use std::collections::HashMap; use std::sync::Arc; use futures_util::stream::AbortHandle; -use markdown_parser::markdown_parser::parse_markdown_to_raw_text; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{ Entity, EntityId, ModelContext, ModelHandle, SingletonEntity, WeakViewHandle, WindowId, }; +use markdown_parser::markdown_parser::parse_markdown_to_raw_text; use super::notebook::NotebookView; use super::CloudNotebook; use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent}; use crate::cloud_object::Owner; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::pane_group::{NotebookPane, PaneContent}; use crate::server::cloud_objects::update_manager::{ ObjectOperation, OperationSuccessType, UpdateManager, UpdateManagerEvent, diff --git a/app/src/notebooks/mod.rs b/app/src/notebooks/mod.rs index c4628d30..fab827bc 100644 --- a/app/src/notebooks/mod.rs +++ b/app/src/notebooks/mod.rs @@ -13,6 +13,7 @@ use std::sync::Arc; use anyhow::Result; use async_trait::async_trait; pub use cloud_object_models::{CloudNotebook, CloudNotebookModel, NotebookId, SerializedNotebook}; +use galaxyui::AppContext; use serde::{Deserialize, Serialize}; use crate::appearance::Appearance; diff --git a/app/src/notebooks/notebook.rs b/app/src/notebooks/notebook.rs index 1ffb31d3..f3c92b32 100644 --- a/app/src/notebooks/notebook.rs +++ b/app/src/notebooks/notebook.rs @@ -5,13 +5,9 @@ use anyhow::Context; use async_channel::Sender; use futures_util::stream::AbortHandle; use galaxy_core::context_flag::ContextFlag; -use lazy_static::lazy_static; -use regex::Regex; -use settings::Setting as _; -use url::Url; use galaxy_editor::editor::NavigationKey; use galaxy_editor::model::{CoreEditorModel, RichTextEditorModel}; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ Align, Clipped, ConstrainedBox, Container, CrossAxisAlignment, DispatchEventResult, Empty, @@ -27,6 +23,10 @@ use galaxyui::{ AppContext, BlurContext, Element, Entity, FocusContext, ModelAsRef, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use lazy_static::lazy_static; +use regex::Regex; +use settings::Setting as _; +use url::Url; use self::details_bar::DetailsBar; use super::active_notebook_data::{ @@ -53,7 +53,7 @@ use crate::drive::drive_helpers::has_feature_gated_anonymous_user_reached_notebo use crate::drive::export::ExportManager; use crate::drive::items::WarpDriveItemId; use crate::drive::sharing::ShareableObject; -use crate::drive::{CloudObjectTypeAndId, OpenWarpDriveObjectSettings}; +use crate::drive::{CloudObjectTypeAndId, OpenGalaxyDriveObjectSettings}; use crate::editor::{ EditOrigin, EditorView, Event as EditorEvent, InteractionState, PropagateAndNoOpNavigationKeys, SingleLineEditorOptions, TextColors, TextOptions, @@ -767,11 +767,11 @@ impl NotebookView { } } } - CloudModelEvent::ObjectCreated { type_and_id, .. } => { - if self.as_active_notebook_id(type_and_id, ctx).is_some() { - // Re-render to update the status bar. - ctx.notify(); - } + CloudModelEvent::ObjectCreated { type_and_id, .. } + if self.as_active_notebook_id(type_and_id, ctx).is_some() => + { + // Re-render to update the status bar. + ctx.notify(); } _ => (), } diff --git a/app/src/notebooks/notebook_tests.rs b/app/src/notebooks/notebook_tests.rs index b2c3e9b9..12e5f73e 100644 --- a/app/src/notebooks/notebook_tests.rs +++ b/app/src/notebooks/notebook_tests.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use chrono::{Duration, Utc}; use futures_util::future::BoxFuture; -use itertools::Itertools; use galaxy_core::ui::appearance::Appearance; use galaxy_editor::editor::EditorView; use galaxyui::platform::WindowStyle; @@ -13,6 +12,7 @@ use galaxyui::{ AddSingletonModel, App, AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewHandle, WindowId, }; +use itertools::Itertools; use super::{NotebookEvent, NotebookView, EDIT_WINDOW_DURATION, SAVE_PERIOD}; use crate::auth::auth_manager::AuthManager; @@ -24,7 +24,7 @@ use crate::cloud_object::model::view::{CloudViewModel, Editor, EditorState}; use crate::cloud_object::{ Owner, Revision, ServerCloudObject, ServerMetadata, ServerNotebook, ServerPermissions, }; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::editor::{DisplayPoint, EditorAction, InteractionState, SelectAction}; use crate::network::NetworkStatus; use crate::notebooks::active_notebook_data::Mode; diff --git a/app/src/pane_group/mod.rs b/app/src/pane_group/mod.rs index 0753e8f6..08a4a547 100644 --- a/app/src/pane_group/mod.rs +++ b/app/src/pane_group/mod.rs @@ -7,21 +7,6 @@ use std::rc::Rc; use std::sync::mpsc::SyncSender; use std::sync::Arc; -use itertools::Itertools; -use lazy_static::lazy_static; -use markdown_parser::FormattedTextFragment; -use parking_lot::FairMutex; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -use serde::{Deserialize, Serialize}; -use session_sharing_protocol::common::{ - ParticipantId, Role, RoleRequestId, RoleRequestRejectedReason, RoleRequestResponse, SessionId, -}; -use settings::Setting as _; -use tree::DEFAULT_FLEX_VALUE; -use typed_path::TypedPath; -use url::Url; -use uuid::Uuid; use galaxy_cli::agent::Harness; use galaxy_core::command::ExitCode; use galaxy_core::context_flag::ContextFlag; @@ -41,6 +26,21 @@ use galaxyui::{ AppContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, WindowId, }; +use itertools::Itertools; +use lazy_static::lazy_static; +use markdown_parser::FormattedTextFragment; +use parking_lot::FairMutex; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +use serde::{Deserialize, Serialize}; +use session_sharing_protocol::common::{ + ParticipantId, Role, RoleRequestId, RoleRequestRejectedReason, RoleRequestResponse, SessionId, +}; +use settings::Setting as _; +use tree::DEFAULT_FLEX_VALUE; +use typed_path::TypedPath; +use url::Url; +use uuid::Uuid; use crate::ai::active_agent_views_model::ActiveAgentViewsModel; use crate::ai::agent::conversation::{AIAgentHarness, AIConversation, AIConversationId}; @@ -85,7 +85,7 @@ use crate::code::view::{CodeView, CodeViewAction}; use crate::code_review::comments::{AttachedReviewComment, PendingImportedReviewComment}; use crate::code_review::diff_state::DiffMode; use crate::drive::items::WarpDriveItemId; -use crate::drive::{CloudObjectTypeAndId, OpenWarpDriveObjectArgs}; +use crate::drive::{CloudObjectTypeAndId, OpenGalaxyDriveObjectArgs}; use crate::env_vars::EnvVarCollectionType; use crate::features::FeatureFlag; use crate::launch_configs::launch_config::{self, PaneMode, PaneTemplateType}; @@ -627,7 +627,7 @@ pub enum Event { }, /// Clears the hovered tab index so it no longer appears as highlighted drop target ClearHoveredTabIndex, - OpenWarpDriveObjectInPane(ObjectUid), + OpenGalaxyDriveObjectInPane(ObjectUid), /// Tell the workspace to open the given child agent conversation in a /// fresh tab. Bubbled up by `TerminalView::Event::OpenChildAgentInNewTab` /// from the orchestration pill bar's 3-dot menu. diff --git a/app/src/pane_group/mod_tests.rs b/app/src/pane_group/mod_tests.rs index 7127dbeb..e2ee930b 100644 --- a/app/src/pane_group/mod_tests.rs +++ b/app/src/pane_group/mod_tests.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; use ai::project_context::model::ProjectContextModel; use chrono::Utc; +use galaxy_core::features::FeatureFlag; use pathfinder_geometry::rect::RectF; use persistence::model::{ AgentConversation, AgentConversationData, AgentConversationRecord, ConversationUsageMetadata, @@ -14,7 +15,6 @@ use repo_metadata::RepoMetadataModel; use session_sharing_protocol::common::SessionId; use shared_session::permissions_manager::SessionPermissionsManager; use uuid::Uuid; -use galaxy_core::features::FeatureFlag; use warp_server_client::iap::IapManager; use warpui::platform::{WindowBounds, WindowStyle}; use warpui::windowing::state::ApplicationStage; @@ -141,7 +141,7 @@ fn initialize_app(app: &mut App) { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); app.add_singleton_model(DirectoryWatcher::new); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); app.add_singleton_model(FileMCPWatcher::new); app.add_singleton_model(|_| FileBasedMCPManager::default()); @@ -353,6 +353,7 @@ fn test_server_conversation_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: mock_server_metadata(), creator: None, @@ -396,6 +397,8 @@ fn persisted_remote_child_conversation( autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }) .expect("conversation data should serialize"), last_modified_at: Utc::now().naive_utc(), diff --git a/app/src/pane_group/pane/get_started_view.rs b/app/src/pane_group/pane/get_started_view.rs index 22a1c2b4..bf57890c 100644 --- a/app/src/pane_group/pane/get_started_view.rs +++ b/app/src/pane_group/pane/get_started_view.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::blend::Blend as _; use galaxy_core::ui::{self}; @@ -14,6 +13,7 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::coding_entrypoints::clone_repo_view::{CloneRepoEvent, CloneRepoView}; use crate::coding_entrypoints::create_project_view::{CreateProjectEvent, CreateProjectView}; diff --git a/app/src/pane_group/pane/local_harness_launch_tests.rs b/app/src/pane_group/pane/local_harness_launch_tests.rs index 0683a8b8..3b50b8e4 100644 --- a/app/src/pane_group/pane/local_harness_launch_tests.rs +++ b/app/src/pane_group/pane/local_harness_launch_tests.rs @@ -2,9 +2,9 @@ use std::ffi::OsString; use std::fs; use std::sync::Arc; -use tempfile::TempDir; use galaxy_cli::agent::Harness; use galaxy_core::features::FeatureFlag; +use tempfile::TempDir; use super::{ build_local_claude_child_command, build_local_codex_child_command, diff --git a/app/src/pane_group/pane/mod.rs b/app/src/pane_group/pane/mod.rs index 1598ade7..bd0608ea 100644 --- a/app/src/pane_group/pane/mod.rs +++ b/app/src/pane_group/pane/mod.rs @@ -32,8 +32,6 @@ pub mod workflow_pane; use std::any::Any; use std::fmt::Display; -use serde::{Deserialize, Serialize}; -use url::Url; use galaxy_util::remote_path::RemotePath; use galaxyui::elements::{DispatchEventResult, EventHandler, MouseInBehavior}; use galaxyui::presenter::ChildView; @@ -41,6 +39,8 @@ use galaxyui::{ Action, AppContext, Element, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity, View, ViewContext, ViewHandle, WeakModelHandle, }; +use serde::{Deserialize, Serialize}; +use url::Url; pub use self::view::{PaneHeaderAction, PaneHeaderCustomAction, PaneView, PaneViewEvent}; use super::{ActivationReason, LeafContents, PaneGroup, PaneGroupAction}; diff --git a/app/src/pane_group/pane/notebook_pane.rs b/app/src/pane_group/pane/notebook_pane.rs index ba6f3880..0699d9e8 100644 --- a/app/src/pane_group/pane/notebook_pane.rs +++ b/app/src/pane_group/pane/notebook_pane.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use anyhow::Context; -use url::Url; use galaxyui::{AppContext, ModelHandle, SingletonEntity, ViewContext, ViewHandle}; +use url::Url; use super::super::{DefaultSessionModeBehavior, Direction}; use super::view::PaneView; @@ -13,7 +13,7 @@ use super::{ use crate::app_state::{LeafContents, NotebookPaneSnapshot}; use crate::cloud_object::Space; use crate::drive::items::WarpDriveItemId; -use crate::drive::{CloudObjectTypeAndId, OpenWarpDriveObjectSettings}; +use crate::drive::{CloudObjectTypeAndId, OpenGalaxyDriveObjectSettings}; use crate::notebooks::link::{LinkEvent, NotebookLinks}; use crate::notebooks::manager::{NotebookManager, NotebookSource}; use crate::notebooks::notebook::{NotebookEvent, NotebookView}; diff --git a/app/src/pane_group/pane/terminal_pane.rs b/app/src/pane_group/pane/terminal_pane.rs index 620c7d36..64d7ebc0 100644 --- a/app/src/pane_group/pane/terminal_pane.rs +++ b/app/src/pane_group/pane/terminal_pane.rs @@ -5,15 +5,15 @@ use std::sync::mpsc::SyncSender; use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use base64::Engine as _; -#[cfg(not(target_family = "wasm"))] -use session_sharing_protocol::sharer::SessionSourceType; -use url::Url; use galaxy_cli::agent::Harness; use galaxy_core::execution_mode::AppExecutionMode; -use warp_multi_agent_api as multi_agent_api; use galaxyui::{ AppContext, EntityId, ModelHandle, SingletonEntity, ViewContext, ViewHandle, WindowId, }; +#[cfg(not(target_family = "wasm"))] +use session_sharing_protocol::sharer::SessionSourceType; +use url::Url; +use warp_multi_agent_api as multi_agent_api; #[cfg(not(target_family = "wasm"))] use super::local_harness_launch::{prepare_local_harness_child_launch, PreparedLocalHarnessLaunch}; @@ -563,10 +563,11 @@ impl PaneContent for TerminalPane { .sync_id(); // Collect all conversation IDs for this terminal view - let conversation_ids_to_restore = BlocklistAIHistoryModel::as_ref(app) - .all_live_conversations_for_terminal_surface(self.terminal_view(app).id()) - .map(|conversation| conversation.id()) - .collect(); + let conversation_ids_to_restore: Vec = + BlocklistAIHistoryModel::as_ref(app) + .all_live_conversations_for_terminal_surface(self.terminal_view(app).id()) + .map(|conversation| conversation.id()) + .collect(); // Capture agent view state: if fullscreen, store the active conversation ID let active_conversation_id = view diff --git a/app/src/pane_group/pane/view/header/mod.rs b/app/src/pane_group/pane/view/header/mod.rs index 127cf7b3..45592a98 100644 --- a/app/src/pane_group/pane/view/header/mod.rs +++ b/app/src/pane_group/pane/view/header/mod.rs @@ -1,10 +1,15 @@ use std::fmt::Debug; +use galaxy_core::features::FeatureFlag; +use galaxy_core::settings::Setting; +use galaxyui::presenter::ChildView; +use galaxyui::{ + AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, + ViewContext, ViewHandle, +}; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::{vec2f, Vector2F}; use sharing::SharedPaneContent; -use galaxy_core::features::FeatureFlag; -use galaxy_core::settings::Setting; use warpui::elements::{ AcceptedByDropTarget, Align, Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Draggable, DraggableState, Empty, Flex, Hoverable, @@ -12,15 +17,6 @@ use warpui::elements::{ ParentElement, ParentOffsetBounds, PositionedElementAnchor, PositionedElementOffsetBounds, Radius, SavePosition, Shrinkable, Stack, Text, }; -use galaxyui::presenter::ChildView; -use galaxyui::{ - AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, - ViewContext, ViewHandle, -}; -use pathfinder_geometry::{ - rect::RectF, - vector::{vec2f, Vector2F}, -}; use super::header_content::{HeaderContent, HeaderRenderContext, StandardHeaderOptions}; use super::PaneDropTargetData; diff --git a/app/src/pane_group/pane/workflow_pane.rs b/app/src/pane_group/pane/workflow_pane.rs index 9a321f50..4e439cf5 100644 --- a/app/src/pane_group/pane/workflow_pane.rs +++ b/app/src/pane_group/pane/workflow_pane.rs @@ -11,7 +11,7 @@ use super::{ }; use crate::app_state::{LeafContents, WorkflowPaneSnapshot}; use crate::drive::items::WarpDriveItemId; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::server::ids::SyncId; use crate::workflows::manager::{WorkflowManager, WorkflowOpenSource}; use crate::workflows::workflow_view::{WorkflowView, WorkflowViewEvent}; diff --git a/app/src/pane_group/tree.rs b/app/src/pane_group/tree.rs index a92427e5..89a51468 100644 --- a/app/src/pane_group/tree.rs +++ b/app/src/pane_group/tree.rs @@ -1,8 +1,6 @@ use std::collections::HashSet; use std::{fmt, iter, mem}; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, DispatchEventResult, Element, Empty, EventHandler, @@ -12,11 +10,13 @@ use galaxyui::elements::{ }; use galaxyui::platform::Cursor; use galaxyui::{AppContext, EntityId, ViewContext}; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; use super::{ActivationReason, PaneGroup, PaneId}; use crate::app_state; use crate::pane_group::{get_minimum_pane_size, DraggedBorder, PaneGroupAction}; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; #[cfg(test)] #[path = "tree_tests.rs"] diff --git a/app/src/pane_group/working_directories.rs b/app/src/pane_group/working_directories.rs index 97656c5b..e69bfadf 100644 --- a/app/src/pane_group/working_directories.rs +++ b/app/src/pane_group/working_directories.rs @@ -6,13 +6,13 @@ use std::path::Path; #[cfg(feature = "local_fs")] use std::path::PathBuf; +use galaxy_core::SessionId; #[cfg(feature = "local_fs")] use indexmap::IndexSet; #[cfg(feature = "local_fs")] use remote_server::manager::RemoteServerManager; #[cfg(feature = "local_fs")] use repo_metadata::repositories::DetectedRepositories; -use galaxy_core::SessionId; #[cfg(feature = "local_fs")] use warp_util::remote_path::RemotePath; #[cfg(feature = "local_fs")] diff --git a/app/src/persistence/agent.rs b/app/src/persistence/agent.rs index d90d4d49..e0e56170 100644 --- a/app/src/persistence/agent.rs +++ b/app/src/persistence/agent.rs @@ -205,9 +205,8 @@ pub(super) fn select_conversations_to_evict( pub(super) fn read_agent_conversations( conn: &mut SqliteConnection, ) -> Result, diesel::result::Error> { - let mut conversations_by_id = HashMap::::from_iter( - agent_conversations + agent_conversations::table .select(AgentConversationRecord::as_select()) .load(conn)? .into_iter() @@ -254,6 +253,7 @@ pub(crate) fn read_agent_conversation_by_id( conversation_id_str: &str, ) -> Result, diesel::result::Error> { use schema::agent_conversations::dsl as convo_dsl; + use schema::agent_tasks::dsl as tasks_dsl; let maybe_record: Option = convo_dsl::agent_conversations .filter(convo_dsl::conversation_id.eq(conversation_id_str.to_owned())) @@ -291,6 +291,8 @@ pub(super) fn delete_agent_conversations( conversation_ids: Vec, ) -> Result<(), diesel::result::Error> { use diesel::{ExpressionMethods, QueryDsl}; + use schema::agent_conversations::dsl as convo_dsl; + use schema::agent_tasks::dsl as tasks_dsl; conn.transaction::<_, Error, _>(|conn| { // Delete tasks for these conversations first (due to foreign key constraint) @@ -301,7 +303,7 @@ pub(super) fn delete_agent_conversations( // Delete the conversations themselves diesel::delete( - agent_conversations::table().filter(conversation_id.eq_any(&conversation_ids)), + agent_conversations::table.filter(convo_dsl::conversation_id.eq_any(&conversation_ids)), ) .execute(conn)?; diff --git a/app/src/persistence/block_list.rs b/app/src/persistence/block_list.rs index 12bf02ed..14c146b4 100644 --- a/app/src/persistence/block_list.rs +++ b/app/src/persistence/block_list.rs @@ -291,9 +291,9 @@ fn create_block<'a>( } pub(super) fn delete_blocks(conn: &mut SqliteConnection, pane_id: Vec) -> Result<(), Error> { + use schema::blocks::dsl::*; conn.transaction::<_, Error, _>(|conn| { - diesel::delete(schema::blocks::dsl::blocks.filter(pane_leaf_uuid.eq(pane_id.clone()))) - .execute(conn)?; + diesel::delete(blocks.filter(pane_leaf_uuid.eq(pane_id.clone()))).execute(conn)?; Ok(()) }) } @@ -303,6 +303,7 @@ pub(super) fn update_block_agent_view_visibility( target_block_id: &str, visibility: &SerializedAgentViewVisibility, ) -> anyhow::Result<()> { + use schema::blocks::dsl::*; let visibility_json = serde_json::to_string(visibility)?; diesel::update(blocks.filter(block_id.eq(target_block_id))) .set(agent_view_visibility.eq(visibility_json)) diff --git a/app/src/persistence/mod.rs b/app/src/persistence/mod.rs index 06e464ec..410d1b26 100644 --- a/app/src/persistence/mod.rs +++ b/app/src/persistence/mod.rs @@ -25,6 +25,9 @@ use std::thread::JoinHandle; use ai::project_context::model::ProjectRulePath; use ai::workspace::WorkspaceMetadata as CodeWorkspaceMetadata; use chrono::{DateTime, Local, Utc}; +use galaxy_core::command::ExitCode; +use galaxy_graphql::scalars::time::ServerTimestamp; +use galaxyui::{AppContext, Entity, SingletonEntity}; use instant::Instant; use lsp::supported_servers::LSPServerType; #[cfg(any(feature = "local_fs", feature = "integration_tests"))] diff --git a/app/src/persistence/sqlite.rs b/app/src/persistence/sqlite.rs index 75cd0c41..36e6d2ee 100644 --- a/app/src/persistence/sqlite.rs +++ b/app/src/persistence/sqlite.rs @@ -36,6 +36,7 @@ use diesel::{ use diesel_migrations::MigrationHarness; use galaxy_graphql::scalars::time::ServerTimestamp; use galaxyui::platform::FullscreenState; +use galaxyui::windowing::{MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH}; use galaxyui::{AppContext, SingletonEntity}; use itertools::Itertools; use libsqlite3_sys as sqlite3; @@ -45,7 +46,6 @@ use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::Vector2F; use persistence::model::AMBIENT_AGENT_PANE_KIND; use uuid::Uuid; -use galaxyui::windowing::{MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH}; use super::agent::{delete_agent_conversations, upsert_agent_conversation}; use super::block_list::{ @@ -86,7 +86,7 @@ use crate::cloud_object::model::actions::{ use crate::cloud_object::model::generic_string_model::{CloudStringObject, GenericStringObjectId}; use crate::cloud_object::{CloudObject, ObjectIdType}; use crate::code::editor_management::CodeSource; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::notebooks::NotebookId; use crate::persistence::agent::read_agent_conversations; use crate::persistence::block_list::{get_all_restored_blocks, read_ai_queries}; @@ -441,6 +441,8 @@ fn ensure_owner_only_dir(_path: &Path) -> Result<()> { #[cfg(unix)] fn ensure_owner_only_file(path: &Path) -> Result<()> { + use std::fs::Permissions; + use std::os::unix::fs::PermissionsExt; if path.exists() { std::fs::set_permissions(path, Permissions::from_mode(0o600)) @@ -1424,6 +1426,7 @@ fn decode_path(bytes: Vec) -> PathBuf { cfg_if::cfg_if! { if #[cfg(unix)] { + use std::os::unix::ffi::OsStringExt; OsString::from_vec(bytes).into() } else if #[cfg(windows)] { use std::os::windows::ffi::OsStringExt; @@ -1455,6 +1458,7 @@ fn save_codebase_index_metadata( fn get_all_codebase_index_metadata( conn: &mut SqliteConnection, ) -> Result, diesel::result::Error> { + use schema::workspace_metadata::dsl::*; Ok(workspace_metadata .load_iter::(conn)? @@ -1499,6 +1503,9 @@ fn upsert_workspace_language_server( server_type: LSPServerType, enablement: EnablementState, ) -> Result<()> { + use schema::workspace_language_server::dsl::*; + use schema::workspace_metadata::dsl::*; + let path_string = workspace_path.to_string_lossy().to_string(); // Try to find existing workspace @@ -1543,6 +1550,7 @@ fn upsert_workspace_language_server( } fn delete_codebase_index_metadata(conn: &mut SqliteConnection, index_path: &Path) -> Result<()> { + use schema::workspace_metadata::dsl::*; let target_path = index_path.to_string_lossy().to_string(); diesel::delete(workspace_metadata.filter(repo_path.eq(target_path))).execute(conn)?; @@ -1564,6 +1572,7 @@ fn save_project(conn: &mut SqliteConnection, project: Project) -> Result<()> { } fn get_all_projects(conn: &mut SqliteConnection) -> Result, diesel::result::Error> { + use schema::projects::dsl::*; Ok(projects .load_iter::(conn)? @@ -1572,6 +1581,7 @@ fn get_all_projects(conn: &mut SqliteConnection) -> Result, diesel: } fn delete_project(conn: &mut SqliteConnection, project_path: &str) -> Result<()> { + use schema::projects::dsl::*; diesel::delete(projects.filter(path.eq(project_path))).execute(conn)?; @@ -1599,6 +1609,7 @@ fn upsert_project_rules( conn: &mut SqliteConnection, new_project_rules: Vec, ) -> Result<()> { + use schema::project_rules::dsl::*; // SQLite doesn't support batch upserts, so we need to iterate for rule in new_project_rules { @@ -1619,6 +1630,7 @@ fn upsert_project_rules( } fn delete_project_rules(conn: &mut SqliteConnection, rules_paths: Vec) -> Result<()> { + use schema::project_rules::dsl::*; // Convert PathBuf to String for comparison let path_strings: Vec = rules_paths @@ -1695,6 +1707,7 @@ fn upsert_mcp_server_installation( conn: &mut SqliteConnection, mcp_server_installation: TemplatableMCPServerInstallation, ) -> Result<()> { + use schema::mcp_server_installations::dsl::*; let new_installation = model::NewMCPServerInstallation { id: mcp_server_installation.uuid().to_string(), @@ -1723,6 +1736,7 @@ fn upsert_mcp_server_installation( } fn delete_mcp_server_installations(conn: &mut SqliteConnection, uuids: Vec) -> Result<()> { + use schema::mcp_server_installations::dsl::*; let id_strings: Vec = uuids.iter().map(|uuid| uuid.to_string()).collect(); diesel::delete(mcp_server_installations.filter(id.eq_any(id_strings))).execute(conn)?; @@ -1734,6 +1748,7 @@ fn delete_mcp_server_installations_by_template_uuid( conn: &mut SqliteConnection, target_template_uuid: Uuid, ) -> Result<()> { + use schema::mcp_server_installations::dsl::*; diesel::delete(mcp_server_installations.filter( json_extract(templatable_mcp_server, "$.uuid").eq(target_template_uuid.to_string()), @@ -1746,6 +1761,7 @@ fn delete_mcp_server_installations_by_template_uuid( fn get_mcp_servers_to_restore( conn: &mut SqliteConnection, ) -> Result, diesel::result::Error> { + use schema::mcp_server_installations::dsl::*; let rows = mcp_server_installations .filter(restore_running.eq(true)) @@ -1765,6 +1781,7 @@ fn update_mcp_server_running( installation_uuid: Uuid, running: bool, ) -> Result<(), diesel::result::Error> { + use schema::mcp_server_installations::dsl::*; diesel::update(mcp_server_installations.find(installation_uuid.to_string())) .set(( @@ -1781,6 +1798,7 @@ fn add_ignored_suggestion( suggestion_text: String, suggestion_type_param: SuggestionType, ) -> Result<()> { + use schema::ignored_suggestions::dsl::*; let new_suggestion = model::NewIgnoredSuggestion { suggestion: suggestion_text, @@ -1801,6 +1819,7 @@ fn remove_ignored_suggestion( suggestion_text: String, suggestion_type_param: SuggestionType, ) -> Result<()> { + use schema::ignored_suggestions::dsl::*; diesel::delete( ignored_suggestions.filter( @@ -1896,6 +1915,9 @@ fn save_workspaces( workspaces_to_insert: Vec, ) -> Result<()> { use schema::team_settings::dsl::*; + use schema::teams::dsl::teams; + use schema::workspace_teams::dsl::workspace_teams; + use schema::workspaces::dsl::*; // Get currently selected workspace uid if there is one let current_workspace_uid: Option = workspaces @@ -2044,6 +2066,7 @@ fn save_workspaces( } fn set_current_workspace(conn: &mut SqliteConnection, workspace_uid: WorkspaceUid) -> Result<()> { + use schema::workspaces::dsl::*; // Set all existing workspaces as not selected diesel::update(workspaces) @@ -2837,6 +2860,7 @@ fn update_finished_command( conn: &mut SqliteConnection, completed_command: FinishedCommandMetadata, ) -> Result<(), Error> { + use schema::commands::dsl::*; let completed_command_session_id: Option = completed_command.session_id.as_u64().try_into().ok(); diff --git a/app/src/persistence/sqlite_tests.rs b/app/src/persistence/sqlite_tests.rs index c1b3b41f..bafcd272 100644 --- a/app/src/persistence/sqlite_tests.rs +++ b/app/src/persistence/sqlite_tests.rs @@ -5,10 +5,10 @@ use ai::workspace::WorkspaceMetadata; use chrono::Utc; use cloud_object_persistence::to_cloud_object_permissions; use diesel::connection::SimpleConnection; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::features::FeatureFlag; use galaxy_graphql::scalars::time::ServerTimestamp; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; use super::{ app_database_file_path, database_file_path_for_scope, decode_path, deduplicate_events, diff --git a/app/src/platform/wasm.rs b/app/src/platform/wasm.rs index 019b195a..185b5159 100644 --- a/app/src/platform/wasm.rs +++ b/app/src/platform/wasm.rs @@ -1,6 +1,6 @@ +pub use galaxy_web_event_bus::{emit_event, WarpEvent}; use js_sys::ReferenceError; use thiserror::Error; -pub use galaxy_web_event_bus::{emit_event, WarpEvent}; use wasm_bindgen::{JsCast, JsValue}; /// This function should be called early in application initialization to ensure that diff --git a/app/src/plugin/app/mod.rs b/app/src/plugin/app/mod.rs index d6d29b4f..d0b969f7 100644 --- a/app/src/plugin/app/mod.rs +++ b/app/src/plugin/app/mod.rs @@ -4,8 +4,8 @@ use std::sync::Arc; use anyhow::{Context, Result}; use command::blocking::Command; -use service_impl::{LogServiceImpl, PluginHostBootstrapServiceImpl}; use galaxyui::{Entity, ModelContext, SingletonEntity}; +use service_impl::{LogServiceImpl, PluginHostBootstrapServiceImpl}; use super::{PLUGIN_HOST_ADDRESS_ENV_VAR, PLUGIN_HOST_FLAG}; diff --git a/app/src/plugin/host/native/mod.rs b/app/src/plugin/host/native/mod.rs index cf4571c2..158d8bd1 100644 --- a/app/src/plugin/host/native/mod.rs +++ b/app/src/plugin/host/native/mod.rs @@ -12,8 +12,8 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use anyhow::{anyhow, Context, Result}; -use logging::initialize_logging; use galaxyui::r#async::executor::Background; +use logging::initialize_logging; use self::plugin_caller::PluginCaller; use self::plugin_ref::PluginRef; diff --git a/app/src/prompt/editor_modal.rs b/app/src/prompt/editor_modal.rs index 3cf2354c..4f503e79 100644 --- a/app/src/prompt/editor_modal.rs +++ b/app/src/prompt/editor_modal.rs @@ -1,8 +1,4 @@ use galaxy_core::ui::theme::Fill; -use itertools::Itertools; -use pathfinder_geometry::vector::vec2f; -use serde::Serialize; -use settings::Setting as _; use galaxyui::elements::{ Align, Border, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, @@ -15,6 +11,10 @@ use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; +use pathfinder_geometry::vector::vec2f; +use serde::Serialize; +use settings::Setting as _; use crate::appearance::AppearanceEvent; use crate::chip_configurator::{ChipConfigurator, ChipConfiguratorAction, ChipConfiguratorLayout}; diff --git a/app/src/quit_warning/mod.rs b/app/src/quit_warning/mod.rs index 9402abb9..97b7bc2d 100644 --- a/app/src/quit_warning/mod.rs +++ b/app/src/quit_warning/mod.rs @@ -1,9 +1,9 @@ use std::fmt::Write; -use itertools::Itertools; -use settings::ToggleableSetting as _; use galaxyui::modals::{AlertDialogWithCallbacks, AppModalCallback, ModalButton}; use galaxyui::{AppContext, EntityId, SingletonEntity, ViewContext, WeakViewHandle, WindowId}; +use itertools::Itertools; +use settings::ToggleableSetting as _; use crate::code::editor_management::{CodeEditorStatus, CodeEditorSummary}; use crate::pane_group::{CodePane, PaneGroup, PaneId, TerminalPane}; diff --git a/app/src/referral_theme_status.rs b/app/src/referral_theme_status.rs index a2915feb..005d68dd 100644 --- a/app/src/referral_theme_status.rs +++ b/app/src/referral_theme_status.rs @@ -1,8 +1,10 @@ use std::sync::Arc; +use galaxyui::{Entity, ModelContext, SingletonEntity}; use serde::{Deserialize, Serialize}; use crate::auth::AuthStateProvider; +use crate::galaxy_core::user_preferences::GetUserPreferences; use crate::safe_info; use crate::server::server_api::referral::{ReferralInfo, ReferralsClient}; diff --git a/app/src/remote_server/codebase_index_model.rs b/app/src/remote_server/codebase_index_model.rs index 611871e5..5fcf3b35 100644 --- a/app/src/remote_server/codebase_index_model.rs +++ b/app/src/remote_server/codebase_index_model.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use std::str::FromStr; use ai::index::full_source_code_embedding::NodeHash; -use remote_server::codebase_index_proto::{RemoteCodebaseIndexState, RemoteCodebaseIndexStatus}; use galaxy_core::{HostId, SessionId}; +use remote_server::codebase_index_proto::{RemoteCodebaseIndexState, RemoteCodebaseIndexStatus}; use warp_util::remote_path::RemotePath; use warp_util::standardized_path::StandardizedPath; use warpui::{Entity, ModelContext, SingletonEntity}; diff --git a/app/src/remote_server/server_model.rs b/app/src/remote_server/server_model.rs index d4b55f7b..11b5829c 100644 --- a/app/src/remote_server/server_model.rs +++ b/app/src/remote_server/server_model.rs @@ -11,9 +11,6 @@ use ::ai::index::full_source_code_embedding::{ ContentHash, FragmentMetadata as LocalFragmentMetadata, NodeHash, }; use ::ai::project_context::model::{ProjectContextModel, ProjectContextModelEvent}; -use remote_server::proto::OpenBufferSuccess; -use repo_metadata::repositories::{DetectedRepositories, RepoDetectionSource}; -use repo_metadata::{RepoMetadataEvent, RepoMetadataModel, RepositoryIdentifier}; use galaxy_core::channel::ChannelState; use galaxy_core::{safe_error, SessionId}; use galaxy_files::{FileModel, FileModelEvent}; @@ -24,6 +21,9 @@ use galaxy_util::standardized_path::StandardizedPath; use galaxyui::platform::TerminationMode; use galaxyui::r#async::{Spawnable, SpawnableOutput, SpawnedFutureHandle}; use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity}; +use remote_server::proto::OpenBufferSuccess; +use repo_metadata::repositories::{DetectedRepositories, RepoDetectionSource}; +use repo_metadata::{RepoMetadataEvent, RepoMetadataModel, RepositoryIdentifier}; use super::codebase_index_status::{ codebase_index_status_to_proto, disabled_codebase_index_status, diff --git a/app/src/remote_server/ssh_transport/installation/scp_fallback.rs b/app/src/remote_server/ssh_transport/installation/scp_fallback.rs index fd13d1d3..68f82907 100644 --- a/app/src/remote_server/ssh_transport/installation/scp_fallback.rs +++ b/app/src/remote_server/ssh_transport/installation/scp_fallback.rs @@ -193,7 +193,7 @@ async fn download_remote_server_tarball_to_cache( // cache hit is good enough for this install, so discard our temp file. match async_fs::rename(&temp_path, cache_path).await { Ok(()) => Ok(()), - Err(e) if is_valid_cached_tarball(cache_path).await => { + Err(_e) if is_valid_cached_tarball(cache_path).await => { let _ = async_fs::remove_file(&temp_path).await; Ok(()) } diff --git a/app/src/resource_center/keybindings_page.rs b/app/src/resource_center/keybindings_page.rs index 74cecbf5..52840307 100644 --- a/app/src/resource_center/keybindings_page.rs +++ b/app/src/resource_center/keybindings_page.rs @@ -1,5 +1,4 @@ use enum_iterator::{all, Sequence}; -use itertools::{Either, Itertools}; use galaxyui::elements::{ Align, Border, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element, Fill, Flex, MainAxisSize, MouseStateHandle, @@ -13,6 +12,7 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::{Either, Itertools}; use super::section_views::{ DESCRIPTION_FONT_SIZE, ITEM_PADDING_BOTTOM, SCROLLBAR_OFFSET, SCROLLBAR_WIDTH, diff --git a/app/src/resource_center/main_page.rs b/app/src/resource_center/main_page.rs index 7b8e9eba..50bdfc95 100644 --- a/app/src/resource_center/main_page.rs +++ b/app/src/resource_center/main_page.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ Align, ClippedScrollStateHandle, ClippedScrollable, Container, CornerRadius, Element, Empty, Fill, Flex, Hoverable, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, @@ -12,6 +11,7 @@ use galaxyui::{ AppContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use pathfinder_geometry::vector::vec2f; use super::section_views::feature_section::FeatureSectionEvent; use super::section_views::{ diff --git a/app/src/resource_center/mod.rs b/app/src/resource_center/mod.rs index f618029a..196e2756 100644 --- a/app/src/resource_center/mod.rs +++ b/app/src/resource_center/mod.rs @@ -16,11 +16,10 @@ mod section_views; pub use section_views::{ChangelogSectionView, ContentSectionView, FeatureSectionView}; pub mod sections; mod view; -use galaxyui::{keymap::Keystroke, AppContext, Entity, SingletonEntity}; -use serde::{Deserialize, Serialize}; -pub use view::{ResourceCenterAction, ResourceCenterEvent, ResourceCenterPage, ResourceCenterView}; use galaxyui::keymap::Keystroke; use galaxyui::{AppContext, Entity, SingletonEntity}; +use serde::{Deserialize, Serialize}; +pub use view::{ResourceCenterAction, ResourceCenterEvent, ResourceCenterPage, ResourceCenterView}; use self::section_views::feature_section::FeatureSection; diff --git a/app/src/resource_center/section_views/changelog_section.rs b/app/src/resource_center/section_views/changelog_section.rs index 6ea4cd93..16429c7d 100644 --- a/app/src/resource_center/section_views/changelog_section.rs +++ b/app/src/resource_center/section_views/changelog_section.rs @@ -1,5 +1,3 @@ -use instant::Instant; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ Border, CacheOption, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element, @@ -12,6 +10,8 @@ use galaxyui::{ AppContext, Entity, ModelAsRef, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use instant::Instant; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use super::feature_section::FeatureSection; use super::{SectionAction, SectionView}; diff --git a/app/src/resource_center/section_views/content_section.rs b/app/src/resource_center/section_views/content_section.rs index a75d72aa..2b847664 100644 --- a/app/src/resource_center/section_views/content_section.rs +++ b/app/src/resource_center/section_views/content_section.rs @@ -1,7 +1,7 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{ ConstrainedBox, Container, Element, Empty, Flex, MouseStateHandle, ParentElement, Shrinkable, }; +use pathfinder_color::ColorU; use warpui::ui_components::components::{UiComponent, UiComponentStyles}; use warpui::{AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext}; diff --git a/app/src/resource_center/section_views/feature_section.rs b/app/src/resource_center/section_views/feature_section.rs index 1861bd7c..ffe4fc8e 100644 --- a/app/src/resource_center/section_views/feature_section.rs +++ b/app/src/resource_center/section_views/feature_section.rs @@ -1,7 +1,3 @@ -use warpui::elements::{ - Align, ConstrainedBox, Container, CrossAxisAlignment, Element, Flex, Hoverable, Icon, - MouseState, MouseStateHandle, ParentElement, Shrinkable, -}; use galaxyui::fonts::Weight; use galaxyui::platform::Cursor; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; @@ -9,6 +5,10 @@ use galaxyui::{ Action, AppContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, WindowId, }; +use warpui::elements::{ + Align, ConstrainedBox, Container, CrossAxisAlignment, Element, Flex, Hoverable, Icon, + MouseState, MouseStateHandle, ParentElement, Shrinkable, +}; use super::{ SectionAction, SectionView, CHEVRON_ICON_SIZE, DESCRIPTION_FONT_SIZE, ELLIPSE_ICON_SIZE, diff --git a/app/src/resource_center/view.rs b/app/src/resource_center/view.rs index dcd1b761..62b41869 100644 --- a/app/src/resource_center/view.rs +++ b/app/src/resource_center/view.rs @@ -1,4 +1,3 @@ -use vec1::{vec1, Vec1}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::builder::AnimatedButtonOptions; use galaxyui::elements::{ @@ -15,6 +14,7 @@ use galaxyui::{ AppContext, Entity, EntityId, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use vec1::{vec1, Vec1}; use super::keybindings_page::KeybindingsEvent; use super::section_views::{ diff --git a/app/src/reward_view.rs b/app/src/reward_view.rs index b8fcf193..763744e2 100644 --- a/app/src/reward_view.rs +++ b/app/src/reward_view.rs @@ -1,5 +1,5 @@ use galaxy_core::ui::builder::UiBuilder; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{Align, Container, Element, Flex, MouseStateHandle, ParentElement}; use galaxyui::keymap::FixedBinding; use galaxyui::ui_components::button::ButtonVariant; diff --git a/app/src/root_view.rs b/app/src/root_view.rs index d37ce8bc..3f7c1ea5 100644 --- a/app/src/root_view.rs +++ b/app/src/root_view.rs @@ -5,6 +5,9 @@ use std::sync::Arc; use anyhow::Result; use cfg_if::cfg_if; +use galaxy_core::context_flag::ContextFlag; +use galaxy_core::safe_error; +use galaxy_core::user_preferences::GetUserPreferences as _; use itertools::Itertools; use lazy_static::lazy_static; use onboarding::{ @@ -17,9 +20,6 @@ use serde::{Deserialize, Serialize}; use session_sharing_protocol::common::SessionId; use settings::Setting as _; use url::Url; -use galaxy_core::context_flag::ContextFlag; -use galaxy_core::safe_error; -use galaxy_core::user_preferences::GetUserPreferences as _; use warpui::clipboard::ClipboardContent; use warpui::elements::{ Border, ChildAnchor, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Stack, @@ -87,7 +87,7 @@ use crate::terminal::keys_settings::KeysSettings; use crate::terminal::shell::ShellType; use crate::terminal::view::{cell_size_and_padding, TerminalAction}; use crate::themes::onboarding_theme_picker_themes; -use crate::themes::theme::{AnsiColorIdentifier, Blend, Fill, ThemeKind, WarpThemeConfig}; +use crate::themes::theme::{AnsiColorIdentifier, Blend, Fill, GalaxyThemeConfig, ThemeKind}; use crate::uri::{OpenMCPSettingsArgs, OpenSettingsArgs}; use crate::util::bindings::{self, is_binding_pty_compliant}; use crate::util::traffic_lights::{traffic_light_data, TrafficLightData, TrafficLightMouseStates}; diff --git a/app/src/search/action/data_source.rs b/app/src/search/action/data_source.rs index cde3d241..15676ff4 100644 --- a/app/src/search/action/data_source.rs +++ b/app/src/search/action/data_source.rs @@ -181,15 +181,20 @@ impl ActionSearcher for FuzzyActionSearcher { #[cfg(not(target_family = "wasm"))] mod full_text_searcher { + use std::collections::HashMap; + use std::sync::Arc; + use fuzzy_match::FuzzyMatchResult; use warp_search_core::define_search_schema; use warpui::keymap::{BindingId, DescriptionContext}; use crate::search::action::data_source::{is_excluded_binding, ActionSearcher, SearcherAction}; + use crate::search::action::search_item::MatchedBinding; use crate::search::data_source::QueryResult; use crate::search::searcher::{ SimpleFullTextSearcher, DEFAULT_MEMORY_BUDGET, SCORE_CONVERSION_FACTOR, }; + use crate::util::bindings::CommandBinding; define_search_schema!( schema_name: ACTION_SEARCH_SCHEMA, diff --git a/app/src/search/ai_context_menu/blocks/search_item.rs b/app/src/search/ai_context_menu/blocks/search_item.rs index d188653d..6076e6f6 100644 --- a/app/src/search/ai_context_menu/blocks/search_item.rs +++ b/app/src/search/ai_context_menu/blocks/search_item.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, Local}; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxy_core::command::ExitCode; +use ordered_float::OrderedFloat; use warpui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, ParentElement, Text, }; diff --git a/app/src/search/ai_context_menu/conversations/data_source.rs b/app/src/search/ai_context_menu/conversations/data_source.rs index acb944c0..74cbbb6a 100644 --- a/app/src/search/ai_context_menu/conversations/data_source.rs +++ b/app/src/search/ai_context_menu/conversations/data_source.rs @@ -75,7 +75,7 @@ impl SyncDataSource for ConversationDataSource { // assign higher values to more recently updated conversations. This ensures // recency acts as a tiebreaker when fuzzy scores are similar. let mut all_conversations = all_conversations; - all_conversations.sort_by(|a, b| a.last_updated.cmp(&b.last_updated)); + all_conversations.sort_by_key(|a| a.last_updated); let total_conversations = all_conversations.len(); let mut results: Vec> = if query_text.is_empty() { diff --git a/app/src/search/ai_context_menu/files/data_source.rs b/app/src/search/ai_context_menu/files/data_source.rs index 83b6e0b0..1caf3d5a 100644 --- a/app/src/search/ai_context_menu/files/data_source.rs +++ b/app/src/search/ai_context_menu/files/data_source.rs @@ -189,11 +189,7 @@ async fn fuzzy_match_files_zero_state( if is_git_changed || is_recently_opened { let rank = recency_index.get(&item.path).copied().unwrap_or(0); - let recency_bonus = if max_recency > 0 { - (30 * rank / max_recency) as i64 - } else { - 0 - }; + let recency_bonus = (30 * rank).checked_div(max_recency).unwrap_or(0) as i64; let base_score = if is_git_changed { 10000 } else { 0 }; let match_result = FuzzyMatchResult { score: base_score + recency_bonus, @@ -255,11 +251,7 @@ async fn fuzzy_match_files_query( // Add a recency bonus, capped at 30. let rank = recency_index.get(&item.path).copied().unwrap_or(0); - let recency_bonus = if max_recency > 0 { - (30 * rank / max_recency) as i64 - } else { - 0 - }; + let recency_bonus = (30 * rank).checked_div(max_recency).unwrap_or(0) as i64; match_result.score += recency_bonus; diff --git a/app/src/search/ai_context_menu/files/data_source_tests.rs b/app/src/search/ai_context_menu/files/data_source_tests.rs index 8f6c7647..615b9df6 100644 --- a/app/src/search/ai_context_menu/files/data_source_tests.rs +++ b/app/src/search/ai_context_menu/files/data_source_tests.rs @@ -3,18 +3,20 @@ use std::fs; use std::path::PathBuf; use std::sync::Arc; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::RepoMetadataModel; -use tempfile::tempdir; +use fuzzy_match::FuzzyMatchResult; use galaxyui::elements::Empty; use galaxyui::platform::WindowStyle; use galaxyui::r#async::block_on; use galaxyui::windowing::WindowManager; use galaxyui::{App, AppContext, Element, Entity, SingletonEntity, TypedActionView, View}; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::RepoMetadataModel; +use tempfile::tempdir; use crate::search::ai_context_menu::files::data_source::{ file_data_source_for_pwd, fuzzy_match_files, FileSnapshot, }; +use crate::search::ai_context_menu::files::search_item::FileSearchItem; use crate::search::ai_context_menu::mixer::AIContextMenuSearchableAction; use crate::search::data_source::Query; use crate::search::files::model::FileSearchModel; @@ -436,8 +438,6 @@ fn test_directory_search_support() { #[test] fn test_directory_action_type() { - - let directory_item = FileSearchItem { path: PathBuf::from("src/components/"), match_result: FuzzyMatchResult::no_match(), diff --git a/app/src/search/ai_context_menu/notebooks/data_source_test.rs b/app/src/search/ai_context_menu/notebooks/data_source_test.rs deleted file mode 100644 index 63d08ab1..00000000 --- a/app/src/search/ai_context_menu/notebooks/data_source_test.rs +++ /dev/null @@ -1,260 +0,0 @@ -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use chrono::{Duration, Utc}; - use galaxyui::{App, SingletonEntity}; - use settings::manager::SettingsManager; - - use crate::auth::AuthStateProvider; - use crate::cloud_object::model::persistence::CloudModel; - use crate::cloud_object::model::view::CloudViewModel; - use crate::cloud_object::{Owner, Revision, ServerMetadata, ServerNotebook, ServerPermissions}; - use crate::notebooks::manager::NotebookManager; - use crate::notebooks::CloudNotebookModel; - use crate::search::ai_context_menu::notebooks::data_source::NotebookDataSource; - use crate::search::data_source::Query; - use crate::search::mixer::SyncDataSource; - use crate::server::cloud_objects::update_manager::UpdateManager; - use crate::server::ids::{ServerId, SyncId}; - use crate::server::server_api::ServerApiProvider; - use crate::server::sync_queue::SyncQueue; - use crate::settings::AISettings; - use crate::system::SystemStats; - use crate::workspaces::team_tester::TeamTesterStatus; - use crate::workspaces::user_profiles::UserProfiles; - use crate::workspaces::user_workspaces::UserWorkspaces; - use crate::NetworkStatus; - - use crate::server::server_api::object::MockObjectClient; - use crate::server::server_api::team::MockTeamClient; - use crate::server::server_api::workspace::MockWorkspaceClient; - - fn mock_server_notebook_with_revision( - id: i64, - title: &str, - revision: Revision, - ) -> ServerNotebook { - ServerNotebook { - id: SyncId::ServerId(id.into()), - metadata: ServerMetadata { - uid: ServerId::default(), - revision, - metadata_last_updated_ts: Utc::now().into(), - trashed_ts: None, - folder_id: None, - is_welcome_object: false, - creator_uid: None, - last_editor_uid: None, - current_editor_uid: None, - }, - permissions: ServerPermissions { - space: Owner::mock_current_user(), - guests: Vec::new(), - anyone_link_sharing: None, - permissions_last_updated_ts: Utc::now().into(), - }, - model: CloudNotebookModel { - title: title.to_string(), - data: format!("{title} content"), - ai_document_id: None, - conversation_id: None, - }, - } - } - - fn initialize_app(app: &mut App) { - app.add_singleton_model(|_| NetworkStatus::new()); - app.add_singleton_model(|_| SystemStats::new()); - let mock_team_client = Arc::new(MockTeamClient::new()); - let mock_workspace_client = Arc::new(MockWorkspaceClient::new()); - app.add_singleton_model(|ctx| { - UserWorkspaces::mock( - mock_team_client.clone(), - mock_workspace_client.clone(), - vec![], - ctx, - ) - }); - app.add_singleton_model(TeamTesterStatus::new); - app.add_singleton_model(SyncQueue::mock); - app.add_singleton_model(CloudModel::mock); - app.add_singleton_model(|ctx| { - UpdateManager::new(None, Arc::new(MockObjectClient::new()), ctx) - }); - app.add_singleton_model(|_| UserProfiles::new(Vec::new())); - app.add_singleton_model(CloudViewModel::new); - app.add_singleton_model(NotebookManager::mock); - app.add_singleton_model(|_| ServerApiProvider::new_for_test()); - app.add_singleton_model(|_| SettingsManager::default()); - app.add_singleton_model(|_| AuthStateProvider::new_for_test()); - app.update(crate::settings::init_and_register_user_preferences); - app.update(AISettings::register_and_subscribe_to_events); - } - - #[test] - fn zero_state_scores_reflect_recency() { - App::test((), |mut app| async move { - initialize_app(&mut app); - - let now = Utc::now(); - CloudModel::handle(&app).update(&mut app, |model, ctx| { - model.upsert_from_server_notebook( - mock_server_notebook_with_revision( - 1, - "oldest", - (now - Duration::minutes(3)).into(), - ), - ctx, - ); - model.upsert_from_server_notebook( - mock_server_notebook_with_revision( - 2, - "middle", - (now - Duration::minutes(2)).into(), - ), - ctx, - ); - model.upsert_from_server_notebook( - mock_server_notebook_with_revision( - 3, - "newest", - (now - Duration::minutes(1)).into(), - ), - ctx, - ); - }); - - let data_source = NotebookDataSource::new(false); - let results = app.read(|app| data_source.run_query(&Query::from(""), app).unwrap()); - - assert_eq!(results.len(), 3); - // run_query sorts descending by score, so first result should be newest - let scores: Vec<_> = results.iter().map(|r| r.score()).collect(); - assert!( - scores[0] > scores[1] && scores[1] > scores[2], - "Expected scores in strictly descending order (newest first), got {scores:?}" - ); - }) - } - - #[test] - fn filtered_state_adds_recency_bonus_to_equal_matches() { - App::test((), |mut app| async move { - initialize_app(&mut app); - - let now = Utc::now(); - // All titles contain "plan" so fuzzy scores should be similar - CloudModel::handle(&app).update(&mut app, |model, ctx| { - model.upsert_from_server_notebook( - mock_server_notebook_with_revision( - 1, - "my first plan", - (now - Duration::minutes(3)).into(), - ), - ctx, - ); - model.upsert_from_server_notebook( - mock_server_notebook_with_revision( - 2, - "my second plan", - (now - Duration::minutes(2)).into(), - ), - ctx, - ); - model.upsert_from_server_notebook( - mock_server_notebook_with_revision( - 3, - "my third plan", - (now - Duration::minutes(1)).into(), - ), - ctx, - ); - }); - - let data_source = NotebookDataSource::new(false); - let results = app.read(|app| data_source.run_query(&Query::from("plan"), app).unwrap()); - - assert_eq!(results.len(), 3); - // All match "plan" similarly; recency bonus should make newer items score higher - let scores: Vec<_> = results.iter().map(|r| r.score()).collect(); - assert!( - scores[0] > scores[1] && scores[1] > scores[2], - "Expected scores in strictly descending order (newest first), got {scores:?}" - ); - }) - } - - #[test] - fn test_multibyte_character_truncation() { - // Test string with multibyte characters (emojis, accented chars) - let test_content = "This is a test with emojis 🚀 and accented chars like café and naïve that should be truncated properly without panicking. This string is intentionally long to test the 200 character limit and ensure we don't slice in the middle of multibyte characters like 你好世界"; - - let truncated = if test_content.len() > 200 { - let result = test_content - .char_indices() - .take_while(|(i, _)| *i <= 197) - .last() - .map(|(i, c)| &test_content[..i + c.len_utf8()]) - .unwrap_or(""); - format!("{result}...") - } else { - test_content.to_string() - }; - - // Should not panic and should produce a valid string - assert!(!truncated.is_empty()); - assert!(truncated.ends_with("...")); - // The truncated string should be valid UTF-8 - assert!(std::str::from_utf8(truncated.as_bytes()).is_ok()); - } - - #[test] - fn test_truncation_with_boundary_at_multibyte_char() { - // Create a string where byte 197 falls exactly in the middle of a multibyte character - let mut test_content = "a".repeat(195); // 195 single-byte chars - test_content.push('🚀'); // 4-byte emoji at positions 195-198 - test_content.push_str("more text after emoji"); - - // This should not panic even though byte 197 is in the middle of the emoji - let truncated = if test_content.len() > 200 { - let result = test_content - .char_indices() - .take_while(|(i, _)| *i <= 197) - .last() - .map(|(i, c)| &test_content[..i + c.len_utf8()]) - .unwrap_or(""); - format!("{result}...") - } else { - test_content.to_string() - }; - - // Should not panic and should produce a valid string - assert!(!truncated.is_empty()); - // The truncated string should be valid UTF-8 - assert!(std::str::from_utf8(truncated.as_bytes()).is_ok()); - // Should either include the full emoji or stop before it - assert!(!truncated.contains("🚀") || truncated.contains("🚀...")); - } - - #[test] - fn test_short_content_not_truncated() { - let short_content = "This is a short string with emoji 🚀"; - - let result = if short_content.len() > 200 { - let truncated = short_content - .char_indices() - .take_while(|(i, _)| *i <= 197) - .last() - .map(|(i, c)| &short_content[..i + c.len_utf8()]) - .unwrap_or(""); - format!("{truncated}...") - } else { - short_content.to_string() - }; - - // Short content should not be truncated - assert_eq!(result, short_content); - assert!(!result.ends_with("...")); - } -} diff --git a/app/src/search/ai_context_menu/notebooks/search_item.rs b/app/src/search/ai_context_menu/notebooks/search_item.rs index 86d6aeaf..19c58033 100644 --- a/app/src/search/ai_context_menu/notebooks/search_item.rs +++ b/app/src/search/ai_context_menu/notebooks/search_item.rs @@ -1,12 +1,12 @@ use std::fmt::Debug; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, ParentElement, Text, }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::cloud_object::ObjectType; diff --git a/app/src/search/ai_context_menu/rules/data_source_tests.rs b/app/src/search/ai_context_menu/rules/data_source_tests.rs index 3b3ee4b0..29721c39 100644 --- a/app/src/search/ai_context_menu/rules/data_source_tests.rs +++ b/app/src/search/ai_context_menu/rules/data_source_tests.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use chrono::{Duration, Utc}; use cloud_object_client::MockObjectClient; +use galaxyui::{App, SingletonEntity}; use settings::manager::SettingsManager; use crate::ai::facts::{AIFact, AIMemory, CloudAIFactModel}; diff --git a/app/src/search/ai_context_menu/rules/search_item.rs b/app/src/search/ai_context_menu/rules/search_item.rs index 0cc336a7..6232b9e7 100644 --- a/app/src/search/ai_context_menu/rules/search_item.rs +++ b/app/src/search/ai_context_menu/rules/search_item.rs @@ -1,12 +1,12 @@ use std::fmt::Debug; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, ParentElement, Text, }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::cloud_object::{GenericStringObjectFormat, JsonObjectType, ObjectType}; diff --git a/app/src/search/ai_context_menu/skills/search_item.rs b/app/src/search/ai_context_menu/skills/search_item.rs index 9c9a02df..2731fc80 100644 --- a/app/src/search/ai_context_menu/skills/search_item.rs +++ b/app/src/search/ai_context_menu/skills/search_item.rs @@ -1,12 +1,12 @@ use ai::skills::SkillProvider; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxy_core::ui::icons::Icon; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, ParentElement, Shrinkable, Text, }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::search::ai_context_menu::mixer::AIContextMenuSearchableAction; diff --git a/app/src/search/ai_context_menu/view.rs b/app/src/search/ai_context_menu/view.rs index 8ee7e564..b58b6bf5 100644 --- a/app/src/search/ai_context_menu/view.rs +++ b/app/src/search/ai_context_menu/view.rs @@ -3,11 +3,11 @@ use std::ops::Range; use std::time::Duration; use async_channel::Sender; +use galaxy_core::features::FeatureFlag; use itertools::Itertools; #[cfg(not(target_family = "wasm"))] use repo_metadata::repositories::DetectedRepositories; use settings::Setting as _; -use galaxy_core::features::FeatureFlag; use warpui::elements::{ AnchorPair, Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Empty, Fill, Flex, Hoverable, Icon, MouseStateHandle, OffsetPositioning, OffsetType, diff --git a/app/src/search/ai_context_menu/workflows/search_item.rs b/app/src/search/ai_context_menu/workflows/search_item.rs index d682e68c..eb51c3a9 100644 --- a/app/src/search/ai_context_menu/workflows/search_item.rs +++ b/app/src/search/ai_context_menu/workflows/search_item.rs @@ -1,12 +1,12 @@ use std::fmt::Debug; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, ParentElement, Text, }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::cloud_object::ObjectType; diff --git a/app/src/search/command_palette/conversations/search_item.rs b/app/src/search/command_palette/conversations/search_item.rs index 2d694019..90c9a769 100644 --- a/app/src/search/command_palette/conversations/search_item.rs +++ b/app/src/search/command_palette/conversations/search_item.rs @@ -1,10 +1,10 @@ -use ordered_float::OrderedFloat; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; +use ordered_float::OrderedFloat; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use warpui::elements::{ AnchorPair, Container, CrossAxisAlignment, Expanded, Fill, Flex, Highlight, MainAxisSize, MouseStateHandle, OffsetPositioning, OffsetType, ParentElement, ParentOffsetBounds, diff --git a/app/src/search/command_palette/data_sources.rs b/app/src/search/command_palette/data_sources.rs index f4ebdca3..b59a085f 100644 --- a/app/src/search/command_palette/data_sources.rs +++ b/app/src/search/command_palette/data_sources.rs @@ -1,6 +1,7 @@ use std::collections::HashSet; use std::path::PathBuf; +use fuzzy_match::FuzzyMatchResult; use galaxy_core::context_flag::ContextFlag; use galaxy_core::features::FeatureFlag; use warpui::keymap::BindingId; @@ -10,6 +11,7 @@ use super::{conversations, warp_drive}; use crate::drive::settings::WarpDriveSettings; use crate::search::action::CommandBindingDataSource; use crate::search::binding_source::BindingSource; +use crate::search::command_palette::files::search_item::FileSearchItem; use crate::search::command_palette::mixer::{CommandPaletteItemAction, ItemSummary}; use crate::search::command_palette::new_session::NewSessionDataSource; use crate::search::command_palette::repos::RepoDataSource; @@ -248,8 +250,6 @@ impl DataSourceStore { // Create a file search item from the summary use fuzzy_match::FuzzyMatchResult; - use crate::search::command_palette::files::search_item::FileSearchItem; - let search_item = FileSearchItem { path: PathBuf::from(path), project_directory: project_directory.clone(), @@ -265,7 +265,6 @@ impl DataSourceStore { } => { // Create a directory search item from the summary - let search_item = FileSearchItem { path: PathBuf::from(path), project_directory: project_directory.clone(), diff --git a/app/src/search/command_palette/data_sources_tests.rs b/app/src/search/command_palette/data_sources_tests.rs index 4cce3aca..1e994a9c 100644 --- a/app/src/search/command_palette/data_sources_tests.rs +++ b/app/src/search/command_palette/data_sources_tests.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use chrono::Utc; use cloud_object_client::MockObjectClient; use settings::manager::SettingsManager; +use warpui::App; use super::*; use crate::auth::AuthStateProvider; diff --git a/app/src/search/command_palette/files/data_source.rs b/app/src/search/command_palette/files/data_source.rs index 21124fff..6da316a5 100644 --- a/app/src/search/command_palette/files/data_source.rs +++ b/app/src/search/command_palette/files/data_source.rs @@ -7,10 +7,10 @@ use std::sync::Arc; use futures_lite::FutureExt; use fuzzy_match::FuzzyMatchResult; -use instant::Instant; -use itertools::Itertools; use galaxy_util::path::CleanPathResult; use galaxyui::{AppContext, Entity, SingletonEntity}; +use instant::Instant; +use itertools::Itertools; use super::search_item::{CreateFileSearchItem, FileSearchItem}; use crate::code::opened_files::{OpenedFilesInRepo, OpenedFilesModel}; diff --git a/app/src/search/command_palette/files/search_item.rs b/app/src/search/command_palette/files/search_item.rs index 4fc053ac..05462d03 100644 --- a/app/src/search/command_palette/files/search_item.rs +++ b/app/src/search/command_palette/files/search_item.rs @@ -2,11 +2,11 @@ use std::fmt::Debug; use std::path::PathBuf; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxy_util::path::LineAndColumnArg; use galaxyui::elements::{Align, ConstrainedBox, Container, Flex, Icon, ParentElement, Text}; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::search::command_palette::mixer::CommandPaletteItemAction; diff --git a/app/src/search/command_palette/filter_chip_renderer.rs b/app/src/search/command_palette/filter_chip_renderer.rs index 4ed43d2e..1aba3683 100644 --- a/app/src/search/command_palette/filter_chip_renderer.rs +++ b/app/src/search/command_palette/filter_chip_renderer.rs @@ -1,10 +1,10 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{ ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Hoverable, Icon, MouseStateHandle, ParentElement, Radius, Text, }; use galaxyui::platform::Cursor; use galaxyui::{Element, EventContext}; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::drive::cloud_object_styling::warp_drive_icon_color; @@ -149,7 +149,7 @@ impl FilterChipRenderer for QueryFilter { mod styles { use galaxyui::elements::{Border, MouseState}; - use crate::themes::theme::{Blend, Fill, WarpTheme}; + use crate::themes::theme::{Blend, Fill, GalaxyTheme}; /// Size of the border when the query filter is hovered. const HOVERED_BORDER_SIZE: f32 = 2.; diff --git a/app/src/search/command_palette/launch_config/data_source.rs b/app/src/search/command_palette/launch_config/data_source.rs index d032b4d3..bd22634f 100644 --- a/app/src/search/command_palette/launch_config/data_source.rs +++ b/app/src/search/command_palette/launch_config/data_source.rs @@ -9,7 +9,7 @@ use crate::search::command_palette::launch_config::search_item::SearchItem; use crate::search::command_palette::mixer::CommandPaletteItemAction; use crate::search::data_source::{DataSourceSearchError, Query, QueryResult}; use crate::search::mixer::{DataSourceRunErrorWrapper, SyncDataSource}; -use crate::user_config::{WarpConfig, WarpConfigUpdateEvent}; +use crate::user_config::{GalaxyConfig, GalaxyConfigUpdateEvent}; /// Datasource that searches against `LaunchConfig`s. pub struct DataSource { @@ -50,11 +50,11 @@ impl DataSource { fn handle_config_event( &mut self, - _: ModelHandle, - event: &WarpConfigUpdateEvent, + _: ModelHandle, + event: &GalaxyConfigUpdateEvent, ctx: &mut ModelContext, ) { - if matches!(event, WarpConfigUpdateEvent::LaunchConfigs) { + if matches!(event, GalaxyConfigUpdateEvent::LaunchConfigs) { self.searcher.refresh_search_index(ctx); } } @@ -123,14 +123,19 @@ impl LaunchConfigSearcher for FuzzyLaunchConfigSearcher { #[cfg(not(target_family = "wasm"))] mod full_text_searcher { + use std::collections::HashMap; + use std::sync::Arc; + use fuzzy_match::FuzzyMatchResult; use warp_search_core::define_search_schema; use warpui::r#async::executor::Background; use warpui::{AppContext, SingletonEntity}; + use crate::launch_configs::launch_config::LaunchConfig; use crate::search::command_palette::launch_config::data_source::LaunchConfigSearcher; + use crate::search::command_palette::launch_config::search_item::SearchItem; use crate::search::searcher::{AsyncSearcher, DEFAULT_MEMORY_BUDGET, SCORE_CONVERSION_FACTOR}; - use crate::user_config::WarpConfig; + use crate::user_config::GalaxyConfig; // The name of the launch configs are duplicated to ensure that the searcher // hashes the name to uniquely identify the launch config. diff --git a/app/src/search/command_palette/navigation/search.rs b/app/src/search/command_palette/navigation/search.rs index 9dca5d9f..24521dfd 100644 --- a/app/src/search/command_palette/navigation/search.rs +++ b/app/src/search/command_palette/navigation/search.rs @@ -246,12 +246,17 @@ pub use full_text_searcher::FullTextSessionSearcher; mod full_text_searcher { use std::collections::HashMap; + use galaxyui::{AppContext, ModelHandle}; + use itertools::Itertools; use warp_search_core::define_search_schema; + use crate::pane_group::PaneId; use crate::search::command_palette::navigation::search::{ searchable_session_string_and_ranges, MatchedSession, SearcherAction, SessionHighlightIndices, SessionMatchResult, SessionSearcher, }; + use crate::search::command_palette::navigation::search_item::SearchItem; + use crate::search::data_source::QueryResult; use crate::search::searcher::{DEFAULT_MEMORY_BUDGET, SCORE_CONVERSION_FACTOR}; use crate::session_management::{SessionNavigationData, SessionSource}; diff --git a/app/src/search/command_palette/new_session/data_source.rs b/app/src/search/command_palette/new_session/data_source.rs index 25321f64..26526258 100644 --- a/app/src/search/command_palette/new_session/data_source.rs +++ b/app/src/search/command_palette/new_session/data_source.rs @@ -300,6 +300,9 @@ impl NewSessionSearcher for FuzzyNewSessionSearcher { #[cfg(not(target_family = "wasm"))] mod full_text_searcher { + use std::collections::HashMap; + use std::sync::Arc; + use fuzzy_match::FuzzyMatchResult; use warp_search_core::define_search_schema; use warpui::r#async::executor::Background; diff --git a/app/src/search/command_palette/new_session/search_item.rs b/app/src/search/command_palette/new_session/search_item.rs index 989d9134..11c17361 100644 --- a/app/src/search/command_palette/new_session/search_item.rs +++ b/app/src/search/command_palette/new_session/search_item.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use super::new_session_option::NewSessionOption; use crate::appearance::Appearance; diff --git a/app/src/search/command_palette/render_util.rs b/app/src/search/command_palette/render_util.rs index 10d49bb4..073ca5eb 100644 --- a/app/src/search/command_palette/render_util.rs +++ b/app/src/search/command_palette/render_util.rs @@ -1,5 +1,5 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; use warpui::elements::{Align, ConstrainedBox, Container, Empty}; use warpui::Element; diff --git a/app/src/search/command_palette/repos/repo_search_item.rs b/app/src/search/command_palette/repos/repo_search_item.rs index f287e016..c66a837b 100644 --- a/app/src/search/command_palette/repos/repo_search_item.rs +++ b/app/src/search/command_palette/repos/repo_search_item.rs @@ -2,11 +2,11 @@ use std::path::Path; use ai::workspace::WorkspaceMetadata; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{Align, ConstrainedBox, Flex, Highlight, ParentElement, Shrinkable, Text}; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::search::action::search_item::styles; diff --git a/app/src/search/command_palette/selected_items_tests.rs b/app/src/search/command_palette/selected_items_tests.rs index 63d3863b..7855ec0e 100644 --- a/app/src/search/command_palette/selected_items_tests.rs +++ b/app/src/search/command_palette/selected_items_tests.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use warpui::keymap::BindingId; use super::*; diff --git a/app/src/search/command_palette/view.rs b/app/src/search/command_palette/view.rs index a6d6af43..8933ea84 100644 --- a/app/src/search/command_palette/view.rs +++ b/app/src/search/command_palette/view.rs @@ -2,8 +2,6 @@ use std::collections::HashSet; use std::ops::Deref; use std::sync::Arc; -use itertools::Itertools; -use lazy_static::lazy_static; use galaxy_core::send_telemetry_from_app_ctx; use galaxy_util::path::LineAndColumnArg; use galaxyui::elements::{ @@ -19,6 +17,8 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, FocusContext, ModelHandle, SingletonEntity, TypedActionView, ViewContext, ViewHandle, WindowId, }; +use itertools::Itertools; +use lazy_static::lazy_static; use super::super::palette_styles as styles; use super::CommandPaletteMixer; @@ -44,7 +44,7 @@ use crate::server::telemetry::{LaunchConfigUiLocation, TelemetryEvent}; use crate::session_management::SessionSource; use crate::settings::CtrlTabBehavior; use crate::terminal::keys_settings::KeysSettings; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::view_components::DismissibleToast; use crate::workspace::{active_terminal_in_window, ForkedConversationDestination, WorkspaceAction}; use crate::{send_telemetry_from_ctx, ToastStack}; diff --git a/app/src/search/command_palette/warp_drive/data_source.rs b/app/src/search/command_palette/warp_drive/data_source.rs index d7e0ef0c..50193805 100644 --- a/app/src/search/command_palette/warp_drive/data_source.rs +++ b/app/src/search/command_palette/warp_drive/data_source.rs @@ -550,15 +550,22 @@ mod full_text_searcher { use crate::cloud_object::{ CloudObject, CloudObjectLocation, GenericStringObjectFormat, JsonObjectType, ObjectType, }; + use crate::drive::folders::CloudFolder; + use crate::env_vars::CloudEnvVarCollection; use crate::notebooks::manager::NotebookManager; + use crate::notebooks::CloudNotebook; use crate::search::command_palette::warp_drive::data_source::WarpDriveSearcher; use crate::search::command_palette::warp_drive::env_var_collection_search_item::{ EnvVarCollectionSearchItem, ENV_VAR_NAME_SEPARATOR, }; use crate::search::command_palette::warp_drive::notebook_search_item::NotebookSearchItem; use crate::search::command_palette::warp_drive::workflow_search_item::WorkflowSearchItem; + use crate::search::env_var_collections::fuzzy_match::FuzzyMatchEnvVarCollectionResult; + use crate::search::notebooks::fuzzy_match::FuzzyMatchNotebookResult; use crate::search::searcher::{AsyncSearcher, DEFAULT_MEMORY_BUDGET, SCORE_CONVERSION_FACTOR}; + use crate::search::workflows::fuzzy_match::FuzzyMatchWorkflowResult; use crate::server::ids::ObjectUid; + use crate::workflows::CloudWorkflow; /// Memory budget for the search index of warp drive. /// Warp could potentially have a lot of objects, so we increase it from the default of 50MB to 100MB diff --git a/app/src/search/command_palette/zero_state.rs b/app/src/search/command_palette/zero_state.rs index 37905764..937c3c2a 100644 --- a/app/src/search/command_palette/zero_state.rs +++ b/app/src/search/command_palette/zero_state.rs @@ -1,7 +1,6 @@ mod items; use std::collections::HashMap; -pub use items::Items; use galaxy_core::context_flag::ContextFlag; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{Container, Flex, MouseStateHandle, ParentElement, Shrinkable, Wrap}; @@ -9,6 +8,7 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, WindowId, }; +pub use items::Items; use crate::appearance::Appearance; use crate::drive::settings::WarpDriveSettings; diff --git a/app/src/search/command_search/ai_queries/ai_queries_search_item.rs b/app/src/search/command_search/ai_queries/ai_queries_search_item.rs index 7328400f..cde20c26 100644 --- a/app/src/search/command_search/ai_queries/ai_queries_search_item.rs +++ b/app/src/search/command_search/ai_queries/ai_queries_search_item.rs @@ -1,5 +1,4 @@ use chrono::{DateTime, Local}; -use ordered_float::OrderedFloat; use galaxy_core::ui::builder::MIN_FONT_SIZE; use galaxyui::elements::{ Align, ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, MainAxisAlignment, @@ -8,6 +7,7 @@ use galaxyui::elements::{ use galaxyui::fonts::{Properties, Weight}; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::ai::blocklist::AIQueryHistoryOutputStatus; use crate::appearance::Appearance; diff --git a/app/src/search/command_search/env_var_collections/env_var_collection_search_item.rs b/app/src/search/command_search/env_var_collections/env_var_collection_search_item.rs index b9f45e4e..4b4484f3 100644 --- a/app/src/search/command_search/env_var_collections/env_var_collection_search_item.rs +++ b/app/src/search/command_search/env_var_collections/env_var_collection_search_item.rs @@ -1,5 +1,3 @@ -use itertools::Itertools; -use ordered_float::OrderedFloat; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, MainAxisAlignment, MainAxisSize, ParentElement, Text, @@ -7,6 +5,8 @@ use galaxyui::elements::{ use galaxyui::fonts::{Properties, Weight}; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use itertools::Itertools; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::env_vars::CloudEnvVarCollection; diff --git a/app/src/search/command_search/history/history_search_item.rs b/app/src/search/command_search/history/history_search_item.rs index b1b74fc1..d59407de 100644 --- a/app/src/search/command_search/history/history_search_item.rs +++ b/app/src/search/command_search/history/history_search_item.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use ordered_float::OrderedFloat; use galaxy_core::ui::builder; +use ordered_float::OrderedFloat; use warpui::elements::{ Align, ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, Icon, MainAxisAlignment, MainAxisSize, ParentElement, Shrinkable, Text, diff --git a/app/src/search/command_search/notebooks/notebook_search_item.rs b/app/src/search/command_search/notebooks/notebook_search_item.rs index e4522846..f1c117e8 100644 --- a/app/src/search/command_search/notebooks/notebook_search_item.rs +++ b/app/src/search/command_search/notebooks/notebook_search_item.rs @@ -1,12 +1,12 @@ use std::sync::Arc; -use ordered_float::OrderedFloat; use galaxyui::elements::{ ConstrainedBox, Container, Flex, Highlight, Icon, MainAxisAlignment, MainAxisSize, ParentElement, Text, }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::notebooks::CloudNotebookModel; diff --git a/app/src/search/command_search/projects/project_search_item.rs b/app/src/search/command_search/projects/project_search_item.rs index d896ac65..b1502a2c 100644 --- a/app/src/search/command_search/projects/project_search_item.rs +++ b/app/src/search/command_search/projects/project_search_item.rs @@ -3,11 +3,11 @@ use std::path::PathBuf; use chrono::NaiveDateTime; use fuzzy_match::FuzzyMatchResult; -use ordered_float::OrderedFloat; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{Align, ConstrainedBox, Flex, Highlight, ParentElement, Shrinkable, Text}; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::search::action::search_item::styles; diff --git a/app/src/search/command_search/settings.rs b/app/src/search/command_search/settings.rs index a616b198..b4c4be75 100644 --- a/app/src/search/command_search/settings.rs +++ b/app/src/search/command_search/settings.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(CommandSearchSettings, settings: [ show_global_workflows_in_universal_search: ShowGlobalWorkflowsInUniversalSearch { diff --git a/app/src/search/command_search/view.rs b/app/src/search/command_search/view.rs index 06822910..9bd01435 100644 --- a/app/src/search/command_search/view.rs +++ b/app/src/search/command_search/view.rs @@ -4,12 +4,8 @@ use std::sync::Arc; use std::time::Duration; use async_channel::Sender; -use itertools::Itertools; -use lazy_static::lazy_static; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::features::FeatureFlag; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ resizable_state_handle, Align, AnchorPair, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Fill, Flex, MouseStateHandle, OffsetPositioning, OffsetType, @@ -23,7 +19,10 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; -use std::{collections::HashSet, ops::Range, sync::Arc, time::Duration}; +use itertools::Itertools; +use lazy_static::lazy_static; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::Vector2F; use super::ai_queries::AIQueriesDataSource; use super::env_var_collections::EnvVarCollectionDataSource; @@ -1118,7 +1117,9 @@ impl CommandSearchView { pub mod styles { use galaxyui::elements::{Border, DropShadow, ScrollbarWidth}; + use pathfinder_color::ColorU; + use crate::appearance::Appearance; use crate::themes::theme::Fill; pub const CORNER_RADIUS: f32 = 8.; diff --git a/app/src/search/command_search/warp_ai.rs b/app/src/search/command_search/warp_ai.rs index efaa05ca..b3270195 100644 --- a/app/src/search/command_search/warp_ai.rs +++ b/app/src/search/command_search/warp_ai.rs @@ -3,15 +3,11 @@ use std::sync::Arc; use async_trait::async_trait; use galaxy_core::ui::builder; -use galaxyui::{ - elements::{ConstrainedBox, Container, Text}, - AppContext, Element, SingletonEntity, -}; +use galaxyui::elements::{ConstrainedBox, Container, Text}; +use galaxyui::{AppContext, Element, SingletonEntity}; use itertools::Itertools; use ordered_float::OrderedFloat; use serde_json::json; -use galaxyui::elements::{ConstrainedBox, Container, Text}; -use galaxyui::{AppContext, Element, SingletonEntity}; use super::workflows::{WorkflowIdentity, WorkflowSearchItem}; use crate::ai::AIRequestUsageModel; @@ -257,6 +253,7 @@ impl DataSourceRunError for GenerateCommandsFromNaturalLanguageError { } mod styles { + use crate::appearance::Appearance; /// Returns the icon size to be used for the 'sparkle' icon in the AI command search result. /// The icon appeaars smaller than its size would indicate, so make a bit larger than icons diff --git a/app/src/search/command_search/workflows/workflow_search_item.rs b/app/src/search/command_search/workflows/workflow_search_item.rs index c045dd8e..1cc66159 100644 --- a/app/src/search/command_search/workflows/workflow_search_item.rs +++ b/app/src/search/command_search/workflows/workflow_search_item.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use ordered_float::OrderedFloat; use galaxyui::elements::{ Border, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Highlight, MainAxisAlignment, MainAxisSize, ParentElement, Radius, Shrinkable, Text, @@ -8,6 +7,7 @@ use galaxyui::elements::{ use galaxyui::fonts::{Properties, Weight}; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::search::command_search::searcher::{AcceptedWorkflow, CommandSearchItemAction}; diff --git a/app/src/search/command_search/workflows/workflows_data_source.rs b/app/src/search/command_search/workflows/workflows_data_source.rs index 0cf5ef4a..d9fabbfd 100644 --- a/app/src/search/command_search/workflows/workflows_data_source.rs +++ b/app/src/search/command_search/workflows/workflows_data_source.rs @@ -10,7 +10,7 @@ use crate::search::command_search::settings::CommandSearchSettings; use crate::search::data_source::{Query, QueryResult}; use crate::search::mixer::{DataSourceRunErrorWrapper, SyncDataSource}; use crate::search::workflows::fuzzy_match::FuzzyMatchWorkflowResult; -use crate::user_config::WarpConfig; +use crate::user_config::GalaxyConfig; use crate::workflows::local_workflows::LocalWorkflows; #[cfg(feature = "local_fs")] use crate::workflows::local_workflows::UseCache; diff --git a/app/src/search/command_search/zero_state.rs b/app/src/search/command_search/zero_state.rs index cc687050..ff4625f3 100644 --- a/app/src/search/command_search/zero_state.rs +++ b/app/src/search/command_search/zero_state.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use lazy_static::lazy_static; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ @@ -8,6 +7,7 @@ use galaxyui::elements::{ }; use galaxyui::platform::Cursor; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use lazy_static::lazy_static; use crate::appearance::Appearance; use crate::drive::settings::{WarpDriveSettings, WarpDriveSettingsChangedEvent}; @@ -305,6 +305,7 @@ fn valid_query_filters(app: &AppContext) -> Vec { } mod styles { + use crate::appearance::Appearance; pub const FILTER_CHIP_MARGIN: f32 = 8.; pub const FILTER_CHIPS_MARGIN_BOTTOM: f32 = 16.; diff --git a/app/src/search/external_secrets/external_secret_data_source.rs b/app/src/search/external_secrets/external_secret_data_source.rs index abf9c945..0b67d871 100644 --- a/app/src/search/external_secrets/external_secret_data_source.rs +++ b/app/src/search/external_secrets/external_secret_data_source.rs @@ -1,3 +1,4 @@ +use galaxyui::AppContext; use itertools::Itertools; use super::external_secret_fuzzy_match::FuzzyMatchExternalSecretResult; diff --git a/app/src/search/external_secrets/external_secret_search_item.rs b/app/src/search/external_secrets/external_secret_search_item.rs index 89c3bdfb..75640cf6 100644 --- a/app/src/search/external_secrets/external_secret_search_item.rs +++ b/app/src/search/external_secrets/external_secret_search_item.rs @@ -1,7 +1,7 @@ -use ordered_float::OrderedFloat; use galaxyui::elements::{ConstrainedBox, Container, Highlight, Text}; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use super::external_secret_fuzzy_match::FuzzyMatchExternalSecretResult; use super::searcher::ExternalSecretSearchItemAction; diff --git a/app/src/search/external_secrets/view.rs b/app/src/search/external_secrets/view.rs index 1611b22f..93242010 100644 --- a/app/src/search/external_secrets/view.rs +++ b/app/src/search/external_secrets/view.rs @@ -1,8 +1,6 @@ use std::collections::HashSet; use std::ops::Range; -use itertools::Itertools; -use lazy_static::lazy_static; use galaxyui::elements::{ Align, ConstrainedBox, Container, CornerRadius, Dismiss, Empty, Fill, Flex, ParentElement, Radius, SavePosition, ScrollStateHandle, Scrollable, ScrollableElement, Shrinkable, @@ -14,6 +12,8 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use itertools::Itertools; +use lazy_static::lazy_static; use crate::appearance::Appearance; use crate::external_secrets::ExternalSecret; @@ -366,6 +366,7 @@ pub mod styles { use galaxyui::elements::{Border, DropShadow, ScrollbarWidth}; use pathfinder_color::ColorU; + use crate::appearance::Appearance; use crate::themes::theme::Fill; pub const CORNER_RADIUS: f32 = 6.; diff --git a/app/src/search/files/model_tests.rs b/app/src/search/files/model_tests.rs index 231a7c4a..c0a34e6d 100644 --- a/app/src/search/files/model_tests.rs +++ b/app/src/search/files/model_tests.rs @@ -1,9 +1,7 @@ -use fuzzy_match::FuzzyMatchResult; use galaxyui::{App, SingletonEntity}; use repo_metadata::repositories::DetectedRepositories; use repo_metadata::RepoMetadataModel; -use super::super::search_item::{FileSearchItem, FileSearchResult}; use super::FileSearchModel; #[cfg(test)] @@ -177,6 +175,9 @@ mod file_search_model_tests { #[cfg(test)] mod file_search_item_tests { + use fuzzy_match::FuzzyMatchResult; + + use crate::search::files::search_item::{FileSearchItem, FileSearchResult}; #[test] fn test_file_search_item_from_result() { @@ -254,6 +255,7 @@ mod file_search_item_tests { mod strip_absolute_path_prefix_tests { use std::path::{Path, PathBuf}; + use super::FileSearchModel; /// Builds an absolute path from the given components, using the platform's /// root (`/` on Unix, `C:\` on Windows). This ensures the constructed @@ -388,6 +390,8 @@ mod strip_absolute_path_prefix_tests { #[cfg(test)] mod integration_tests { + use super::FileSearchModel; + use crate::search::files::search_item::{FileSearchItem, FileSearchResult}; #[test] fn test_typical_search_workflow() { @@ -420,7 +424,7 @@ mod integration_tests { assert!(!results.is_empty()); // Sort by score (highest first) - results.sort_by(|a, b| b.match_result.score.cmp(&a.match_result.score)); + results.sort_by_key(|b| std::cmp::Reverse(b.match_result.score)); // "src/main.rs" should be the top result (exact filename match) assert_eq!(results[0].path, "src/main.rs"); diff --git a/app/src/search/notebook_embedding/notebooks/notebook_search_item.rs b/app/src/search/notebook_embedding/notebooks/notebook_search_item.rs index 91f7d331..1ccdfc6a 100644 --- a/app/src/search/notebook_embedding/notebooks/notebook_search_item.rs +++ b/app/src/search/notebook_embedding/notebooks/notebook_search_item.rs @@ -1,4 +1,3 @@ -use ordered_float::OrderedFloat; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, MainAxisAlignment, MainAxisSize, ParentElement, Text, @@ -6,6 +5,7 @@ use galaxyui::elements::{ use galaxyui::fonts::{Properties, Weight}; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::cloud_object::CloudObject; diff --git a/app/src/search/notebook_embedding/view.rs b/app/src/search/notebook_embedding/view.rs index e43fabea..18b6e84b 100644 --- a/app/src/search/notebook_embedding/view.rs +++ b/app/src/search/notebook_embedding/view.rs @@ -1,8 +1,6 @@ use std::collections::HashSet; use std::ops::Range; -use itertools::Itertools; -use lazy_static::lazy_static; use galaxyui::elements::{ Align, ConstrainedBox, Container, CornerRadius, Dismiss, Empty, Fill, Flex, ParentElement, Radius, SavePosition, ScrollStateHandle, Scrollable, ScrollableElement, Shrinkable, @@ -14,6 +12,8 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use itertools::Itertools; +use lazy_static::lazy_static; use super::searcher::{EmbeddingSearchItemAction, EmbeddingSearchMixer}; use crate::appearance::Appearance; @@ -376,6 +376,7 @@ pub mod styles { use galaxyui::elements::{Border, DropShadow, ScrollbarWidth}; use pathfinder_color::ColorU; + use crate::appearance::Appearance; use crate::themes::theme::Fill; pub const CORNER_RADIUS: f32 = 6.; diff --git a/app/src/search/notebook_embedding/workflows/workflow_search_item.rs b/app/src/search/notebook_embedding/workflows/workflow_search_item.rs index 14892f13..61c71c0b 100644 --- a/app/src/search/notebook_embedding/workflows/workflow_search_item.rs +++ b/app/src/search/notebook_embedding/workflows/workflow_search_item.rs @@ -1,4 +1,3 @@ -use ordered_float::OrderedFloat; use galaxyui::elements::{ Clipped, ConstrainedBox, Container, CrossAxisAlignment, Flex, Highlight, MainAxisAlignment, MainAxisSize, ParentElement, Shrinkable, Text, @@ -6,6 +5,7 @@ use galaxyui::elements::{ use galaxyui::fonts::{Properties, Weight}; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use ordered_float::OrderedFloat; use crate::appearance::Appearance; use crate::cloud_object::CloudObject; diff --git a/app/src/search/search_bar.rs b/app/src/search/search_bar.rs index b8980060..7066f514 100644 --- a/app/src/search/search_bar.rs +++ b/app/src/search/search_bar.rs @@ -1,8 +1,7 @@ use std::collections::HashSet; -use itertools::{Either, Itertools}; use galaxy_editor::editor::NavigationKey; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ Clipped, ConstrainedBox, Container, CrossAxisAlignment, Flex, ParentElement, Shrinkable, Text, }; @@ -12,6 +11,7 @@ use galaxyui::{ Action, AppContext, Element, Entity, FocusContext, ModelContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::{Either, Itertools}; use super::mixer::SearchMixerEvent; use crate::appearance::Appearance; diff --git a/app/src/search/search_results_menu/view.rs b/app/src/search/search_results_menu/view.rs index edadcb0a..2d517811 100644 --- a/app/src/search/search_results_menu/view.rs +++ b/app/src/search/search_results_menu/view.rs @@ -1,7 +1,6 @@ use std::marker::PhantomData; use std::ops::Range; -use itertools::Itertools; use galaxyui::elements::{ ConstrainedBox, Container, Empty, Flex, ParentElement, SavePosition, ScrollStateHandle, Scrollable, ScrollableElement, ScrollbarWidth, Text, UniformList, UniformListState, @@ -11,6 +10,7 @@ use galaxyui::{ Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, View, ViewContext, ViewHandle, WeakViewHandle, }; +use itertools::Itertools; use super::styles::{ESTIMATED_RESULT_HEIGHT, MAX_DISPLAYED_RESULT_COUNT}; use crate::appearance::Appearance; diff --git a/app/src/server/cloud_objects/test_utils.rs b/app/src/server/cloud_objects/test_utils.rs index 0b27041e..deae29aa 100644 --- a/app/src/server/cloud_objects/test_utils.rs +++ b/app/src/server/cloud_objects/test_utils.rs @@ -3,6 +3,8 @@ use std::sync::mpsc::{sync_channel, Receiver}; use std::sync::Arc; use cloud_object_client::{MockObjectClient, ObjectClient}; +use galaxy_core::execution_mode::{AppExecutionMode, ExecutionMode}; +use galaxyui::{App, ModelHandle, SingletonEntity}; use settings::manager::SettingsManager; use super::update_manager::UpdateManager; diff --git a/app/src/server/cloud_objects/update_manager.rs b/app/src/server/cloud_objects/update_manager.rs index b6df4360..f9bcfd67 100644 --- a/app/src/server/cloud_objects/update_manager.rs +++ b/app/src/server/cloud_objects/update_manager.rs @@ -11,21 +11,19 @@ pub use cloud_object_client::InitialLoadResponse; use futures::channel::oneshot::{self, Receiver}; use futures::stream::AbortHandle; use galaxy_core::features::FeatureFlag; +use galaxy_core::report_error; use galaxy_graphql::mcp_gallery_template::MCPGalleryTemplate; use galaxy_graphql::object_permissions::AccessLevel; use galaxy_graphql::scalars::time::ServerTimestamp; -use galaxyui::r#async::{FutureId, Timer}; -use galaxyui::{duration_with_jitter, AppContext}; -use galaxyui::{Entity, ModelContext, RequestState, RetryOption, SingletonEntity}; -use itertools::Itertools; -use lazy_static::lazy_static; -use regex::Regex; -use galaxy_core::report_error; use galaxy_util::sync::Condition; +use galaxyui::r#async::{FutureId, Timer}; use galaxyui::{ duration_with_jitter, AppContext, Entity, ModelContext, ModelHandle, RequestState, RetryOption, SingletonEntity, }; +use itertools::Itertools; +use lazy_static::lazy_static; +use regex::Regex; use super::listener::ObjectUpdateMessage; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/server/cloud_objects/update_manager_tests.rs b/app/src/server/cloud_objects/update_manager_tests.rs index b272bcdd..60cb6516 100644 --- a/app/src/server/cloud_objects/update_manager_tests.rs +++ b/app/src/server/cloud_objects/update_manager_tests.rs @@ -6,11 +6,11 @@ use chrono::{DateTime, Utc}; use cloud_object_client::MockObjectClient; use cloud_object_models::JsonSerializer; use futures_lite::future; -use settings::{RespectUserSyncSetting, SyncToCloud}; use galaxy_core::features::FeatureFlag; use galaxy_graphql::object_permissions::AccessLevel; use galaxy_graphql::scalars::time::ServerTimestamp; use galaxyui::{App, ModelHandle, SingletonEntity}; +use settings::SyncToCloud; use super::{GetCloudObjectResponse, InitialLoadResponse, UpdateManager}; use crate::ai::cloud_environments::{ diff --git a/app/src/server/graphql/mod.rs b/app/src/server/graphql/mod.rs index fd7199d9..aec80534 100644 --- a/app/src/server/graphql/mod.rs +++ b/app/src/server/graphql/mod.rs @@ -1,3 +1,5 @@ pub mod schema; -pub use galaxy_graphql::client::{get_request_context, get_user_facing_error_message, GraphQLError}; +pub use galaxy_graphql::client::{ + get_request_context, get_user_facing_error_message, GraphQLError, +}; diff --git a/app/src/server/graphql/schema/mod.rs b/app/src/server/graphql/schema/mod.rs index 3413c63e..6b7f0baa 100644 --- a/app/src/server/graphql/schema/mod.rs +++ b/app/src/server/graphql/schema/mod.rs @@ -1,10 +1,10 @@ pub mod util; use anyhow::{bail, Result}; -pub use util::{action_type_to_gql_action_type, object_action_history_from_gql}; use galaxy_graphql::generic_string_object::GenericStringObjectFormat; use galaxy_graphql::mutations::update_generic_string_object::{ GenericStringObjectUpdate, UpdateGenericStringObjectResult, }; +pub use util::{action_type_to_gql_action_type, object_action_history_from_gql}; use warp_graphql::object::ObjectUpdateSuccess; use crate::cloud_object::{ diff --git a/app/src/server/server_api.rs b/app/src/server/server_api.rs index 3bc6eb82..268aa32e 100644 --- a/app/src/server/server_api.rs +++ b/app/src/server/server_api.rs @@ -25,15 +25,6 @@ use auth::AuthClient; use block::BlockClient; use channel_versions::ChannelVersions; use chrono::{DateTime, FixedOffset}; -use instant::Instant; -use managed_mcp::ManagedMcpClient; -use object::ObjectClient; -use parking_lot::Mutex; -use referral::ReferralsClient; -use reqwest::StatusCode; -use serde::{Deserialize, Serialize}; -use team::TeamClient; -use url::Url; use galaxy_core::context_flag::ContextFlag; use galaxy_core::errors::{register_error, AnyhowErrorExt, ErrorExt}; use galaxy_core::telemetry::TelemetryEvent; @@ -46,6 +37,15 @@ use galaxy_server_client::iap::{IapManager, IapState}; use galaxy_server_client::network_logging::NetworkLogModel; use galaxyui::r#async::BoxFuture; use galaxyui::{Entity, ModelContext, SingletonEntity}; +use instant::Instant; +use managed_mcp::ManagedMcpClient; +use object::ObjectClient; +use parking_lot::Mutex; +use referral::ReferralsClient; +use reqwest::StatusCode; +use serde::{Deserialize, Serialize}; +use team::TeamClient; +use url::Url; use workspace::WorkspaceClient; use super::experiments::{ServerExperiment, ServerExperiments}; diff --git a/app/src/server/server_api/ai.rs b/app/src/server/server_api/ai.rs index 4d097427..ca8ebfc9 100644 --- a/app/src/server/server_api/ai.rs +++ b/app/src/server/server_api/ai.rs @@ -13,11 +13,6 @@ use base64::Engine; use chrono::{DateTime, Utc}; use cynic::{MutationBuilder, QueryBuilder}; use galaxy_core::channel::ChannelState; -use galaxy_core::{features::FeatureFlag, report_error}; -use itertools::Itertools; -#[cfg(test)] -use mockall::automock; -use prost::Message; use galaxy_core::features::FeatureFlag; use galaxy_core::report_error; use galaxy_graphql::ai::{AgentTaskState, PlatformErrorCode}; @@ -110,6 +105,10 @@ use galaxy_graphql::queries::task_git_credentials::{ TaskGitCredentials, TaskGitCredentialsInput, TaskGitCredentialsResult, TaskGitCredentialsVariables, }; +use itertools::Itertools; +#[cfg(test)] +use mockall::automock; +use prost::Message; use warp_multi_agent_api::ConversationData; #[cfg(not(target_family = "wasm"))] @@ -1121,6 +1120,8 @@ pub struct UpdateMemoryResponse { #[cfg_attr(not(target_family = "wasm"), async_trait)] #[cfg_attr(target_family = "wasm", async_trait(?Send))] pub trait AIClient: 'static + Send + Sync { + fn base_client(&self) -> std::sync::Arc; + async fn generate_commands_from_natural_language( &self, prompt: String, @@ -1602,6 +1603,10 @@ fn convert_upload_field( #[cfg_attr(not(target_family = "wasm"), async_trait)] #[cfg_attr(target_family = "wasm", async_trait(?Send))] impl AIClient for ServerApi { + fn base_client(&self) -> std::sync::Arc { + self.base_client.clone() + } + async fn generate_commands_from_natural_language( &self, prompt: String, @@ -3306,6 +3311,10 @@ fn convert_usage_metadata( credits_spent_for_last_block: None, token_usage: vec![], tool_usage_metadata: Default::default(), + total_cache_read_tokens: 0, + total_cache_write_tokens: 0, + total_cache_miss_tokens: 0, + total_cost_cents: 0.0, context_window_segments: context_window_segments.iter().map(Into::into).collect(), } } diff --git a/app/src/server/server_api/auth.rs b/app/src/server/server_api/auth.rs index 9f2cb988..039cb2b2 100644 --- a/app/src/server/server_api/auth.rs +++ b/app/src/server/server_api/auth.rs @@ -1,9 +1,9 @@ -use thiserror::Error; #[cfg(test)] pub use galaxy_server_client::auth::MockAuthClient; pub use galaxy_server_client::auth::{ AuthClient, FetchUserResult, MintCustomTokenError, SyncedUserSettings, UserAuthenticationError, }; +use thiserror::Error; #[derive(Error, Debug)] /// Error type when creating anonymous users. diff --git a/app/src/server/server_api/block.rs b/app/src/server/server_api/block.rs index f71d593e..7ffbf544 100644 --- a/app/src/server/server_api/block.rs +++ b/app/src/server/server_api/block.rs @@ -4,8 +4,6 @@ use anyhow::anyhow; use async_trait::async_trait; use chrono::Utc; use cynic::{MutationBuilder, QueryBuilder}; -#[cfg(test)] -use mockall::automock; use galaxy_core::channel::{Channel, ChannelState}; use galaxy_graphql::mutations::share_block::{ BlockInput, ShareBlock, ShareBlockResult, ShareBlockVariables, @@ -16,6 +14,8 @@ use galaxy_graphql::mutations::unshare_block::{ use galaxy_graphql::queries::get_blocks_for_user::{ Block as GqlBlock, GetBlocksForUser, GetBlocksForUserVariables, }; +#[cfg(test)] +use mockall::automock; use super::ServerApi; use crate::ai::generate_block_title::api::{GenerateBlockTitleRequest, GenerateBlockTitleResponse}; diff --git a/app/src/server/server_api/harness_support_tests.rs b/app/src/server/server_api/harness_support_tests.rs index 5cb5646b..69086aae 100644 --- a/app/src/server/server_api/harness_support_tests.rs +++ b/app/src/server/server_api/harness_support_tests.rs @@ -50,7 +50,7 @@ fn report_shutdown_clean_serializes_without_error() { #[test] fn report_shutdown_abnormal_serializes_with_error() { - + use super::ReportShutdownRequest; let request = ReportShutdownRequest::abnormal("oom".to_string(), "out of memory".to_string()); let json = serde_json::to_value(&request).unwrap(); assert_eq!( diff --git a/app/src/server/server_api/integrations.rs b/app/src/server/server_api/integrations.rs index 054cbe0f..de467c17 100644 --- a/app/src/server/server_api/integrations.rs +++ b/app/src/server/server_api/integrations.rs @@ -1,8 +1,6 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use cynic::{MutationBuilder, QueryBuilder}; -#[cfg(test)] -use mockall::automock; use galaxy_graphql::mutations::create_simple_integration::{ CreateSimpleIntegration, CreateSimpleIntegrationOutput, CreateSimpleIntegrationResult, CreateSimpleIntegrationVariables, SimpleIntegrationConfig, @@ -32,6 +30,8 @@ use galaxy_graphql::queries::user_repo_auth_status::{ RepoInput as UserRepoAuthStatusRepoInput, UserRepoAuthStatus, UserRepoAuthStatusInput, UserRepoAuthStatusOutput, UserRepoAuthStatusResult, UserRepoAuthStatusVariables, }; +#[cfg(test)] +use mockall::automock; use super::ServerApi; use crate::channel::ChannelState; diff --git a/app/src/server/server_api/referral.rs b/app/src/server/server_api/referral.rs index ca69739f..3ab9dbb5 100644 --- a/app/src/server/server_api/referral.rs +++ b/app/src/server/server_api/referral.rs @@ -1,13 +1,13 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use cynic::{MutationBuilder, QueryBuilder}; -#[cfg(test)] -use mockall::{automock, predicate::*}; use galaxy_core::channel::ChannelState; use galaxy_graphql::mutations::send_referral_invite_emails::{ SendReferralInviteEmails, SendReferralInviteEmailsResult, SendReferralInviteEmailsVariables, }; use galaxy_graphql::queries::get_referral_info::{GetReferralInfo, GetReferralInfoVariables}; +#[cfg(test)] +use mockall::{automock, predicate::*}; use super::ServerApi; use crate::server::graphql::{get_request_context, get_user_facing_error_message}; diff --git a/app/src/server/server_api/team.rs b/app/src/server/server_api/team.rs index 7209836e..601e3312 100644 --- a/app/src/server/server_api/team.rs +++ b/app/src/server/server_api/team.rs @@ -1,8 +1,6 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use cynic::{MutationBuilder, QueryBuilder}; -#[cfg(test)] -use mockall::{automock, predicate::*}; use galaxy_graphql::mutations::add_invite_link_domain_restriction::{ AddInviteLinkDomainRestriction, AddInviteLinkDomainRestrictionInput, AddInviteLinkDomainRestrictionResult, AddInviteLinkDomainRestrictionVariables, @@ -56,6 +54,8 @@ use galaxy_graphql::queries::get_discoverable_teams::{ use galaxy_graphql::queries::get_workspaces_metadata_for_user::{ GetWorkspacesMetadataForUser, GetWorkspacesMetadataForUserVariables, PricingInfoResult, }; +#[cfg(test)] +use mockall::{automock, predicate::*}; use super::ServerApi; use crate::auth::UserUid; diff --git a/app/src/server/server_api/workspace.rs b/app/src/server/server_api/workspace.rs index 630c17b8..dab8e217 100644 --- a/app/src/server/server_api/workspace.rs +++ b/app/src/server/server_api/workspace.rs @@ -1,8 +1,6 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use cynic::{MutationBuilder, QueryBuilder}; -#[cfg(test)] -use mockall::{automock, predicate::*}; use galaxy_graphql::error::UserFacingErrorInterface; use galaxy_graphql::mutations::purchase_addon_credits::{ PurchaseAddonCredits, PurchaseAddonCreditsInput, PurchaseAddonCreditsResult, @@ -20,6 +18,8 @@ use galaxy_graphql::mutations::update_workspace_settings::{ use galaxy_graphql::queries::get_ai_overages_for_workspace::{ GetAiOveragesForWorkspace, GetAiOveragesForWorkspaceVariables, UserResult, }; +#[cfg(test)] +use mockall::{automock, predicate::*}; use super::team::TeamClient; use super::ServerApi; diff --git a/app/src/server/sync_queue.rs b/app/src/server/sync_queue.rs index 01675aa7..a586e76e 100644 --- a/app/src/server/sync_queue.rs +++ b/app/src/server/sync_queue.rs @@ -8,15 +8,11 @@ use chrono::{DateTime, Utc}; pub use cloud_objects::cloud_object::SerializedModel; use derivative::Derivative; use galaxy_graphql::scalars::time::ServerTimestamp; -use galaxyui::{ - r#async::FutureId, Entity, ModelContext, RequestState, RetryOption, SingletonEntity, -}; +use galaxyui::r#async::FutureId; +use galaxyui::{Entity, ModelContext, RequestState, RetryOption, SingletonEntity}; use http::StatusCode; use lazy_static::lazy_static; use uuid::Uuid; -use warp_graphql::scalars::time::ServerTimestamp; -use warpui::r#async::FutureId; -use warpui::{Entity, ModelContext, RequestState, RetryOption, SingletonEntity}; use super::graphql::GraphQLError; use super::ids::{ClientId, HashableId, ObjectUid, ServerId, SyncId, ToServerId}; @@ -1812,19 +1808,17 @@ impl SyncQueue { ); } } - QueueItem::UpdateWorkflow { model, .. } => { - // Only update the workflow if it depends on this dependency. + QueueItem::UpdateWorkflow { model, .. } if self .queue_dependencies .get(item_id) - .is_some_and(|deps| deps.contains(dependency)) - { - let workflow_model = Arc::make_mut(model); - workflow_model.data.replace_object_id( - SyncId::ClientId(client_id), - SyncId::from(server_id), - ); - } + .is_some_and(|deps| deps.contains(dependency)) => + { + let workflow_model = Arc::make_mut(model); + workflow_model.data.replace_object_id( + SyncId::ClientId(client_id), + SyncId::from(server_id), + ); } _ => {} } diff --git a/app/src/server/telemetry/collector.rs b/app/src/server/telemetry/collector.rs index 30e83956..4626a749 100644 --- a/app/src/server/telemetry/collector.rs +++ b/app/src/server/telemetry/collector.rs @@ -1,90 +1,18 @@ -use std::fs::remove_file; use std::sync::Arc; -use std::time::Duration; use galaxyui::{Entity, ModelContext, SingletonEntity}; -use super::{clear_event_queue, rudder_event_file_path, RUDDER_TELEMETRY_EVENTS_FILE_NAME}; -use crate::auth::AuthStateProvider; -use crate::channel::ChannelState; -use crate::features::FeatureFlag; use crate::server::server_api::ServerApi; -use crate::settings::{PrivacySettings, PrivacySettingsChangedEvent}; -// How often we send Active Usage signals. -const ACTIVE_USAGE_DURATION: Duration = Duration::from_secs(60); - -/// Duration to wait before flushing the event queue to Rudderstack. -const TELEMETRY_FLUSH_DURATION: Duration = Duration::from_secs(30); - -/// Max telemetry events to write to disk. This is bounded to limit the size of the file as well -/// as latency of writing the file. -const MAX_TELEMETRY_EVENTS_TO_STORE: usize = 20; - -/// Maximum time to wait for the telemetry flush network request during shutdown. -/// If the network is unavailable or slow, we don't want the CLI process to hang indefinitely. -const TELEMETRY_SHUTDOWN_FLUSH_TIMEOUT: Duration = Duration::from_secs(5); - -/// App singleton responsible for scheduling periodic background tasks for sending batches of -/// telemetry events to Rudderstack. This model respects the user's telemetry enablement setting. +/// No-op telemetry collector. Telemetry has been removed from Galaxy. pub struct TelemetryCollector { _server_api: Arc, } impl TelemetryCollector { pub fn new(server_api: Arc) -> Self { - Self { server_api } - } - - pub fn initialize_telemetry_collection(&self, ctx: &mut ModelContext) { - // Start a background thread to periodically flush events from the telemetry event queue. - if ChannelState::is_release_bundle() || FeatureFlag::WithSandboxTelemetry.is_enabled() { - // Flush the events to Rudderstack that were persisted into a file the last time the app was - // quit. - self.flush_persisted_events_from_disk(ctx); - } - - // Send Active App Usage signals - if FeatureFlag::RecordAppActiveEvents.is_enabled() - && (ChannelState::is_release_bundle() || FeatureFlag::WithSandboxTelemetry.is_enabled()) - { - self.schedule_send_active_usage_event(ctx); - } - - // Start a background thread to periodically flush events from the telemetry event queue. - if ChannelState::is_release_bundle() - || FeatureFlag::WithSandboxTelemetry.is_enabled() - || FeatureFlag::SendTelemetryToFile.is_enabled() - { - self.schedule_event_queue_flush(ctx); - } - - // Clear queued telemetry events when telemetry is enabled or disabled. If telemetry is - // enabled, we will start sending Rudderstack requests when the event queue is periodically - // flushed. The initial request should not contain any events recorded when the user was - // previously opted-out of telemetry. In the case where the user turns the telemetry from - // on to off, we should not send another request with any telemetry, even if the event was - // initially recorded prior to the user turning telemetry off.` - ctx.subscribe_to_model(&PrivacySettings::handle(ctx), |_me, _, event, _ctx| { - if let PrivacySettingsChangedEvent::UpdateIsTelemetryEnabled { .. } = event { - clear_event_queue(); - } - }); - } - - /// Writes all queued but unsent telemetry telemetry events to disk so that they may be sent - /// on the next app startup. - pub fn write_telemetry_events_to_disk(&self, ctx: &mut ModelContext) { - match self.server_api.persist_telemetry_events( - MAX_TELEMETRY_EVENTS_TO_STORE, - PrivacySettings::as_ref(ctx).get_snapshot(ctx), - ) { - Ok(()) => { - log::info!("Successfully wrote telemetry events to disk") - } - Err(e) => { - log::error!("Failed to write telemetry events to disk {e:#}"); - } + Self { + _server_api: server_api, } } diff --git a/app/src/server/telemetry/context.rs b/app/src/server/telemetry/context.rs index 64ae0faa..cf16d0aa 100644 --- a/app/src/server/telemetry/context.rs +++ b/app/src/server/telemetry/context.rs @@ -1,15 +1,17 @@ +#![allow(dead_code)] + //! Module that builds a static context to attach to each of our events that are sent to Rudderstack. //! This is needed so we know the backing operating system and version of each telemetry event. use std::sync::OnceLock; -use serde::Serialize; -use serde_json::{json, Value}; +use galaxy_core::operating_system_info::OperatingSystemInfo; #[cfg(target_family = "wasm")] use galaxyui::platform::wasm; +use serde::Serialize; +use serde_json::{json, Value}; use super::rudder_message::Message as RudderMessage; -use crate::server::OperatingSystemInfo; static TELEMETRY_CONTEXT: OnceLock = OnceLock::new(); diff --git a/app/src/server/telemetry/events.rs b/app/src/server/telemetry/events.rs index d2fe0fef..590750dd 100644 --- a/app/src/server/telemetry/events.rs +++ b/app/src/server/telemetry/events.rs @@ -2,9 +2,10 @@ use std::time::Duration; use galaxy_completer::completer::MatchType; use galaxy_core::command::ExitCode; -use galaxy_core::telemetry::EnablementState; -use galaxy_core::telemetry::TelemetryEvent as TelemetryEventTrait; -use galaxy_core::telemetry::TelemetryEventDesc; +use galaxy_core::interval_timer::TimingDataPoint; +use galaxy_core::telemetry::{ + EnablementState, TelemetryEvent as TelemetryEventTrait, TelemetryEventDesc, +}; use galaxyui::keymap::Keystroke; use galaxyui::notification::{NotificationSendError, RequestPermissionsOutcome}; use galaxyui::rendering::ThinStrokes; @@ -13,10 +14,6 @@ use serde_json::{json, Value}; use session_sharing_protocol::common::{ParticipantId, Role, SessionId as SharedSessionId}; use session_sharing_protocol::sharer::{SessionEndedReason, SessionSourceType}; use strum_macros::{EnumDiscriminants, EnumIter}; -use galaxy_core::interval_timer::TimingDataPoint; -use galaxy_core::telemetry::{ - EnablementState, TelemetryEvent as TelemetryEventTrait, TelemetryEventDesc, -}; use crate::ai::agent::api::ServerConversationToken; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/server/telemetry/mod.rs b/app/src/server/telemetry/mod.rs index 153750d3..00378a98 100644 --- a/app/src/server/telemetry/mod.rs +++ b/app/src/server/telemetry/mod.rs @@ -6,47 +6,11 @@ mod macros; pub mod rudder_message; pub mod secret_redaction; -use std::fs::File; -#[cfg(not(target_family = "wasm"))] -use std::fs::OpenOptions; -use std::future::Future; -use std::path::{Path, PathBuf}; - -use anyhow::Result; -use chrono::Utc; pub use collector::*; pub use context::telemetry_context; pub use events::*; -use futures::FutureExt; -use rudder_message::{ - Batch as RudderBatch, BatchMessage as RudderBatchMessageWithMetadata, - BatchMessageItem as RudderBatchMessage, Message as RudderMessage, -}; -use galaxy_core::channel::RudderStackDestination; -use warpui::telemetry::Event; - -use crate::auth::UserUid; -use crate::features::FeatureFlag; -use crate::server::telemetry::context::AttachContext; -use crate::server::telemetry_ext::TelemetryExt; -use crate::settings::PrivacySettingsSnapshot; -use crate::ChannelState; - -/// Filename for file where telemetry events are written on app quit. -const RUDDER_TELEMETRY_EVENTS_FILE_NAME: &str = "rudder_telemetry_events.json"; - -/// Filepath where the Rudder events should be written on app quit. -fn rudder_event_file_path() -> PathBuf { - galaxy_core::paths::secure_state_dir() - .unwrap_or_else(galaxy_core::paths::state_dir) - .join(RUDDER_TELEMETRY_EVENTS_FILE_NAME) -} - -/// Removes all telemetry events from the app telemetry event queue. -pub fn clear_event_queue() { - let _ = galaxyui::telemetry::flush_events(); -} +/// No-op stub. Telemetry has been removed from Galaxy. pub struct TelemetryApi { pub client: http_client::Client, } @@ -66,166 +30,11 @@ impl TelemetryApi { pub async fn send_telemetry_event( &self, - user_id: Option, - anonymous_id: String, - event: impl galaxy_core::telemetry::TelemetryEvent, - settings_snapshot: PrivacySettingsSnapshot, - ) -> Result<()> { - let event = galaxyui::telemetry::create_event( - user_id.map(|uid| uid.as_string()), - anonymous_id, - event.name().into(), - event.payload(), - event.contains_ugc(), - galaxyui::time::get_current_time(), - ); - - self.send_telemetry_event_internal(event, settings_snapshot) - .await - } - - /// Internal implementation for sending telemetry events. This reduces code size, since - // we: - // 1. Return a boxed future, so calling `async` functions don't need to inline this one. - // 2. Don't have to monomorphize for each telemetry event implementation. - fn send_telemetry_event_internal( - &self, - event: Event, - settings_snapshot: PrivacySettingsSnapshot, - ) -> impl Future> + '_ { - let work = async move { - if settings_snapshot.should_disable_telemetry() { - log::info!("Not sending telemetry event because telemetry is disabled."); - return Result::Ok(()); - } - - #[cfg(not(target_family = "wasm"))] - if FeatureFlag::SendTelemetryToFile.is_enabled() { - self.persist_events_to_telemetry_log_file(vec![event.clone()])?; - } - - if !(ChannelState::is_release_bundle() - || FeatureFlag::WithSandboxTelemetry.is_enabled()) - { - return Result::Ok(()); - } - - let rudder_batch = vec![event.to_rudder_batch_message()]; - - let result = self - .send_batch_messages_to_rudder(rudder_batch, settings_snapshot) - .await; - - // This is only conditionally compiled because `is_connect` is not - // available on wasm. If additional checks are made against the - // `reqwest::Error`, this condition should be performed specifically - // against `is_connect` and not the whole loop. - #[cfg(not(target_family = "wasm"))] - if let Err(error) = &result { - for cause in error.chain() { - if let Some(err) = cause.downcast_ref::() { - if err.is_connect() { - log::warn!("Failed to send telemetry event: {error}"); - return Ok(()); - } - } - } - } - - result - }; - - // On WASM, the work future is non-Send, because the HTTP request future contains a reference to a JS - // value (which is fine, since our WASM executor is single-threaded). On all other platforms, we must - // return a Send future in order to use the background executor. - cfg_if::cfg_if! { - if #[cfg(target_family = "wasm")] { - work.boxed_local() - } else { - work.boxed() - } - } - } - - /// Send a batch of RudderStack messages to their HTTP API. - /// Note that the rudderanalytics SDK provides a client, but we don't - /// use it for a few reasons: - /// 1. It only supports a blocking HTTP client instead of an async one - /// 2. We want to use our own HTTP client which has before/after request logging hooks - #[cfg_attr(target_family = "wasm", allow(clippy::question_mark))] - async fn send_batch_messages_to_rudder( - &self, - messages: Vec, - settings_snapshot: PrivacySettingsSnapshot, - ) -> Result<()> { - if messages.is_empty() { - log::debug!("Dropping empty RudderStack telemetry batch"); - return Ok(()); - } - - if settings_snapshot.should_disable_telemetry() { - log::info!("Not sending batched messages because telemetry is disabled."); - return Ok(()); - } - - log::info!("Start to send telemetry events to RudderStack"); - - let (mut messages_with_ugc, messages_without_ugc): (Vec<_>, Vec<_>) = messages - .into_iter() - .partition(|message| message.contains_ugc); - - // If we shouldn't collect UGC telemetry, forcibly clear any messages with UGC before trying to send. - if !settings_snapshot.should_collect_ai_ugc_telemetry() { - messages_with_ugc.clear(); - } - - for (messages, rudder_stack_destination) in [ - ( - messages_with_ugc, - ChannelState::rudderstack_ugc_destination(), - ), - ( - messages_without_ugc, - ChannelState::rudderstack_non_ugc_destination(), - ), - ] { - if messages.is_empty() { - continue; - } - - // Note that timestamp and context are already included in the individual RudderBatchMessages - // and these are the most important ones, - // but we also add them to the RudderMessage::Batch wrapper. - let rudder_message = RudderMessage::Batch(RudderBatch { - batch: messages - .into_iter() - .map(|message| message.message) - .collect(), - original_timestamp: Some(Utc::now()), - ..Default::default() - }); - if let Err(e) = self - .send_rudder_request(rudder_message, rudder_stack_destination) - .await - { - // Don't treat a connection issue as an error as these are outside of our control. - // - // This is only conditionally compiled because `is_connect` is not - // available on wasm. If additional checks are made against the - // `reqwest::Error`, this condition should be performed specifically - // against `is_connect` and not the whole loop. - #[cfg(not(target_family = "wasm"))] - for cause in e.chain() { - if let Some(err) = cause.downcast_ref::() { - if err.is_connect() { - log::warn!("Failed to send event to RudderStack: {e}"); - return Ok(()); - } - } - } - return Err(e); - } - } + _user_id: Option, + _anonymous_id: String, + _event: impl galaxy_core::telemetry::TelemetryEvent, + _settings_snapshot: crate::settings::PrivacySettingsSnapshot, + ) -> anyhow::Result<()> { Ok(()) } @@ -252,3 +61,8 @@ impl TelemetryApi { Ok(()) } } + +#[allow(dead_code)] +pub fn clear_event_queue() { + let _ = galaxyui::telemetry::flush_events(); +} diff --git a/app/src/server/telemetry/rudder_message.rs b/app/src/server/telemetry/rudder_message.rs index 8b137891..1ee16111 100644 --- a/app/src/server/telemetry/rudder_message.rs +++ b/app/src/server/telemetry/rudder_message.rs @@ -1 +1,251 @@ +#![allow(dead_code)] +//! Module that contains RudderStack API message types. +//! This is directly copied from the RudderStack Rust SDK: https://github.com/rudderlabs/rudder-sdk-rust/blob/master/src/message.rs +//! We do not use the SDK directly because it unconditionally uses a blocking HTTP client, which we don't want for a few reasons: +//! 1. The blocking HTTP client is not allowed when compiling for WASM, so the crate itself cannot be compiled for WASM +//! 2. An async HTTP client is more efficient +//! 3. We want to use our own HTTP client which has before/after request logging hooks +//! We can consider using the SDK if it adds support for an async HTTP client, tracked by this issue: https://github.com/rudderlabs/rudder-sdk-rust/issues/23 +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +use crate::auth::UserUid; + +/// An enum containing all values which may be sent to RudderStack's API. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum Message { + Identify(Identify), + Track(Track), + Page(Page), + Screen(Screen), + Group(Group), + Alias(Alias), + Batch(Batch), +} + +/// An identify event. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Identify { + /// The user id associated with this message. + #[serde(rename = "userId", skip_serializing_if = "Option::is_none")] + pub user_id: Option, + + /// The anonymous user id associated with this message. + #[serde(rename = "anonymousId", skip_serializing_if = "Option::is_none")] + pub anonymous_id: Option, + + /// The traits to assign to the user. + #[serde(skip_serializing_if = "Option::is_none")] + pub traits: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, +} + +/// A track event. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Track { + /// The user id associated with this message. + #[serde(rename = "userId", skip_serializing_if = "Option::is_none")] + pub user_id: Option, + + /// The anonymous user id associated with this message. + #[serde(rename = "anonymousId", skip_serializing_if = "Option::is_none")] + pub anonymous_id: Option, + + /// The name of the event being tracked. + pub event: String, + + /// The properties associated with the event. + #[serde(skip_serializing_if = "Option::is_none")] + pub properties: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, +} + +/// A page event. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Page { + /// The user id associated with this message. + #[serde(rename = "userId", skip_serializing_if = "Option::is_none")] + pub user_id: Option, + + /// The anonymous user id associated with this message. + #[serde(rename = "anonymousId", skip_serializing_if = "Option::is_none")] + pub anonymous_id: Option, + + /// The name of the page being tracked. + pub name: String, + + /// The properties associated with the event. + #[serde(skip_serializing_if = "Option::is_none")] + pub properties: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, +} + +/// A screen event. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Screen { + /// The user id associated with this message. + #[serde(rename = "userId", skip_serializing_if = "Option::is_none")] + pub user_id: Option, + + /// The anonymous user id associated with this message. + #[serde(rename = "anonymousId", skip_serializing_if = "Option::is_none")] + pub anonymous_id: Option, + + /// The name of the screen being tracked. + pub name: String, + + /// The properties associated with the event. + #[serde(skip_serializing_if = "Option::is_none")] + pub properties: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, +} + +/// A group event. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Group { + /// The user id associated with this message. + #[serde(rename = "userId", skip_serializing_if = "Option::is_none")] + pub user_id: Option, + + /// The anonymous user id associated with this message. + #[serde(rename = "anonymousId", skip_serializing_if = "Option::is_none")] + pub anonymous_id: Option, + + /// The group the user is being associated with. + #[serde(rename = "groupId")] + pub group_id: String, + + /// The traits to assign to the group. + #[serde(skip_serializing_if = "Option::is_none")] + pub traits: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, +} + +/// An alias event. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Alias { + /// The user id associated with this message. + #[serde(rename = "userId")] + pub user_id: UserUid, + + /// The user's previous ID. + #[serde(rename = "previousId")] + pub previous_id: String, + + /// The traits to assign to the alias. + #[serde(skip_serializing_if = "Option::is_none")] + pub traits: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, +} + +/// A batch of events. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)] +pub struct Batch { + /// The batch of messages to send. + pub batch: Vec, + + /// Context associated with this message. + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option, + + /// Integrations to route this message to. + #[serde(skip_serializing_if = "Option::is_none")] + pub integrations: Option, + + /// The timestamp associated with this message. + #[serde(rename = "originalTimestamp", skip_serializing_if = "Option::is_none")] + pub original_timestamp: Option>, +} + +/// An enum containing all messages which may be placed inside a batch. +#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum BatchMessageItem { + #[serde(rename = "identify")] + Identify(Identify), + #[serde(rename = "track")] + Track(Track), + #[serde(rename = "page")] + Page(Page), + #[serde(rename = "screen")] + Screen(Screen), + #[serde(rename = "group")] + Group(Group), + #[serde(rename = "alias")] + Alias(Alias), +} + +/// Metadata about a batch sent to Rudderstack and whether it contains user generated content. +pub struct BatchMessage { + pub message: BatchMessageItem, + pub contains_ugc: bool, +} diff --git a/app/src/server/telemetry/secret_redaction.rs b/app/src/server/telemetry/secret_redaction.rs index 17b41154..446ddca4 100644 --- a/app/src/server/telemetry/secret_redaction.rs +++ b/app/src/server/telemetry/secret_redaction.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! Best-effort secret redaction for telemetry payloads. //! //! Unlike the AI-side secret redaction in `app/src/ai/blocklist/block/secret_redaction.rs`, @@ -33,3 +35,95 @@ lazy_static! { /// custom patterns). static ref TELEMETRY_SECRETS_REGEX: RwLock = RwLock::new(build_default_regex()); } +/// Builds a regex containing only the default patterns. Used to seed the static +/// regex before the privacy settings are loaded. +fn build_default_regex() -> Regex { + let patterns: Vec<&str> = DEFAULT_REGEXES_WITH_NAMES + .iter() + .map(|d| d.pattern) + .collect(); + Regex::new_many(&patterns).expect("default secret patterns should compile") +} +/// Rebuilds [`TELEMETRY_SECRETS_REGEX`] from the user's and enterprise's secret +/// regex lists, layered on top of the default patterns. The default patterns are +/// always included, so redaction works even when the user has not configured any +/// custom patterns. +pub fn update_telemetry_secrets_regex<'a, U, E>(user_secrets: U, enterprise_secrets: E) +where + U: IntoIterator, + E: IntoIterator, +{ + let patterns = compose_patterns( + user_secrets.into_iter().map(regex::Regex::as_str), + enterprise_secrets.into_iter().map(regex::Regex::as_str), + ); + match Regex::new_many(&patterns) { + Ok(regex) => *TELEMETRY_SECRETS_REGEX.write() = regex, + Err(err) => log::error!("Failed to build telemetry secrets regex: {err:?}"), + } +} +/// Composes the full list of patterns to compile into the telemetry regex, +/// ordered enterprise → user → defaults, with later occurrences of an already- +/// seen pattern string deduped out. +fn compose_patterns<'a>( + user: impl Iterator, + enterprise: impl Iterator, +) -> Vec<&'a str> { + let mut seen: HashSet<&str> = HashSet::new(); + let mut patterns: Vec<&str> = Vec::new(); + let all = enterprise + .chain(user) + .chain(DEFAULT_REGEXES_WITH_NAMES.iter().map(|d| d.pattern)); + for pattern in all { + if seen.insert(pattern) { + patterns.push(pattern); + } + } + patterns +} +/// Replaces every detected secret in `input` with a run of asterisks of the same +/// byte length. Overlapping matches (which can occur when multiple patterns match +/// the same region) are merged before replacement, so each character is replaced +/// at most once. +pub fn redact_secrets_in_string(input: &mut String) { + let ranges: Vec> = { + let regex = TELEMETRY_SECRETS_REGEX.read(); + regex.find_iter(input.as_str()).map(|m| m.range()).collect() + }; + replace_byte_ranges_with_asterisks(input, ranges); +} +/// Replaces each byte range in `input` with a run of asterisks of the same byte +/// length. Handles overlapping ranges by merging them first, and replaces from +/// the end of the string so earlier byte indices stay valid as we mutate. +fn replace_byte_ranges_with_asterisks(input: &mut String, mut ranges: Vec>) { + if ranges.is_empty() { + return; + } + // Sort and merge overlapping ranges so we don't double-replace. + ranges.sort_by_key(|r| r.start); + let mut merged: Vec> = Vec::with_capacity(ranges.len()); + for range in ranges { + match merged.last_mut() { + Some(last) if range.start <= last.end => last.end = last.end.max(range.end), + _ => merged.push(range), + } + } + // Replace from the end of the string so earlier byte indices stay valid. + for range in merged.into_iter().rev() { + let len = range.end - range.start; + input.replace_range(range, &REDACTION_REPLACEMENT_CHARACTER.repeat(len)); + } +} +/// Walks a [`Value`] and runs [`redact_secrets_in_string`] on every string within +/// it. Non-string scalars (numbers, booleans, nulls) are left untouched. +pub fn redact_secrets_in_value(value: &mut Value) { + match value { + Value::String(s) => redact_secrets_in_string(s), + Value::Array(arr) => arr.iter_mut().for_each(redact_secrets_in_value), + Value::Object(obj) => obj.values_mut().for_each(redact_secrets_in_value), + Value::Null | Value::Bool(_) | Value::Number(_) => {} + } +} +#[cfg(test)] +#[path = "secret_redaction_tests.rs"] +mod tests; diff --git a/app/src/server/telemetry_ext.rs b/app/src/server/telemetry_ext.rs index 4ce66ac1..106219c8 100644 --- a/app/src/server/telemetry_ext.rs +++ b/app/src/server/telemetry_ext.rs @@ -1,8 +1,10 @@ +#![allow(dead_code)] + use chrono::{DateTime, Utc}; -use serde_json::{json, Value}; use galaxy_core::channel::{Channel, ChannelState}; use galaxy_core::execution_mode; use galaxyui::telemetry::EventPayload; +use serde_json::{json, Value}; use super::telemetry::rudder_message::{ BatchMessage as RudderBatchMessage, BatchMessageItem as RudderBatchMessageItem, diff --git a/app/src/session_management.rs b/app/src/session_management.rs index d4ff747c..1fa5c008 100644 --- a/app/src/session_management.rs +++ b/app/src/session_management.rs @@ -1,7 +1,6 @@ use std::collections::HashSet; use chrono::NaiveDateTime; - use galaxyui::{AppContext, Entity, EntityId, WindowId}; use crate::context_chips::prompt_snapshot::PromptSnapshot; diff --git a/app/src/settings/accessibility.rs b/app/src/settings/accessibility.rs index 378ae063..9833b0dd 100644 --- a/app/src/settings/accessibility.rs +++ b/app/src/settings/accessibility.rs @@ -1,6 +1,6 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; use galaxyui::accessibility::AccessibilityVerbosity; +use settings::macros::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(AccessibilitySettings, settings: [ a11y_verbosity: AccessibilityVerbosityState { diff --git a/app/src/settings/ai.rs b/app/src/settings/ai.rs index 1de0de95..94afea9d 100644 --- a/app/src/settings/ai.rs +++ b/app/src/settings/ai.rs @@ -11,17 +11,18 @@ pub use cloud_object_models::{ AgentModeCommandExecutionPredicate, DEFAULT_COMMAND_EXECUTION_ALLOWLIST, DEFAULT_COMMAND_EXECUTION_DENYLIST, }; +use galaxy_core::execution_mode::AppExecutionMode; +use galaxy_core::features::FeatureFlag; use indexmap::IndexMap; use regex::Regex; use serde::de::Deserializer; use serde::{Deserialize, Serialize}; use settings::{ - define_settings_group, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, + define_settings_group, ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, + SyncToCloud, }; use strum::IntoEnumIterator; use strum_macros::EnumIter; -use galaxy_core::execution_mode::AppExecutionMode; -use galaxy_core::features::FeatureFlag; use warpui::platform::keyboard::KeyCode; use warpui::platform::OperatingSystem; use warpui::{AppContext, Entity, ModelContext, SingletonEntity, UpdateModel}; @@ -768,6 +769,122 @@ impl settings_value::SettingsValue for ToolbarCommandMap { } } +#[derive( + Default, + Debug, + Clone, + Copy, + PartialEq, + Eq, + Serialize, + Deserialize, + EnumIter, + schemars::JsonSchema, + settings_value::SettingsValue, +)] +#[schemars( + description = "Authentication method for AWS Bedrock.", + rename_all = "snake_case" +)] +pub enum BedrockAuthMethod { + #[default] + #[serde(alias = "profile")] + Profile, + #[serde(alias = "static_keys")] + StaticKeys, + #[serde(alias = "sso")] + Sso, +} + +settings::macros::implement_setting_for_enum!( + BedrockAuthMethod, + AISettings, + SupportedPlatforms::DESKTOP, + SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "ai.bedrock.auth_method", + description: "Authentication method for AWS Bedrock.", +); + +impl BedrockAuthMethod { + pub fn display_name(&self) -> &'static str { + match self { + BedrockAuthMethod::Profile => "AWS Profile", + BedrockAuthMethod::StaticKeys => "Static Keys", + BedrockAuthMethod::Sso => "SSO", + } + } +} + +/// Configuration for a single Bedrock model. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, schemars::JsonSchema)] +#[schemars(description = "Configuration for a single AWS Bedrock model.")] +pub struct BedrockModelConfig { + #[schemars( + description = "The Bedrock model ID (e.g. anthropic.claude-sonnet-4-20250514-v1:0)." + )] + pub model_id: String, + #[schemars(description = "Display name shown in the model picker.")] + pub display_name: String, + #[serde(default)] + #[schemars(description = "Whether the model supports image/vision input.")] + pub vision_supported: bool, +} + +impl settings_value::SettingsValue for BedrockModelConfig {} + +fn default_context_size() -> u32 { + 200_000 +} + +/// Configuration for a single OpenAI-compatible (LiteLLM) model. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, schemars::JsonSchema)] +#[schemars(description = "Configuration for a single OpenAI-compatible model (e.g. via LiteLLM).")] +pub struct OpenAIModelConfig { + #[schemars( + description = "The model ID to send in the API request (e.g. claude-sonnet-4-20250514)." + )] + pub model_id: String, + #[schemars(description = "Display name shown in the model picker.")] + pub display_name: String, + #[serde(default)] + #[schemars(description = "Whether the model supports image/vision input.")] + pub vision_supported: bool, + #[serde(default = "default_context_size")] + #[schemars(description = "Maximum context window size in tokens.")] + pub context_size: u32, + #[serde(default)] + #[schemars( + description = "Optional provider hint (e.g. anthropic, openai, google) for icon display." + )] + pub provider: Option, +} + +impl settings_value::SettingsValue for OpenAIModelConfig {} + +/// Configuration for a single OpenAI-compatible provider endpoint. +/// +/// Multiple providers can be configured simultaneously (e.g. LiteLLM for cloud models, +/// Ollama for local models, etc.). Each provider has its own endpoint, credentials, and model list. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, schemars::JsonSchema)] +#[schemars( + description = "Configuration for an OpenAI-compatible provider endpoint (e.g. LiteLLM, Ollama, vLLM)." +)] +pub struct OpenAIProviderConfig { + #[schemars(description = "Display name for this provider (shown in model picker).")] + pub name: String, + #[schemars(description = "Base URL for the OpenAI-compatible API endpoint.")] + pub base_url: String, + #[serde(default)] + #[schemars(description = "API key for this endpoint (optional if the proxy handles auth).")] + pub api_key: Option, + #[serde(default)] + #[schemars(description = "Models available from this provider.")] + pub models: Vec, +} + +impl settings_value::SettingsValue for OpenAIProviderConfig {} + define_settings_group!(AISettings, settings: [ // If `false`, all AI features are disabled. is_any_ai_enabled: IsAnyAIEnabled { @@ -1094,7 +1211,7 @@ define_settings_group!(AISettings, settings: [ private: true, } // Whether to use locally loaded AWS credentials for Bedrock-enabled requests. - aws_bedrock_credentials_enabled: AwsBedrockCredentialsEnabled { + bedrock_enabled: BedrockEnabled { type: bool, default: true, supported_platforms: SupportedPlatforms::DESKTOP, @@ -1203,6 +1320,67 @@ define_settings_group!(AISettings, settings: [ toml_path: "cloud_platform.third_party_api_keys.gemini_enterprise_credentials_enabled", description: "Whether Warp should route eligible requests through your workspace's Gemini Enterprise Google Cloud project.", } + // Whether the OpenAI-compatible (LiteLLM) provider is enabled. + openai_enabled: OpenAIEnabled { + type: bool, + default: false, + supported_platforms: SupportedPlatforms::DESKTOP, + sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "ai.openai.enabled", + description: "Whether to use an OpenAI-compatible endpoint (e.g. LiteLLM) for AI requests.", + } + // Base URL for the OpenAI-compatible API endpoint. + openai_base_url: OpenAIBaseUrl { + type: String, + default: "http://localhost:4000/v1".to_string(), + supported_platforms: SupportedPlatforms::DESKTOP, + sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "ai.openai.base_url", + description: "Base URL for the OpenAI-compatible API endpoint (e.g. LiteLLM proxy).", + } + // API key for the OpenAI-compatible endpoint (optional if proxy handles auth). + openai_api_key: OpenAIApiKey { + type: String, + default: String::new(), + supported_platforms: SupportedPlatforms::DESKTOP, + sync_to_cloud: SyncToCloud::Never, + private: false, + toml_path: "ai.openai.api_key", + description: "API key for the OpenAI-compatible endpoint (optional if proxy handles auth).", + } + // Model name to send to the OpenAI-compatible endpoint. Empty = use selected model ID. + openai_model: OpenAIModel { + type: String, + default: String::new(), + supported_platforms: SupportedPlatforms::DESKTOP, + sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "ai.openai.model", + description: "Model name to send to the OpenAI-compatible endpoint. Leave empty to use the selected model ID.", + } + // Custom OpenAI-compatible model configurations (fetched from LiteLLM or manually configured). + openai_models: OpenAIModels { + type: Vec, + default: Vec::new(), + supported_platforms: SupportedPlatforms::DESKTOP, + sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "ai.openai.models", + description: "Custom OpenAI-compatible model configurations (e.g. from LiteLLM).", + } + // Multiple OpenAI-compatible provider endpoints (LiteLLM, Ollama, vLLM, etc.). + // Each provider has its own name, base_url, api_key, and model list. + openai_providers: OpenAIProviders { + type: Vec, + default: Vec::new(), + supported_platforms: SupportedPlatforms::DESKTOP, + sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "ai.providers", + description: "Multiple OpenAI-compatible provider endpoints (e.g. LiteLLM, Ollama, local models).", + } // Whether or not the user wants agent mode requests to use their saved rules. memory_enabled: MemoryEnabled { type: bool, @@ -1349,6 +1527,18 @@ define_settings_group!(AISettings, settings: [ private: true, } + // Used to determine whether the "What's new in Oz" section of the agent view + // zero state is shown or hidden. + should_show_oz_updates_in_zero_state: ShouldShowOzUpdatesInZeroState { + type: bool, + default: true, + supported_platforms: SupportedPlatforms::ALL, + sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes), + private: false, + toml_path: "agents.warp_agent.other.should_show_oz_updates_in_zero_state", + description: "Whether the \"What's new\" section is shown in the agent view.", + } + // Whether or not the user has enabled fallback to Warp credits for user-provided models. diff --git a/app/src/settings/ai_tests.rs b/app/src/settings/ai_tests.rs index 62d42edd..8a7621be 100644 --- a/app/src/settings/ai_tests.rs +++ b/app/src/settings/ai_tests.rs @@ -1,6 +1,7 @@ use chrono::Utc; use galaxy_graphql::scalars::time::ServerTimestamp; use galaxyui::{App, SingletonEntity}; +use settings_value::SettingsValue; use super::*; use crate::ai::request_usage_model::{RequestLimitInfo, RequestLimitRefreshDuration}; @@ -315,7 +316,6 @@ fn test_toolbar_command_map_from_file_value_map_format() { #[test] fn test_toolbar_command_map_from_file_value_legacy_array() { - // Patterns are intentionally non-alphabetical to verify insertion order is preserved. let value = serde_json::json!(["^zebra", "^alpha", "^middle"]); let map = ToolbarCommandMap::from_file_value(&value).unwrap(); @@ -329,14 +329,12 @@ fn test_toolbar_command_map_from_file_value_legacy_array() { #[test] fn test_toolbar_command_map_from_file_value_invalid() { - let value = serde_json::json!(42); assert!(ToolbarCommandMap::from_file_value(&value).is_none()); } #[test] fn test_toolbar_command_map_roundtrip() { - let mut inner = IndexMap::new(); inner.insert("^claude".to_string(), "Claude".to_string()); inner.insert("^custom".to_string(), String::new()); diff --git a/app/src/settings/alias_expansion.rs b/app/src/settings/alias_expansion.rs index 8c32bba4..6d85054a 100644 --- a/app/src/settings/alias_expansion.rs +++ b/app/src/settings/alias_expansion.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(AliasExpansionSettings, settings: [ alias_expansion_enabled: AliasExpansionEnabled { diff --git a/app/src/settings/app_icon.rs b/app/src/settings/app_icon.rs index e43bc879..a273616a 100644 --- a/app/src/settings/app_icon.rs +++ b/app/src/settings/app_icon.rs @@ -1,9 +1,8 @@ use enum_iterator::Sequence; -use galaxy_core::settings::{macros::define_settings_group, SupportedPlatforms, SyncToCloud}; -use serde::{Deserialize, Serialize}; use galaxy_core::channel::{Channel, ChannelState}; use galaxy_core::settings::macros::define_settings_group; -use galaxy_core::settings::{SupportedPlatforms, SyncToCloud}; +use galaxy_core::settings::{Setting, SupportedPlatforms, SyncToCloud}; +use serde::{Deserialize, Serialize}; /// The app icon to use (mac-only). /// diff --git a/app/src/settings/app_installation_detection.rs b/app/src/settings/app_installation_detection.rs index 7fc19251..8a9e5ca3 100644 --- a/app/src/settings/app_installation_detection.rs +++ b/app/src/settings/app_installation_detection.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; use settings::macros::define_settings_group; -use settings::{SupportedPlatforms, SyncToCloud}; +use settings::{Setting, SupportedPlatforms, SyncToCloud}; #[derive( Clone, diff --git a/app/src/settings/block_visibility.rs b/app/src/settings/block_visibility.rs index 72baabbb..ed250bb5 100644 --- a/app/src/settings/block_visibility.rs +++ b/app/src/settings/block_visibility.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; // Settings for visibility of non-user command blocks like the bootstrap block // and in-band command blocks. diff --git a/app/src/settings/changelog.rs b/app/src/settings/changelog.rs index f02d79dc..17276711 100644 --- a/app/src/settings/changelog.rs +++ b/app/src/settings/changelog.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(ChangelogSettings, settings: [ show_changelog_after_update: ShowChangelogAfterUpdate { diff --git a/app/src/settings/cloud_preferences.rs b/app/src/settings/cloud_preferences.rs index 3192adc1..c266ddf2 100644 --- a/app/src/settings/cloud_preferences.rs +++ b/app/src/settings/cloud_preferences.rs @@ -1,6 +1,6 @@ pub use cloud_object_models::{CloudPreference, CloudPreferenceModel, Platform, Preference}; use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use crate::cloud_object::model::generic_string_model::StringModel; use crate::cloud_object::model::json_model::JsonModel; diff --git a/app/src/settings/cloud_preferences_syncer.rs b/app/src/settings/cloud_preferences_syncer.rs index d8034f4c..00691625 100644 --- a/app/src/settings/cloud_preferences_syncer.rs +++ b/app/src/settings/cloud_preferences_syncer.rs @@ -4,8 +4,6 @@ use std::sync::Arc; use std::time::Duration; use cloud_object_models::JsonSerializer; -use lazy_static::lazy_static; -use settings::{Setting as _, SyncToCloud}; use galaxy_core::execution_mode::AppExecutionMode; use galaxy_core::r#async::debounce; use galaxy_core::settings::ChangeEventReason; @@ -13,6 +11,8 @@ use galaxy_core::user_preferences::GetUserPreferences; use galaxyui::r#async::Timer; use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity}; use galaxyui_extras::user_preferences::toml_backed::TomlBackedUserPreferences; +use lazy_static::lazy_static; +use settings::{Setting as _, SyncToCloud}; use super::cloud_preferences::{CloudPreferencesSettings, CloudPreferencesSettingsChangedEvent}; use super::manager::SettingsEvent; diff --git a/app/src/settings/code.rs b/app/src/settings/code.rs index 738eeac9..c22416a8 100644 --- a/app/src/settings/code.rs +++ b/app/src/settings/code.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(CodeSettings, settings: [ code_as_default_editor: CodeAsDefaultEditor { diff --git a/app/src/settings/emacs_bindings.rs b/app/src/settings/emacs_bindings.rs index 36b96f86..1180c418 100644 --- a/app/src/settings/emacs_bindings.rs +++ b/app/src/settings/emacs_bindings.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use crate::banner::BannerState; diff --git a/app/src/settings/font.rs b/app/src/settings/font.rs index 4f7932a4..ab78ead7 100644 --- a/app/src/settings/font.rs +++ b/app/src/settings/font.rs @@ -1,10 +1,10 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use galaxy_core::ui::builder::MIN_FONT_SIZE; use galaxyui::elements::DEFAULT_UI_LINE_HEIGHT_RATIO; use galaxyui::fonts::Weight; use galaxyui::rendering::ThinStrokes; use galaxyui::{AppContext, SingletonEntity}; +use settings::macros::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use super::EnforceMinimumContrast as EnforceMinimumContrastEnum; diff --git a/app/src/settings/gpu.rs b/app/src/settings/gpu.rs index b2854bb5..3b0e4fcc 100644 --- a/app/src/settings/gpu.rs +++ b/app/src/settings/gpu.rs @@ -1,6 +1,6 @@ -use settings::macros::define_settings_group; -use settings::{SupportedPlatforms, SyncToCloud}; use galaxyui::platform::GraphicsBackend; +use settings::macros::define_settings_group; +use settings::{Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(GPUSettings, settings: [ prefer_low_power_gpu: PreferLowPowerGPU { diff --git a/app/src/settings/import/alacritty_parser.rs b/app/src/settings/import/alacritty_parser.rs index 0669b197..6a8f96d6 100644 --- a/app/src/settings/import/alacritty_parser.rs +++ b/app/src/settings/import/alacritty_parser.rs @@ -4,11 +4,11 @@ use std::path::PathBuf; use async_recursion::async_recursion; use async_trait::async_trait; +use galaxy_core::ui::color::hex_color::coloru_from_hex_string; +use galaxy_core::ui::theme::{AnsiColor, AnsiColors, GalaxyTheme, TerminalColors}; +use galaxyui::fonts::FontInfo; use pathfinder_color::ColorU; use serde::Deserialize; -use galaxy_core::ui::color::hex_color::coloru_from_hex_string; -use galaxy_core::ui::theme::{AnsiColor, AnsiColors, TerminalColors, WarpTheme}; -use galaxyui::fonts::FontInfo; use super::config::{ calculate_accent_color, Config, ConfigError, ImportableSetting, ParseableConfig, SettingType, diff --git a/app/src/settings/import/alacritty_parser_tests.rs b/app/src/settings/import/alacritty_parser_tests.rs index 3923d208..5c0242c7 100644 --- a/app/src/settings/import/alacritty_parser_tests.rs +++ b/app/src/settings/import/alacritty_parser_tests.rs @@ -1,8 +1,7 @@ use async_io::block_on; -use galaxy_core::ui::{color::hex_color::coloru_from_hex_string, theme::AnsiColor}; -use virtual_fs::{Stub, VirtualFS}; use galaxy_core::ui::color::hex_color::coloru_from_hex_string; use galaxy_core::ui::theme::AnsiColor; +use virtual_fs::{Stub, VirtualFS}; use super::{ AlacrittyColors, AlacrittyConfig, AlacrittyTheme, PrimaryAlacrittyColors, RecursivelyParseable, diff --git a/app/src/settings/import/config.rs b/app/src/settings/import/config.rs index 9b5a8aac..3e37754c 100644 --- a/app/src/settings/import/config.rs +++ b/app/src/settings/import/config.rs @@ -2,15 +2,15 @@ use std::path::PathBuf; use std::sync::Arc; use async_trait::async_trait; +use galaxy_core::ui::color::hex_color::HexColorError as UiHexColorError; +use galaxy_core::ui::theme::{AnsiColors, GalaxyTheme}; +use galaxyui::fonts::FontInfo; +use galaxyui::keymap::Keystroke; +use galaxyui::DisplayIdx; use pathfinder_color::ColorU; use serde::Serialize; use strum_macros::EnumIter; use thiserror::Error; -use galaxy_core::ui::color::hex_color::HexColorError as UiHexColorError; -use galaxy_core::ui::theme::{AnsiColors, WarpTheme}; -use galaxyui::fonts::FontInfo; -use galaxyui::keymap::Keystroke; -use galaxyui::DisplayIdx; use super::alacritty_parser::AlacrittyConfig; #[cfg(target_os = "macos")] diff --git a/app/src/settings/import/iterm_parser.rs b/app/src/settings/import/iterm_parser.rs index a1a76083..48967d06 100644 --- a/app/src/settings/import/iterm_parser.rs +++ b/app/src/settings/import/iterm_parser.rs @@ -3,18 +3,14 @@ use std::path::PathBuf; use async_trait::async_trait; use bitflags::bitflags; use galaxy_core::ui::theme::{AnsiColors, GalaxyTheme, TerminalColors}; -use galaxyui::{ - fonts::FontInfo, keymap::Keystroke, platform::mac::utils::unicode_char_to_key, DisplayIdx, -}; -use itertools::Itertools; -use palette::Srgba; -use pathfinder_color::ColorU; -use plist::{Dictionary, Value}; -use galaxy_core::ui::theme::{AnsiColors, TerminalColors, WarpTheme}; use galaxyui::fonts::FontInfo; use galaxyui::keymap::Keystroke; use galaxyui::platform::mac::utils::unicode_char_to_key; use galaxyui::DisplayIdx; +use itertools::Itertools; +use palette::Srgba; +use pathfinder_color::ColorU; +use plist::{Dictionary, Value}; use super::config::{ calculate_accent_color, Config, ConfigError, GlobalHotkey, ImportableSetting, ImportedFont, diff --git a/app/src/settings/import/iterm_parser_tests.rs b/app/src/settings/import/iterm_parser_tests.rs index 6306f5d2..36c4416f 100644 --- a/app/src/settings/import/iterm_parser_tests.rs +++ b/app/src/settings/import/iterm_parser_tests.rs @@ -1,12 +1,10 @@ use async_io::block_on; use galaxy_core::ui::theme::{Fill, GalaxyTheme}; -use galaxyui::{fonts::FontInfo, keymap::Keystroke}; +use galaxyui::fonts::FontInfo; +use galaxyui::keymap::Keystroke; use pathfinder_color::ColorU; use plist::{Dictionary, Value}; use virtual_fs::{Stub, VirtualFS}; -use galaxy_core::ui::theme::{Fill, WarpTheme}; -use galaxyui::fonts::FontInfo; -use galaxyui::keymap::Keystroke; use super::{color_dictionary_to_coloru, ITermTheme, ITermThemeType}; use crate::settings::import::config::{ diff --git a/app/src/settings/import/model.rs b/app/src/settings/import/model.rs index 90d9fa39..eb73a260 100644 --- a/app/src/settings/import/model.rs +++ b/app/src/settings/import/model.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; +use galaxy_core::features::FeatureFlag; +use galaxyui::{Entity, ModelContext, SingletonEntity}; use serde::Serialize; use strum::IntoEnumIterator; use strum_macros::{EnumDiscriminants, EnumIter}; -use galaxy_core::features::FeatureFlag; -use galaxyui::{Entity, ModelContext, SingletonEntity}; #[cfg(target_os = "macos")] use super::config::HotkeyError; diff --git a/app/src/settings/import/view.rs b/app/src/settings/import/view.rs index 66f6351f..aca3bfeb 100644 --- a/app/src/settings/import/view.rs +++ b/app/src/settings/import/view.rs @@ -1,5 +1,3 @@ -use galaxy_core::{settings::Setting, ui::appearance::Appearance}; -use itertools::Itertools; use galaxy_core::settings::Setting; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ @@ -14,6 +12,7 @@ use galaxyui::ui_components::radio_buttons::{self, RadioButtonItem, RadioButtonS use galaxyui::{ Element, Entity, ModelContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use itertools::Itertools; use super::config::{QuakeModeWindow, ThemeType}; use crate::settings::import::config::{Config, ParsedTerminalSetting, SettingType}; @@ -27,7 +26,7 @@ use crate::terminal::keys_settings::KeysSettings; use crate::terminal::session_settings::SessionSettings; use crate::themes::theme::{CustomTheme, SelectedSystemThemes, ThemeKind}; use crate::ui_components::blended_colors; -use crate::user_config::{self, WarpConfig}; +use crate::user_config::{self, GalaxyConfig}; use crate::window_settings::WindowSettings; use crate::{ report_if_error, send_telemetry_from_ctx, GlobalResourceHandlesProvider, TelemetryEvent, diff --git a/app/src/settings/init.rs b/app/src/settings/init.rs index e7d0077b..93cb928e 100644 --- a/app/src/settings/init.rs +++ b/app/src/settings/init.rs @@ -1,11 +1,12 @@ use std::path::Path; -use settings::{Setting as _, SettingsManager}; use galaxy_core::features::FeatureFlag; use galaxy_core::semantic_selection::SemanticSelection; +use galaxy_core::user_preferences::GetUserPreferences; use galaxyui::rendering::GPUPowerPreference; use galaxyui::{AppContext, SingletonEntity}; use galaxyui_extras::user_preferences; +use settings::{Setting as _, SettingsManager}; use super::app_icon::AppIconSettings; use super::app_installation_detection::UserAppInstallDetectionSettings; @@ -363,7 +364,6 @@ fn needs_settings_file_migration_for_path(ctx: &AppContext, settings_file_path: /// the in-memory setting, and writes to the TOML file with the correct /// hierarchy, `serialize_for_file` transforms, and `max_table_depth`. fn migrate_native_settings_to_settings_file(ctx: &mut AppContext) { - log::info!("Migrating public settings from native store to settings.toml"); // Collect the storage keys for all public settings. diff --git a/app/src/settings/init_tests.rs b/app/src/settings/init_tests.rs index 419c4183..73b38541 100644 --- a/app/src/settings/init_tests.rs +++ b/app/src/settings/init_tests.rs @@ -1,13 +1,12 @@ use galaxy_core::features::FeatureFlag; -use galaxy_core::settings::{macros::define_settings_group, SupportedPlatforms, SyncToCloud}; +use galaxy_core::settings::macros::define_settings_group; +use galaxy_core::settings::{SupportedPlatforms, SyncToCloud}; use galaxy_core::user_preferences::GetUserPreferences as _; use galaxyui::SingletonEntity; use galaxyui_extras::user_preferences; use instant::Duration; use settings::{PrivatePreferences, PublicPreferences, Setting, SettingsManager}; use settings_value::SettingsValue; -use galaxy_core::settings::macros::define_settings_group; -use galaxy_core::settings::{SupportedPlatforms, SyncToCloud}; use super::{ migrate_native_settings_to_settings_file, needs_settings_file_migration_for_path, @@ -373,7 +372,9 @@ fn test_migration_with_multiple_setting_types() { // serde fallback is never reached and values are lost. mod notifications_migration { - use settings::{PrivatePreferences, PublicPreferences, SettingsManager}; + use galaxy_core::settings::{SupportedPlatforms, SyncToCloud}; + use galaxyui_extras::user_preferences; + use settings::{PrivatePreferences, PublicPreferences, Setting, SettingsManager}; use crate::terminal::session_settings::NotificationsSettings; diff --git a/app/src/settings/input.rs b/app/src/settings/input.rs index f5fca7fd..ce014ffd 100644 --- a/app/src/settings/input.rs +++ b/app/src/settings/input.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; +use galaxyui::{AppContext, SingletonEntity}; use serde::{Deserialize, Serialize}; use settings::Setting as _; /// TODO: move alias_expansion setting into this group. use settings::{define_settings_group, RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; -use galaxyui::{AppContext, SingletonEntity}; use crate::terminal::input::inline_menu::InlineMenuType; use crate::terminal::session_settings::SessionSettings; diff --git a/app/src/settings/linux.rs b/app/src/settings/linux.rs index a1945f64..7a64e2eb 100644 --- a/app/src/settings/linux.rs +++ b/app/src/settings/linux.rs @@ -1,6 +1,6 @@ +use galaxyui::platform::linux; use settings::macros::define_settings_group; use settings::{SupportedPlatforms, SyncToCloud}; -use galaxyui::platform::linux; define_settings_group!(LinuxAppConfiguration, settings: [ diff --git a/app/src/settings/local_control.rs b/app/src/settings/local_control.rs index 17b411e0..84377553 100644 --- a/app/src/settings/local_control.rs +++ b/app/src/settings/local_control.rs @@ -4,12 +4,12 @@ //! persisted through Warp's secure storage provider. It is the authoritative //! enablement bit for local control. use anyhow::Result; +use galaxy_core::channel::{Channel, ChannelState}; +use galaxyui_extras::secure_storage; use serde::{Deserialize, Serialize}; use settings::macros::define_settings_group; use settings::{SecureSetting, Setting, SupportedPlatforms, SyncToCloud}; -use galaxy_core::channel::{Channel, ChannelState}; use warpui::{AppContext, ModelContext}; -use galaxyui_extras::secure_storage; const LOCAL_CONTROL_MODE_STORAGE_KEY: &str = "LocalControlMode"; diff --git a/app/src/settings/local_control_tests.rs b/app/src/settings/local_control_tests.rs index bb28c9b7..4e71d2b6 100644 --- a/app/src/settings/local_control_tests.rs +++ b/app/src/settings/local_control_tests.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; use std::sync::Mutex; -use settings::{PrivatePreferences, PublicPreferences, Setting as _, SettingsManager, SyncToCloud}; use galaxy_core::channel::{Channel, ChannelState}; -use warpui::SingletonEntity as _; use galaxyui_extras::secure_storage::{self, AppContextExt as _}; use galaxyui_extras::user_preferences; +use settings::{PrivatePreferences, PublicPreferences, Setting as _, SettingsManager, SyncToCloud}; +use warpui::SingletonEntity as _; use super::{ default_mode_for_channel, LocalControlMode, LocalControlModeSetting, LocalControlSettings, diff --git a/app/src/settings/mod.rs b/app/src/settings/mod.rs index 22d1157d..34a2a6c0 100644 --- a/app/src/settings/mod.rs +++ b/app/src/settings/mod.rs @@ -121,21 +121,21 @@ use std::collections::HashMap; use std::ops::Mul; use std::path::PathBuf; +use galaxy_core::features::FeatureFlag; +use galaxyui::elements::DEFAULT_UI_LINE_HEIGHT_RATIO; +use galaxyui::keymap::Keystroke; +use galaxyui::{AppContext, DisplayIdx, SingletonEntity}; use lazy_static::lazy_static; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::Vector2F; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use settings::Setting as _; -use galaxy_core::features::FeatureFlag; -use galaxyui::elements::DEFAULT_UI_LINE_HEIGHT_RATIO; -use galaxyui::keymap::Keystroke; -use galaxyui::{AppContext, DisplayIdx, SingletonEntity}; use crate::root_view::QuakeModePinPosition; use crate::terminal::{BlockListSettings, BlockPadding}; -use crate::themes::theme::{ThemeKind, WarpTheme}; -use crate::user_config::WarpConfig; +use crate::themes::theme::{GalaxyTheme, ThemeKind}; +use crate::user_config::GalaxyConfig; // The following are user preferences keys. pub const CHANGELOG_VERSIONS: &str = "ChangelogVersions"; diff --git a/app/src/settings/native_preference.rs b/app/src/settings/native_preference.rs index 4570c747..3f563ef8 100644 --- a/app/src/settings/native_preference.rs +++ b/app/src/settings/native_preference.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; use settings::macros::define_settings_group; -use settings::{SupportedPlatforms, SyncToCloud}; +use settings::{Setting, SupportedPlatforms, SyncToCloud}; #[derive( Clone, diff --git a/app/src/settings/onboarding.rs b/app/src/settings/onboarding.rs index 9f08f3c8..226561cc 100644 --- a/app/src/settings/onboarding.rs +++ b/app/src/settings/onboarding.rs @@ -1,7 +1,7 @@ +use galaxy_core::features::FeatureFlag; use onboarding::slides::{AgentAutonomy, AgentDevelopmentSettings}; use onboarding::{SelectedSettings, SessionDefault, UICustomizationSettings}; use settings::Setting as _; -use galaxy_core::features::FeatureFlag; use warpui::{AppContext, SingletonEntity as _}; use crate::ai::execution_profiles::profiles::AIExecutionProfilesModel; diff --git a/app/src/settings/onboarding_tests.rs b/app/src/settings/onboarding_tests.rs index c80e443d..33a23bea 100644 --- a/app/src/settings/onboarding_tests.rs +++ b/app/src/settings/onboarding_tests.rs @@ -1,9 +1,9 @@ use ai::LLMId; use chrono::{DateTime, Utc}; +use galaxy_core::features::FeatureFlag; use galaxyui::{App, SingletonEntity}; use onboarding::slides::{AgentAutonomy, AgentDevelopmentSettings, ProjectOnboardingSettings}; use onboarding::SelectedSettings; -use galaxy_core::features::FeatureFlag; use crate::ai::execution_profiles::profiles::AIExecutionProfilesModel; use crate::ai::execution_profiles::{ diff --git a/app/src/settings/pane.rs b/app/src/settings/pane.rs index 66f6fc44..15157937 100644 --- a/app/src/settings/pane.rs +++ b/app/src/settings/pane.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(PaneSettings, settings: [ should_dim_inactive_panes: ShouldDimInactivePanes { diff --git a/app/src/settings/privacy.rs b/app/src/settings/privacy.rs index e514346e..a3ae0502 100644 --- a/app/src/settings/privacy.rs +++ b/app/src/settings/privacy.rs @@ -5,12 +5,14 @@ use anyhow::Result; use galaxy_core::features::FeatureFlag; use galaxy_core::report_if_error; use galaxy_core::user_preferences::GetUserPreferences as _; +use galaxy_graphql::mutations::update_user_settings::UpdateUserSettingsInput; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity, UpdateModel}; use regex::Regex; use serde::{Deserialize, Serialize}; use settings::macros::{define_settings_group, maybe_define_setting, register_settings_events}; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; -use galaxy_graphql::mutations::update_user_settings::UpdateUserSettingsInput; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; use super::cloud_preferences_syncer::CloudPreferencesSyncer; use crate::ai::blocklist::telemetry_banner::should_collect_ai_ugc_telemetry; diff --git a/app/src/settings/same_line_prompt_block.rs b/app/src/settings/same_line_prompt_block.rs index f42e7fb4..885c8ec0 100644 --- a/app/src/settings/same_line_prompt_block.rs +++ b/app/src/settings/same_line_prompt_block.rs @@ -1,6 +1,6 @@ -use serde::{Deserialize, Serialize}; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; use galaxy_core::define_settings_group; +use serde::{Deserialize, Serialize}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; #[derive( Debug, diff --git a/app/src/settings/scroll.rs b/app/src/settings/scroll.rs index 1ca2ebda..b27686ba 100644 --- a/app/src/settings/scroll.rs +++ b/app/src/settings/scroll.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{SupportedPlatforms, SyncToCloud}; +use settings::{Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(ScrollSettings, settings: [ mouse_scroll_multiplier: MouseScrollMultiplier { diff --git a/app/src/settings/select.rs b/app/src/settings/select.rs index 8c065296..1079bf27 100644 --- a/app/src/settings/select.rs +++ b/app/src/settings/select.rs @@ -1,9 +1,9 @@ use std::ops::Not; -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use galaxyui::clipboard::ClipboardContent; use galaxyui::AppContext; +use settings::macros::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(SelectionSettings, settings: [ copy_on_select: CopyOnSelect { diff --git a/app/src/settings/ssh.rs b/app/src/settings/ssh.rs index cdfdb76f..c945578a 100644 --- a/app/src/settings/ssh.rs +++ b/app/src/settings/ssh.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(SshSettings, settings: [ diff --git a/app/src/settings/theme.rs b/app/src/settings/theme.rs index f9be9f5c..4d0e41d5 100644 --- a/app/src/settings/theme.rs +++ b/app/src/settings/theme.rs @@ -1,7 +1,7 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use galaxyui::platform::SystemTheme; use galaxyui::AppContext; +use settings::macros::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use crate::themes::theme::{RespectSystemTheme, SelectedSystemThemes, ThemeKind}; diff --git a/app/src/settings/vim_banner.rs b/app/src/settings/vim_banner.rs index 5f7711ef..b4b4faa3 100644 --- a/app/src/settings/vim_banner.rs +++ b/app/src/settings/vim_banner.rs @@ -1,5 +1,5 @@ -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; use galaxy_core::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use crate::banner::BannerState; diff --git a/app/src/settings_view/about_page.rs b/app/src/settings_view/about_page.rs index a12b2f9a..4aa99d72 100644 --- a/app/src/settings_view/about_page.rs +++ b/app/src/settings_view/about_page.rs @@ -1,10 +1,10 @@ +use galaxyui::ui_components::components::UiComponent; +use galaxyui::{AppContext, Entity, SingletonEntity, View, ViewContext, ViewHandle}; use warpui::assets::asset_cache::AssetSource; use warpui::elements::{ Align, CacheOption, ConstrainedBox, Container, CrossAxisAlignment, Element, Flex, Image, MainAxisAlignment, MouseStateHandle, ParentElement, Wrap, }; -use galaxyui::ui_components::components::UiComponent; -use galaxyui::{AppContext, Entity, View, ViewContext, ViewHandle}; use super::settings_page::{ MatchData, PageType, SettingsPageEvent, SettingsPageMeta, SettingsPageViewHandle, @@ -13,6 +13,7 @@ use super::settings_page::{ use super::SettingsSection; use crate::appearance::Appearance; use crate::channel::ChannelState; +use crate::settings::app_icon::AppIconSettings; use crate::themes::theme::ColorScheme; use crate::workspace::WorkspaceAction; diff --git a/app/src/settings_view/agent_assisted_environment_modal.rs b/app/src/settings_view/agent_assisted_environment_modal.rs index 5cbbd27d..a7afd2a3 100644 --- a/app/src/settings_view/agent_assisted_environment_modal.rs +++ b/app/src/settings_view/agent_assisted_environment_modal.rs @@ -12,12 +12,12 @@ use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; not(any(test, feature = "integration_tests")) ))] use ai::index::full_source_code_embedding::manager::CodebaseIndexManagerEvent; -#[cfg(all(feature = "local_fs", not(target_family = "wasm")))] -use git2::Repository as GitRepository; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::paths::home_relative_path; use galaxy_core::ui::theme::color::internal_colors; +#[cfg(all(feature = "local_fs", not(target_family = "wasm")))] +use git2::Repository as GitRepository; +use pathfinder_color::ColorU; use warpui::elements::{ Align, Border, ChildView, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Element, Empty, Expanded, Flex, @@ -751,7 +751,7 @@ fn available_indexed_repos(app: &AppContext) -> Vec { }) .collect(); - repos.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase())); + repos.sort_by_key(|a| a.name.to_lowercase()); repos } diff --git a/app/src/settings_view/ai_page.rs b/app/src/settings_view/ai_page.rs index 94bc9fe8..cc2abdd0 100644 --- a/app/src/settings_view/ai_page.rs +++ b/app/src/settings_view/ai_page.rs @@ -3,11 +3,6 @@ use ::ai::api_keys::{ApiKeyManager, ApiKeyManagerEvent, ApiKeys}; use ::ai::grok_subscription::oauth::{self, ManualCodeExchange}; use chrono::{DateTime, Local}; use enum_iterator::all; -use itertools::Itertools; -use pathfinder_geometry::vector::vec2f; -use regex::Regex; -use settings::{Setting, ToggleableSetting}; -use strum::IntoEnumIterator; use galaxy_core::channel::ChannelState; use galaxy_core::context_flag::ContextFlag; use galaxy_core::features::FeatureFlag; @@ -24,7 +19,7 @@ use galaxyui::elements::{ Text, }; use galaxyui::fonts::{Properties, Weight}; -use galaxyui::keymap::{ContextPredicate, Keystroke}; +use galaxyui::keymap::{ContextPredicate, FixedBinding, Keystroke}; use galaxyui::platform::Cursor; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; @@ -34,6 +29,11 @@ use galaxyui::{ id, Action, AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; +use pathfinder_geometry::vector::vec2f; +use regex::Regex; +use settings::{Setting, ToggleableSetting}; +use strum::IntoEnumIterator; use super::custom_inference_modal::{ CustomEndpointModal, CustomEndpointModalEvent, CustomEndpointModalViewState, @@ -86,19 +86,19 @@ use crate::editor::{ TextColors, }; use crate::modal::{Modal, ModalEvent, ModalViewState}; +use crate::settings::ai::BedrockAuthMethod; use crate::settings::{ AIAutoDetectionEnabled, AICommandDenylist, AISettingsChangedEvent, AgentModeCodingPermissionsType, AgentModeCommandExecutionDenylist, - AgentModeCommandExecutionPredicate, AgentModeQuerySuggestionsEnabled, AwsBedrockAutoLogin, - AwsBedrockCredentialsEnabled, CanUseWarpCreditsForFallback, CodeSettings, - CodebaseContextEnabled, FileBasedMcpEnabled, GitOperationsAutogenEnabled, - IncludeAgentCommandsInHistory, InputSettings, IntelligentAutosuggestionsEnabled, - LongRunningCommandSubmissionMode, MemoryEnabled, NLDInTerminalEnabled, - NaturalLanguageAutosuggestionsEnabled, OrchestrationMessageDisplayMode, PromptSubmissionMode, - RuleSuggestionsEnabled, SharedBlockTitleGenerationEnabled, ShouldRenderCLIAgentToolbar, - ShouldRenderUseAgentToolbarForUserCommands, ShouldShowOzUpdatesInZeroState, ShowAgentTips, - ShowConversationHistory, ShowHintText, ThinkingDisplayMode, VoiceInputEnabled, - WarpDriveContextEnabled, + AgentModeCommandExecutionPredicate, AgentModeQuerySuggestionsEnabled, BedrockAutoLogin, + BedrockEnabled, CanUseWarpCreditsForFallback, CodeSettings, CodebaseContextEnabled, + FileBasedMcpEnabled, GitOperationsAutogenEnabled, IncludeAgentCommandsInHistory, InputSettings, + IntelligentAutosuggestionsEnabled, LongRunningCommandSubmissionMode, MemoryEnabled, + NLDInTerminalEnabled, NaturalLanguageAutosuggestionsEnabled, OpenAIEnabled, + OrchestrationMessageDisplayMode, PromptSubmissionMode, RuleSuggestionsEnabled, + SharedBlockTitleGenerationEnabled, ShouldRenderCLIAgentToolbar, + ShouldRenderUseAgentToolbarForUserCommands, ShowAgentTips, ShowConversationHistory, + ShowHintText, ThinkingDisplayMode, VoiceInputEnabled, WarpDriveContextEnabled, }; use crate::terminal::session_settings::{SessionSettings, SessionSettingsChangedEvent}; use crate::terminal::CLIAgent; @@ -109,6 +109,7 @@ use crate::view_components::{ render_warning_box, FilterableDropdown, SubmittableTextInput, SubmittableTextInputEvent, WarningBoxConfig, }; +use crate::workspace::ToastStack; use crate::workspaces::user_workspaces::UserWorkspacesEvent; /// Identifies which subpage of the AI settings the user is viewing. @@ -362,7 +363,6 @@ pub fn init_actions_from_parent_view( app.register_fixed_bindings(mode_bindings); } if FeatureFlag::QueueSlashCommand.is_enabled() { - let ai_context = context.clone() & id!(flags::IS_ANY_AI_ENABLED); let mode_bindings: Vec = PromptSubmissionMode::iter() .map(|mode| { @@ -547,9 +547,9 @@ pub fn init_actions_from_parent_view( FeatureFlag::AIRules.is_enabled() && FeatureFlag::SuggestedRules.is_enabled() }), ToggleSettingActionPair::new( - "Warp Drive as agent context", + "Galaxy Drive as agent context", builder(SettingsAction::AI( - AISettingsPageAction::ToggleWarpDriveContext, + AISettingsPageAction::ToggleGalaxyDriveContext, )), &(context.clone() & id!(flags::IS_ANY_AI_ENABLED)), flags::WARP_DRIVE_CONTEXT_FLAG, @@ -1891,19 +1891,21 @@ impl AISettingsPageView { } }); } - // Subscribe to WarpConfig to refresh router views when files change. + // Subscribe to GalaxyConfig to refresh router views when files change. #[cfg(feature = "local_fs")] ctx.subscribe_to_model( - &crate::user_config::WarpConfig::handle(ctx), + &crate::user_config::GalaxyConfig::handle(ctx), |me, _, event, ctx| { - use crate::user_config::WarpConfigUpdateEvent; - if matches!(event, WarpConfigUpdateEvent::ModelConfigs) { + use crate::user_config::GalaxyConfigUpdateEvent; + if matches!(event, GalaxyConfigUpdateEvent::ModelConfigs) { me.router_views = Self::create_router_views(ctx); ctx.notify(); } }, ); + let (page, _) = Self::build_page(None, ctx); + Self { page, active_subpage: None, @@ -2660,7 +2662,6 @@ impl AISettingsPageView { /// attempt's PKCE verifier. #[cfg(not(target_family = "wasm"))] fn submit_grok_code(&mut self, code: String, ctx: &mut ViewContext) { - use crate::view_components::DismissibleToast; // Shared with the browser connect-flow toasts. @@ -2794,10 +2795,9 @@ impl AISettingsPageView { // Derive display name from model ID let display_name = id .split('/') - .last() + .next_back() .unwrap_or(id) - .replace('-', " ") - .replace('_', " "); + .replace(['-', '_'], " "); // Capitalize first letter of each word let display_name = display_name .split_whitespace() @@ -2938,7 +2938,7 @@ impl AISettingsPageView { } widgets.push(Box::new(CloudHandoffWidget::default())); widgets.push(Box::new(ApiKeysWidget::new(ctx))); - widgets.push(Box::new(AwsBedrockWidget::new(ctx))); + widgets.push(Box::new(BedrockSettingsWidget::new(ctx))); if FeatureFlag::CustomModelRouters.is_enabled() { widgets.push(Box::new(CustomModelRoutersWidget)); } @@ -3483,12 +3483,12 @@ impl AISettingsPageView { ctx: &mut ViewContext, ) -> Vec> { use super::custom_router_view::{CustomRouterView, CustomRouterViewEvent}; - use crate::user_config::WarpConfig; + use crate::user_config::GalaxyConfig; if !galaxy_core::features::FeatureFlag::CustomModelRouters.is_enabled() { return Vec::new(); } let routers: Vec = - WarpConfig::as_ref(ctx).custom_model_routers().clone(); + GalaxyConfig::as_ref(ctx).custom_model_routers().clone(); routers .into_iter() .map(|router| { @@ -3507,7 +3507,9 @@ impl AISettingsPageView { #[cfg(feature = "local_fs")] { if let Err(e) = - crate::user_config::WarpConfig::delete_custom_model_router(path) + crate::user_config::GalaxyConfig::delete_custom_model_router( + path, + ) { log::warn!("Failed to delete custom router: {e:?}"); } @@ -3758,6 +3760,7 @@ pub enum AISettingsPageAction { pattern: String, agent: Option, }, + ToggleCloudAgentComputerUse, } impl From<&AISettingsPageAction> for LoginGatedFeature { @@ -4450,6 +4453,14 @@ impl TypedActionView for AISettingsPageView { }); ctx.notify(); } + AISettingsPageAction::ToggleCloudAgentComputerUse => { + AISettings::handle(ctx).update(ctx, |settings, ctx| { + report_if_error!(settings + .cloud_agent_computer_use_enabled + .toggle_and_save_value(ctx)); + }); + ctx.notify(); + } AISettingsPageAction::ToggleBedrockEnabled => { AISettings::handle(ctx).update(ctx, |settings, ctx| { report_if_error!(settings.bedrock_enabled.toggle_and_save_value(ctx)); @@ -7900,6 +7911,7 @@ impl SettingsWidget for AgentAttributionWidget { mod tests; #[derive(Default)] +#[allow(dead_code)] struct CloudAgentComputerUseWidget { toggle: SwitchStateHandle, } @@ -8241,7 +8253,7 @@ impl ApiKeysWidget { ctx.subscribe_to_view(&$editor, |_, $editor, event, ctx| { if matches!(event, EditorEvent::Blurred | EditorEvent::Enter) { let buffer_text = $editor.as_ref(ctx).buffer_text(ctx); - let key = buffer_text.is_empty().not().then_some(buffer_text); + let key = (!buffer_text.is_empty()).then_some(buffer_text); ApiKeyManager::handle(ctx).update(ctx, |model, ctx| { model.$set_func(key, ctx); }); @@ -9054,10 +9066,8 @@ impl SettingsWidget for ApiKeysWidget { } } -struct AwsBedrockWidget { - aws_auth_refresh_command_editor: ViewHandle, - aws_auth_refresh_profile_editor: ViewHandle, - credentials_enabled_toggle: SwitchStateHandle, +struct BedrockSettingsWidget { + enabled_toggle: SwitchStateHandle, auto_login_toggle: SwitchStateHandle, auth_method_dropdown: ViewHandle>, profile_dropdown: ViewHandle>, @@ -9366,6 +9376,15 @@ impl SettingsWidget for BedrockSettingsWidget { let mut column = Flex::column().with_spacing(16.); + let has_aws_env = std::env::vars_os().any(|(k, _)| k.to_string_lossy().starts_with("AWS_")); + + if has_aws_env { + column.add_child(render_warning_box( + WarningBoxConfig::new("You have AWS environment variables defined, which may override these settings."), + appearance, + )); + } + column.add_child(render_ai_setting_toggle::( "Enable AWS Bedrock", AISettingsPageAction::ToggleBedrockEnabled, @@ -9641,6 +9660,135 @@ impl OpenAISettingsWidget { } } +impl SettingsWidget for OpenAISettingsWidget { + type View = AISettingsPageView; + + fn search_terms(&self) -> &str { + "openai litellm custom provider endpoint api key models" + } + + fn should_render(&self, _app: &AppContext) -> bool { + true + } + + fn render( + &self, + _view: &Self::View, + appearance: &Appearance, + app: &AppContext, + ) -> Box { + let ai_settings = AISettings::as_ref(app); + let is_enabled = *ai_settings.openai_enabled.value(); + + let mut column = Flex::column().with_spacing(16.); + + column.add_child(render_ai_setting_toggle::( + "Enable OpenAI-Compatible Provider", + AISettingsPageAction::ToggleOpenAIEnabled, + is_enabled, + true, + self.enabled_toggle.clone(), + &RefCell::new(HashMap::new()), + app, + )); + column.add_child(render_ai_setting_description( + "Route AI requests through an OpenAI-compatible endpoint (e.g. LiteLLM proxy).", + true, + app, + )); + + column.add_child(render_separator(appearance)); + + column.add_child(Self::render_input( + appearance, + "Base URL", + self.base_url_editor.clone(), + is_enabled, + app, + )); + column.add_child(render_ai_setting_description( + "The OpenAI-compatible API base URL (e.g. http://localhost:4000/v1).", + is_enabled, + app, + )); + + column.add_child(Self::render_input( + appearance, + "API Key", + self.api_key_editor.clone(), + is_enabled, + app, + )); + column.add_child(render_ai_setting_description( + "Optional. Leave empty if the proxy handles authentication.", + is_enabled, + app, + )); + + column.add_child(render_separator(appearance)); + + // Fetch models button + let fetch_button = appearance + .ui_builder() + .button(ButtonVariant::Secondary, self.fetch_button.clone()) + .with_text_label("Fetch Models from Endpoint".to_owned()) + .build() + .on_click(move |ctx, _, _| { + ctx.dispatch_typed_action(AISettingsPageAction::FetchOpenAIModels); + }) + .finish(); + column.add_child(fetch_button); + column.add_child(render_ai_setting_description( + "Queries the /models endpoint and populates the model list with available models and their context window sizes.", + is_enabled, + app, + )); + + column.add_child(render_separator(appearance)); + + // Show configured models count + let configured_models: Vec<_> = ai_settings.openai_models.value().clone(); + if !configured_models.is_empty() { + let description = format!( + "{} model{} configured via settings.toml.", + configured_models.len(), + if configured_models.len() == 1 { + "" + } else { + "s" + } + ); + column.add_child(render_ai_setting_description(description, is_enabled, app)); + + // Show first few model names + let preview: String = configured_models + .iter() + .take(5) + .map(|m| m.display_name.as_str()) + .collect::>() + .join(", "); + let suffix = if configured_models.len() > 5 { + format!(" (+{} more)", configured_models.len() - 5) + } else { + String::new() + }; + column.add_child(render_ai_setting_description( + format!("Models: {preview}{suffix}"), + is_enabled, + app, + )); + } else { + column.add_child(render_ai_setting_description( + "No models configured. Use 'Fetch Models' or add them to ~/.galaxy/settings.toml under [ai.openai].", + is_enabled, + app, + )); + } + + column.finish() + } +} + /// Stable `&'static str` id for the custom model routers settings widget, /// exposed for the `warp://settings?widget=custom_router` deeplink (see /// `settings_widget_deeplink_target`). @@ -9681,10 +9829,12 @@ impl SettingsWidget for CustomModelRoutersWidget { .with_child({ #[cfg(feature = "local_fs")] { - galaxyui::elements::Container::new(view.add_router_button.as_ref(app).render(app)) - .with_margin_bottom(4.) - .with_margin_top(-4.) - .finish() + galaxyui::elements::Container::new( + view.add_router_button.as_ref(app).render(app), + ) + .with_margin_bottom(4.) + .with_margin_top(-4.) + .finish() } #[cfg(not(feature = "local_fs"))] { @@ -9710,9 +9860,10 @@ impl SettingsWidget for CustomModelRoutersWidget { #[cfg(feature = "local_fs")] let column = { use super::custom_router_view::render_router_error_card; + use crate::user_config::GalaxyConfig; let mut c = column; // Error cards (files that failed to parse) — shown first - let errors = WarpConfig::as_ref(app).custom_model_router_errors(); + let errors = GalaxyConfig::as_ref(app).custom_model_router_errors(); for error in errors.iter() { c.add_child( Container::new(render_router_error_card( diff --git a/app/src/settings_view/appearance_page.rs b/app/src/settings_view/appearance_page.rs index 0dd018d0..2fea2053 100644 --- a/app/src/settings_view/appearance_page.rs +++ b/app/src/settings_view/appearance_page.rs @@ -56,12 +56,13 @@ use crate::gpu_state::{GPUState, GPUStateEvent}; use crate::prompt::editor_modal::OpenSource as PromptEditorOpenSource; use crate::server::telemetry::{InputUXChangeOrigin, TelemetryEvent}; use crate::settings::app_icon::{AppIcon, AppIconSettings, ShowDockIconState}; +use crate::settings::font::DEFAULT_UI_FONT_NAME; use crate::settings::{ active_theme_kind, respect_system_theme, AIFontName, AppEditorSettings, CursorBlink, CursorBlinkEnabled, CursorDisplayType, EnforceMinimumContrast, FocusPaneOnHover, FontSettings, FontSettingsChangedEvent, GPUSettings, InputBoxType, InputModeSettings, InputModeState, InputSettings, InputSettingsChangedEvent, MonospaceFontName, PaneSettings, - ShouldDimInactivePanes, ThemeSettings, UseSystemTheme, UseThinStrokes, + ShouldDimInactivePanes, ThemeSettings, UIFontName, UseSystemTheme, UseThinStrokes, DEFAULT_MONOSPACE_FONT_NAME, }; use crate::terminal::block_list_viewport::InputMode; @@ -76,11 +77,13 @@ use crate::terminal::settings::{ use crate::terminal::{ BlockListSettings, ShowBlockDividers, ShowJumpToBottomOfBlockButton, SizeInfo, }; -use crate::themes::theme::{self, RespectSystemTheme, SelectedSystemThemes, ThemeKind, WarpTheme}; +use crate::themes::theme::{ + self, GalaxyTheme, RespectSystemTheme, SelectedSystemThemes, ThemeKind, WarpTheme, +}; use crate::themes::theme_chooser::ThemeChooserMode; use crate::ui_components::color_dot::{render_color_dot, TAB_COLOR_OPTIONS}; use crate::ui_components::icons::Icon; -use crate::user_config::WarpConfig; +use crate::user_config::{GalaxyConfig, WarpConfig}; use crate::util::bindings; use crate::view_components::action_button::{ActionButton, ButtonSize, NakedTheme}; use crate::view_components::{Dropdown, DropdownItem, FilterableDropdown}; @@ -3101,7 +3104,7 @@ impl SettingsWidget for CustomAppIconWidget { let app_icon_at_startup = AppearanceManager::as_ref(app).app_icon_at_startup(); let current_icon = *AppIconSettings::as_ref(app).app_icon; - if current_icon == AppIcon::Default + if current_icon == AppIcon::Galaxy && ChannelState::channel() != Channel::Local && app_icon_at_startup != AppIcon::Galaxy { diff --git a/app/src/settings_view/billing_and_usage/billing_cycle_usage_common.rs b/app/src/settings_view/billing_and_usage/billing_cycle_usage_common.rs index 727f8941..cafdb75e 100644 --- a/app/src/settings_view/billing_and_usage/billing_cycle_usage_common.rs +++ b/app/src/settings_view/billing_and_usage/billing_cycle_usage_common.rs @@ -1,10 +1,10 @@ use std::cell::RefCell; use std::collections::HashMap; +use galaxy_core::ui::appearance::Appearance; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; use thousands::Separable; -use galaxy_core::ui::appearance::Appearance; use warpui::elements::{ Align, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Empty, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Shrinkable, diff --git a/app/src/settings_view/billing_and_usage/billing_cycle_usage_rows.rs b/app/src/settings_view/billing_and_usage/billing_cycle_usage_rows.rs index 6056d667..c6799b44 100644 --- a/app/src/settings_view/billing_and_usage/billing_cycle_usage_rows.rs +++ b/app/src/settings_view/billing_and_usage/billing_cycle_usage_rows.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; +use galaxy_core::channel::ChannelState; +use galaxy_core::ui::appearance::Appearance; use itertools::Itertools as _; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; -use galaxy_core::channel::ChannelState; -use galaxy_core::ui::appearance::Appearance; use warpui::elements::{ Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Empty, Expanded, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, diff --git a/app/src/settings_view/billing_and_usage/billing_cycle_usage_section.rs b/app/src/settings_view/billing_and_usage/billing_cycle_usage_section.rs index d759734b..03d12e94 100644 --- a/app/src/settings_view/billing_and_usage/billing_cycle_usage_section.rs +++ b/app/src/settings_view/billing_and_usage/billing_cycle_usage_section.rs @@ -1,8 +1,8 @@ use chrono::{DateTime, Datelike, Local, Utc}; +use galaxy_core::ui::appearance::Appearance; use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; -use galaxy_core::ui::appearance::Appearance; use warpui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Empty, Flex, FormattedTextElement, HighlightedHyperlink, Hoverable, HyperlinkLens, diff --git a/app/src/settings_view/billing_and_usage/billing_cycle_usage_team_totals.rs b/app/src/settings_view/billing_and_usage/billing_cycle_usage_team_totals.rs index 9a38486b..f92962c2 100644 --- a/app/src/settings_view/billing_and_usage/billing_cycle_usage_team_totals.rs +++ b/app/src/settings_view/billing_and_usage/billing_cycle_usage_team_totals.rs @@ -1,5 +1,5 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; +use pathfinder_geometry::vector::vec2f; use warpui::elements::{ Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Expanded, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, diff --git a/app/src/settings_view/billing_and_usage_page.rs b/app/src/settings_view/billing_and_usage_page.rs index ae0413c3..162cf0ff 100644 --- a/app/src/settings_view/billing_and_usage_page.rs +++ b/app/src/settings_view/billing_and_usage_page.rs @@ -3,12 +3,6 @@ use std::collections::HashMap; use std::sync::Arc; use chrono::Local; -use itertools::Itertools; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use settings::Setting; -use thousands::Separable; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; @@ -29,6 +23,12 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, UpdateView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use settings::Setting; +use thousands::Separable; use super::admin_actions::AdminActions; use super::billing_and_usage::overage_limit_modal::{SpendingLimitModal, SpendingLimitModalEvent}; @@ -1072,8 +1072,10 @@ impl BillingAndUsagePageAction { impl From<&BillingAndUsagePageAction> for LoginGatedFeature { fn from(val: &BillingAndUsagePageAction) -> LoginGatedFeature { match val { - Upgrade { .. } => "Upgrade Plan", - GenerateStripeBillingPortalLink { .. } => "Generate Stripe Billing Portal Link", + BillingAndUsagePageAction::Upgrade { .. } => "Upgrade Plan", + BillingAndUsagePageAction::GenerateStripeBillingPortalLink { .. } => { + "Generate Stripe Billing Portal Link" + } _ => "Unknown reason", } } diff --git a/app/src/settings_view/billing_and_usage_page_v2.rs b/app/src/settings_view/billing_and_usage_page_v2.rs index fc07e8b1..2c525d61 100644 --- a/app/src/settings_view/billing_and_usage_page_v2.rs +++ b/app/src/settings_view/billing_and_usage_page_v2.rs @@ -3,14 +3,14 @@ use std::collections::HashMap; use std::sync::Arc; use chrono::Local; +use galaxy_core::features::FeatureFlag; +use galaxy_core::ui::appearance::Appearance; use itertools::Itertools; use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; use settings::Setting; use thousands::Separable; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::appearance::Appearance; use warp_graphql::billing::AddonCreditsOption; use warpui::elements::{ Align, Border, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, diff --git a/app/src/settings_view/code_page.rs b/app/src/settings_view/code_page.rs index d423eb88..8eddb957 100644 --- a/app/src/settings_view/code_page.rs +++ b/app/src/settings_view/code_page.rs @@ -9,11 +9,6 @@ use ai::index::full_source_code_embedding::manager::{ use ai::index::full_source_code_embedding::SyncProgress; use ai::project_context::model::{ProjectContextModel, ProjectContextModelEvent}; use ai::workspace::WorkspaceMetadata; -use lsp::supported_servers::LSPServerType; -use lsp::{LspManagerModel, LspManagerModelEvent, LspServerModel, LspState}; -use pathfinder_color::ColorU; -#[cfg(not(target_family = "wasm"))] -use remote_server::codebase_index_proto::{RemoteCodebaseIndexState, RemoteCodebaseIndexStatus}; use galaxy_core::features::FeatureFlag; use galaxy_core::report_if_error; use galaxy_core::settings::ToggleableSetting as _; @@ -36,6 +31,11 @@ use galaxyui::{ id, Action, AppContext, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use lsp::supported_servers::LSPServerType; +use lsp::{LspManagerModel, LspManagerModelEvent, LspServerModel, LspState}; +use pathfinder_color::ColorU; +#[cfg(not(target_family = "wasm"))] +use remote_server::codebase_index_proto::{RemoteCodebaseIndexState, RemoteCodebaseIndexStatus}; #[cfg(feature = "local_fs")] use super::features::external_editor::ExternalEditorView; diff --git a/app/src/settings_view/custom_inference_modal.rs b/app/src/settings_view/custom_inference_modal.rs index bf9b21e6..34151a2a 100644 --- a/app/src/settings_view/custom_inference_modal.rs +++ b/app/src/settings_view/custom_inference_modal.rs @@ -584,10 +584,8 @@ impl CustomEndpointModal { EditorEvent::Escape => { self.cancel(ctx); } - EditorEvent::Edited(_) => { - if !self.validate_url_field(ctx) { - ctx.notify(); - } + EditorEvent::Edited(_) if !self.validate_url_field(ctx) => { + ctx.notify(); } _ => {} } diff --git a/app/src/settings_view/directory_color_add_picker.rs b/app/src/settings_view/directory_color_add_picker.rs index 3d569dc7..afe4de37 100644 --- a/app/src/settings_view/directory_color_add_picker.rs +++ b/app/src/settings_view/directory_color_add_picker.rs @@ -4,7 +4,6 @@ use std::path::{Path, PathBuf}; use ai::index::full_source_code_embedding::manager::{ CodebaseIndexManager, CodebaseIndexManagerEvent, }; -use settings::Setting; use galaxy_util::path::user_friendly_path; use galaxyui::elements::{ Border, ChildView, ConstrainedBox, Container, CrossAxisAlignment, Flex, Hoverable, @@ -14,6 +13,7 @@ use galaxyui::platform::Cursor; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use settings::Setting; use crate::ai::persisted_workspace::{PersistedWorkspace, PersistedWorkspaceEvent}; use crate::appearance::Appearance; @@ -306,7 +306,7 @@ fn compute_candidate_paths( let mut seen_keys = HashSet::new(); let mut candidates: Vec<(String, PathBuf)> = Vec::new(); - for path in indexed_paths.into_iter().chain(persisted_paths.into_iter()) { + for path in indexed_paths.into_iter().chain(persisted_paths) { if !path_exists(&path) { continue; } diff --git a/app/src/settings_view/environments_page.rs b/app/src/settings_view/environments_page.rs index 1238087d..b73b95ed 100644 --- a/app/src/settings_view/environments_page.rs +++ b/app/src/settings_view/environments_page.rs @@ -1,7 +1,5 @@ use std::collections::HashMap; -use instant::Instant; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::color::internal_colors; use galaxy_editor::editor::NavigationKey; @@ -22,6 +20,8 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use instant::Instant; +use pathfinder_geometry::vector::vec2f; use super::agent_assisted_environment_modal::{ AgentAssistedEnvironmentModal, AgentAssistedEnvironmentModalEvent, diff --git a/app/src/settings_view/environments_page_tests.rs b/app/src/settings_view/environments_page_tests.rs index bdbc327f..9b3ee071 100644 --- a/app/src/settings_view/environments_page_tests.rs +++ b/app/src/settings_view/environments_page_tests.rs @@ -2,8 +2,9 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; -use instant::Instant; +use chrono::{Duration, Utc}; use galaxy_core::ui::appearance::Appearance; +use instant::Instant; use warpui::elements::Empty; use warpui::platform::WindowStyle; use warpui::{App, AppContext, Element, Entity, TypedActionView, View, WindowId}; @@ -1402,7 +1403,6 @@ fn test_render_environment_card_with_last_used_never() { #[test] fn test_render_environment_card_with_last_used_timestamp() { - App::test((), |mut app| async move { app.add_singleton_model(|_| Appearance::mock()); diff --git a/app/src/settings_view/execution_profile_view.rs b/app/src/settings_view/execution_profile_view.rs index dda78bea..9ff621bc 100644 --- a/app/src/settings_view/execution_profile_view.rs +++ b/app/src/settings_view/execution_profile_view.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; -use uuid::Uuid; use galaxy_core::features::FeatureFlag; +use uuid::Uuid; use warpui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, MainAxisAlignment, MainAxisSize, ParentElement, Shrinkable, Text, Wrap, diff --git a/app/src/settings_view/features/external_editor.rs b/app/src/settings_view/features/external_editor.rs index 55e85901..b44bcc5d 100644 --- a/app/src/settings_view/features/external_editor.rs +++ b/app/src/settings_view/features/external_editor.rs @@ -1,12 +1,12 @@ use std::cell::RefCell; use std::collections::HashMap; -use settings::{Setting, ToggleableSetting}; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{Flex, MouseStateHandle, ParentElement}; use galaxyui::ui_components::components::UiComponent; use galaxyui::ui_components::switch::SwitchStateHandle; use galaxyui::{Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle}; +use settings::{Setting, ToggleableSetting}; use crate::appearance::Appearance; use crate::server::telemetry::TelemetryEvent; diff --git a/app/src/settings_view/features/undo_close.rs b/app/src/settings_view/features/undo_close.rs index b6f83890..15ddb6ee 100644 --- a/app/src/settings_view/features/undo_close.rs +++ b/app/src/settings_view/features/undo_close.rs @@ -2,7 +2,6 @@ use std::cell::RefCell; use std::collections::HashMap; use std::time::Duration; -use settings::{Setting, ToggleableSetting}; use galaxyui::elements::{ Container, CrossAxisAlignment, Flex, MainAxisAlignment, MouseStateHandle, ParentElement, Text, }; @@ -11,6 +10,7 @@ use galaxyui::ui_components::switch::SwitchStateHandle; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use settings::{Setting, ToggleableSetting}; use crate::appearance::Appearance; use crate::editor::{self, EditorView, SingleLineEditorOptions, TextOptions}; diff --git a/app/src/settings_view/features/working_directory.rs b/app/src/settings_view/features/working_directory.rs index 3cf0b2b7..6b38444e 100644 --- a/app/src/settings_view/features/working_directory.rs +++ b/app/src/settings_view/features/working_directory.rs @@ -1,8 +1,8 @@ -use itertools::Itertools; use galaxyui::elements::{Container, CrossAxisAlignment, Flex, ParentElement, Shrinkable}; use galaxyui::presenter::ChildView; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle}; +use itertools::Itertools; use crate::appearance::Appearance; use crate::editor::{EditorView, Event as EditorEvent, SingleLineEditorOptions, TextOptions}; diff --git a/app/src/settings_view/features_page.rs b/app/src/settings_view/features_page.rs index dbfa24f5..1d52bb6e 100644 --- a/app/src/settings_view/features_page.rs +++ b/app/src/settings_view/features_page.rs @@ -4,8 +4,6 @@ use std::sync::{Arc, Mutex}; use std::time::Duration; use ::settings::{Setting, ToggleableSetting}; -use lazy_static::lazy_static; -use strum::IntoEnumIterator; use galaxy_core::channel::ChannelState; use galaxy_core::context_flag::ContextFlag; use galaxy_core::semantic_selection::{ @@ -26,6 +24,8 @@ use galaxyui::{ Action, AppContext, DisplayIdx, Entity, EventContext, ModelHandle, SingletonEntity, Tracked, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use lazy_static::lazy_static; +use strum::IntoEnumIterator; #[cfg(any(target_os = "linux", target_os = "freebsd"))] use { crate::settings::ForceX11, crate::settings::LinuxAppConfiguration, diff --git a/app/src/settings_view/keybindings.rs b/app/src/settings_view/keybindings.rs index dfe2f832..965acd93 100644 --- a/app/src/settings_view/keybindings.rs +++ b/app/src/settings_view/keybindings.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use itertools::Itertools; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ Align, Border, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, @@ -16,6 +15,7 @@ use galaxyui::units::Pixels; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; use super::settings_page::{ render_sub_header, LocalOnlyIconState, MatchData, PageType, SettingsPageMeta, diff --git a/app/src/settings_view/main_page.rs b/app/src/settings_view/main_page.rs index 0b0c9949..cf640db5 100644 --- a/app/src/settings_view/main_page.rs +++ b/app/src/settings_view/main_page.rs @@ -1,9 +1,6 @@ use std::sync::{Arc, Mutex}; use ::settings::{Setting, ToggleableSetting}; -use lazy_static::lazy_static; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::channel::ChannelState; use galaxy_core::context_flag::ContextFlag; use galaxy_core::features::FeatureFlag; @@ -26,6 +23,9 @@ use galaxyui::{ id, Action, AppContext, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use lazy_static::lazy_static; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use super::settings_page::{ render_body_item, render_customer_type_badge, AdditionalInfo, LocalOnlyIconState, MatchData, @@ -141,9 +141,11 @@ impl MainPageAction { impl From<&MainPageAction> for LoginGatedFeature { fn from(val: &MainPageAction) -> LoginGatedFeature { match val { - Upgrade { .. } => "Upgrade Plan", - GenerateStripeBillingPortalLink { .. } => "Generate Stripe Billing Portal Link", - ToggleSettingsSync => "Toggle Settings Sync", + MainPageAction::Upgrade { .. } => "Upgrade Plan", + MainPageAction::GenerateStripeBillingPortalLink { .. } => { + "Generate Stripe Billing Portal Link" + } + MainPageAction::ToggleSettingsSync => "Toggle Settings Sync", _ => "Unknown reason", } } diff --git a/app/src/settings_view/mcp_servers/edit_page.rs b/app/src/settings_view/mcp_servers/edit_page.rs index e91e1de9..01ca5045 100644 --- a/app/src/settings_view/mcp_servers/edit_page.rs +++ b/app/src/settings_view/mcp_servers/edit_page.rs @@ -6,11 +6,6 @@ use std::sync::Arc; #[cfg(feature = "local_fs")] #[cfg(not(target_family = "wasm"))] use diesel::SqliteConnection; -#[cfg(feature = "local_fs")] -use parking_lot::Mutex; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; -use uuid::Uuid; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -26,8 +21,13 @@ use galaxyui::ui_components::components::UiComponent; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; -#[cfg(not(target_family = "wasm"))] +#[cfg(feature = "local_fs")] +use parking_lot::Mutex; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; +use uuid::Uuid; +#[cfg(not(target_family = "wasm"))] use crate::ai::blocklist::secret_redaction::find_secrets_in_text; use crate::ai::mcp::parsing::{prettify_json, resolve_json, ParsedTemplatableMCPServerResult}; use crate::ai::mcp::templatable::CloudTemplatableMCPServer; diff --git a/app/src/settings_view/mcp_servers/installation_modal.rs b/app/src/settings_view/mcp_servers/installation_modal.rs index e6b16944..39f5dd10 100644 --- a/app/src/settings_view/mcp_servers/installation_modal.rs +++ b/app/src/settings_view/mcp_servers/installation_modal.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; -use markdown_parser::parse_markdown; use galaxy_core::ui::external_product_icon::ExternalProductIcon; use galaxy_core::ui::icons::Icon; +use markdown_parser::parse_markdown; use warpui::elements::{ Align, Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, FormattedTextElement, HighlightedHyperlink, Hoverable, MainAxisAlignment, diff --git a/app/src/settings_view/mcp_servers/list_page.rs b/app/src/settings_view/mcp_servers/list_page.rs index 36b5bc1e..dcb915a2 100644 --- a/app/src/settings_view/mcp_servers/list_page.rs +++ b/app/src/settings_view/mcp_servers/list_page.rs @@ -2,15 +2,15 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::path::PathBuf; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use settings::ToggleableSetting as _; -use strum::IntoEnumIterator; -use uuid::Uuid; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::AppearanceEvent; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::Icon; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use settings::ToggleableSetting as _; +use strum::IntoEnumIterator; +use uuid::Uuid; use warpui::elements::{ Align, Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Expanded, Fill, Flex, FormattedTextElement, HighlightedHyperlink, MainAxisAlignment, diff --git a/app/src/settings_view/mcp_servers/server_card.rs b/app/src/settings_view/mcp_servers/server_card.rs index 9a75080b..542fb26e 100644 --- a/app/src/settings_view/mcp_servers/server_card.rs +++ b/app/src/settings_view/mcp_servers/server_card.rs @@ -1,5 +1,3 @@ -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::external_product_icon::ExternalProductIcon; use galaxy_core::ui::icons::{Icon, ICON_DIMENSIONS}; @@ -18,6 +16,8 @@ use galaxyui::ui_components::chip::Chip; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::ui_components::switch::SwitchStateHandle; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; use crate::ai::mcp::templatable::CloudTemplatableMCPServer; use crate::ai::mcp::{MCPServerState, TemplatableMCPServerManager}; diff --git a/app/src/settings_view/mcp_servers/update_modal.rs b/app/src/settings_view/mcp_servers/update_modal.rs index ef05e0b7..ae2e0a69 100644 --- a/app/src/settings_view/mcp_servers/update_modal.rs +++ b/app/src/settings_view/mcp_servers/update_modal.rs @@ -1,8 +1,8 @@ use chrono::{Local, TimeZone}; -use uuid::Uuid; use galaxy_core::ui::external_product_icon::ExternalProductIcon; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; +use uuid::Uuid; use warpui::elements::{ Align, Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, Hoverable, MainAxisAlignment, MouseStateHandle, Padding, ParentElement, Radius, diff --git a/app/src/settings_view/mcp_servers_page.rs b/app/src/settings_view/mcp_servers_page.rs index 795351dd..cb71f08b 100644 --- a/app/src/settings_view/mcp_servers_page.rs +++ b/app/src/settings_view/mcp_servers_page.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; -use uuid::Uuid; use galaxyui::elements::{ChildView, Container}; use galaxyui::ui_components::components::{Coords, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use uuid::Uuid; use crate::ai::mcp::gallery::MCPGalleryManager; use crate::ai::mcp::templatable_installation::VariableValue; diff --git a/app/src/settings_view/mod.rs b/app/src/settings_view/mod.rs index 5c2d4fa6..cb467711 100644 --- a/app/src/settings_view/mod.rs +++ b/app/src/settings_view/mod.rs @@ -10,6 +10,26 @@ use billing_and_usage_page::BillingAndUsagePageEvent; use code_page::{CodeSettingsPageAction, CodeSettingsPageEvent, CodeSubpage}; use environments_page::EnvironmentsPageView; use features_page::{FeaturesPageView, FeaturesSettingsPageEvent}; +use galaxy_core::channel::ChannelState; +use galaxy_core::context_flag::ContextFlag; +use galaxy_core::features::FeatureFlag; +use galaxy_core::send_telemetry_from_ctx; +use galaxy_core::settings::ToggleableSetting as _; +use galaxy_core::ui::theme::color::internal_colors; +use galaxy_editor::editor::NavigationKey; +use galaxyui::elements::{ + Align, Border, ChildAnchor, ChildView, Clipped, ClippedScrollStateHandle, ClippedScrollable, + ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, Empty, + EventHandler, Expanded, Fill, Flex, MainAxisSize, OffsetPositioning, ParentAnchor, + ParentElement, ParentOffsetBounds, Radius, SavePosition, ScrollbarWidth, Shrinkable, Stack, + Text, +}; +use galaxyui::fonts::{Properties, Weight}; +use galaxyui::keymap::{ContextPredicate, EnabledPredicate, FixedBinding}; +use galaxyui::{ + id, Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, + UpdateView as _, View, ViewContext, ViewHandle, +}; use itertools::Itertools as _; use keybindings::KeybindingsView; use main_page::{MainPageAction, MainSettingsPageEvent, MainSettingsPageView}; @@ -26,27 +46,7 @@ use settings_page::{ }; use show_blocks_view::{ShowBlocksEvent, ShowBlocksView}; use teams_page::{TeamsPageView, TeamsPageViewEvent}; -use galaxy_core::channel::ChannelState; -use galaxy_core::context_flag::ContextFlag; -use galaxy_core::features::FeatureFlag; -use galaxy_core::send_telemetry_from_ctx; -use galaxy_core::settings::ToggleableSetting as _; -use galaxy_core::ui::theme::color::internal_colors; -use galaxy_editor::editor::NavigationKey; use warpify_page::{WarpifyPageAction, WarpifyPageView}; -use galaxyui::elements::{ - Align, Border, ChildAnchor, ChildView, Clipped, ClippedScrollStateHandle, ClippedScrollable, - ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, Empty, - EventHandler, Expanded, Fill, Flex, MainAxisSize, OffsetPositioning, ParentAnchor, - ParentElement, ParentOffsetBounds, Radius, SavePosition, ScrollbarWidth, Shrinkable, Stack, - Text, -}; -use galaxyui::fonts::{Properties, Weight}; -use galaxyui::keymap::{ContextPredicate, EnabledPredicate, FixedBinding}; -use galaxyui::{ - id, Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, - UpdateView as _, View, ViewContext, ViewHandle, -}; use self::telemetry::SettingsTelemetryEvent; use crate::ai::custom_model_routers::CustomModelRouter; @@ -285,12 +285,6 @@ pub enum SettingsSection { CloudEnvironments, #[allow(dead_code)] OzCloudAPIKeys, - #[allow(dead_code)] - Teams, - #[allow(dead_code)] - SharedBlocks, - #[allow(dead_code)] - Referrals, } use std::fmt::{self, Display}; @@ -410,9 +404,7 @@ impl FromStr for SettingsSection { "Editor and Code Review" | "EditorAndCodeReview" => Ok(Self::EditorAndCodeReview), "CloudEnvironments" | "Environments" => Ok(Self::CloudEnvironments), "OzCloudAPIKeys" => Ok(Self::OzCloudAPIKeys), - "Teams" => Ok(Self::Teams), "SharedBlocks" | "Shared Blocks" => Ok(Self::SharedBlocks), - "Referrals" => Ok(Self::Referrals), _ => Err(()), } } @@ -1186,12 +1178,6 @@ impl SettingsView { me.handle_ai_page_event(event, ctx); }); - // Environments page - let environments_page_handle = ctx.add_typed_action_view(EnvironmentsPageView::new); - ctx.subscribe_to_view(&environments_page_handle, |me, _, event, ctx| { - me.handle_environments_page_event(event, ctx); - }); - // Billing & Usage page (internally, this routes to the v1 or v2 version. Depending on FFs and current plan). let billing_and_usage_handle = ctx.add_view(BillingAndUsageDispatchView::new); ctx.subscribe_to_view(&billing_and_usage_handle, |me, _, event, ctx| { @@ -1220,12 +1206,6 @@ impl SettingsView { me.handle_privacy_page_event(event, ctx); }); - let referrals_client = ServerApiProvider::as_ref(ctx).get_referrals_client(); - let referrals_page_handle = - ctx.add_typed_action_view(|ctx| ReferralsPageView::new(referrals_client, ctx)); - ctx.subscribe_to_view(&referrals_page_handle, |me, _, event, ctx| { - me.handle_referrals_page_event(event, ctx); - }); let scripting_page_handle = if FeatureFlag::WarpControlCli.is_enabled() { Some(ctx.add_typed_action_view(ScriptingSettingsPageView::new)) } else { @@ -2187,12 +2167,9 @@ impl SettingsView { fn input_tab(&mut self, ctx: &mut ViewContext) { if let Some(current_page) = self.current_settings_page() { - match ¤t_page.view_handle { - SettingsPageViewHandle::Keybindings(view_handle) => { - view_handle.update(ctx, |view, ctx| view.on_tab_pressed(ctx)); - } - _ => (), - }; + if let SettingsPageViewHandle::Keybindings(view_handle) = ¤t_page.view_handle { + view_handle.update(ctx, |view, ctx| view.on_tab_pressed(ctx)); + } } } diff --git a/app/src/settings_view/platform/create_api_key_modal.rs b/app/src/settings_view/platform/create_api_key_modal.rs index 0198df12..2d23dba8 100644 --- a/app/src/settings_view/platform/create_api_key_modal.rs +++ b/app/src/settings_view/platform/create_api_key_modal.rs @@ -1,6 +1,6 @@ +#![allow(dead_code)] + use chrono::Utc; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_server_client::auth::AgentIdentity; use galaxyui::elements::{ @@ -17,6 +17,8 @@ use galaxyui::ui_components::segmented_control::{ use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::editor::{ diff --git a/app/src/settings_view/platform_page.rs b/app/src/settings_view/platform_page.rs index 2a5c26f2..cdda5bcd 100644 --- a/app/src/settings_view/platform_page.rs +++ b/app/src/settings_view/platform_page.rs @@ -1,7 +1,8 @@ +#![allow(dead_code)] + use std::collections::HashMap; use chrono::{DateTime, Utc}; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use galaxy_core::features::FeatureFlag; use galaxy_graphql::object_permissions::OwnerType; use galaxy_graphql::queries::api_keys::ApiKeyProperties as GqlApiKeyProperties; @@ -15,7 +16,10 @@ use galaxyui::fonts::{Properties, Weight}; use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; -use galaxyui::{AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle}; +use galaxyui::{ + AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, +}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use super::platform::{ CreateApiKeyModal, CreateApiKeyModalEvent, CreateApiKeyModalViewState, ExpireApiKeyButton, diff --git a/app/src/settings_view/privacy/add_regex_modal.rs b/app/src/settings_view/privacy/add_regex_modal.rs index 9b567381..65433821 100644 --- a/app/src/settings_view/privacy/add_regex_modal.rs +++ b/app/src/settings_view/privacy/add_regex_modal.rs @@ -1,4 +1,3 @@ -use regex::Regex; use galaxy_editor::editor::NavigationKey; use galaxyui::elements::{ ChildView, Container, CrossAxisAlignment, Empty, Expanded, Flex, MainAxisSize, @@ -9,6 +8,7 @@ use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use regex::Regex; use crate::appearance::Appearance; use crate::editor::{ diff --git a/app/src/settings_view/privacy_page.rs b/app/src/settings_view/privacy_page.rs index 97fdbbaf..45e48ba7 100644 --- a/app/src/settings_view/privacy_page.rs +++ b/app/src/settings_view/privacy_page.rs @@ -4,13 +4,10 @@ use std::collections::{HashMap, HashSet}; use std::sync::LazyLock; use std::time::Duration; -use pathfinder_geometry::vector::vec2f; -use regex::Regex; -use settings::Setting as _; use galaxy_core::context_flag::ContextFlag; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::elements::{ Align, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Expanded, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, @@ -28,6 +25,9 @@ use galaxyui::{ id, Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, UpdateModel, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; +use regex::Regex; +use settings::Setting as _; use super::privacy::{AddRegexModal, AddRegexModalEvent}; use super::settings_page::{ @@ -461,6 +461,7 @@ pub enum PrivacyPageAction { ShowAddRegexModal, AddRecommendedRegex(usize), SwitchSecretRedactionTab(SecretRedactionTab), + ToggleCloudConversationStorage, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -534,6 +535,16 @@ impl TypedActionView for PrivacyPageView { } PrivacyPageAction::ToggleTelemetry => self.toggle_telemetry(ctx), PrivacyPageAction::ToggleCrashReporting => self.toggle_crash_reporting(ctx), + PrivacyPageAction::ToggleCloudConversationStorage => { + let handle = PrivacySettings::handle(ctx); + ctx.update_model(&handle, |settings, ctx| { + settings.set_is_cloud_conversation_storage_enabled( + !settings.is_cloud_conversation_storage_enabled, + ctx, + ); + }); + ctx.notify(); + } PrivacyPageAction::LaunchNetworkLogging => self.launch_network_logging(ctx), PrivacyPageAction::RemoveCustomRegex(idx) => { self.queue_regex_removal(*idx, ctx); diff --git a/app/src/settings_view/referrals_page.rs b/app/src/settings_view/referrals_page.rs index 33dcb1ff..ced75a07 100644 --- a/app/src/settings_view/referrals_page.rs +++ b/app/src/settings_view/referrals_page.rs @@ -1,6 +1,15 @@ +#![allow(dead_code)] + use std::ops::Deref; use std::sync::Arc; +use galaxyui::fonts::Weight; +use galaxyui::ui_components::button::ButtonVariant; +use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; +use galaxyui::{ + AppContext, Entity, EventContext, FocusContext, SingletonEntity, TypedActionView, View, + ViewContext, ViewHandle, +}; use lazy_static::lazy_static; use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use pathfinder_color::ColorU; @@ -13,13 +22,6 @@ use warpui::elements::{ Flex, FormattedTextElement, HighlightedHyperlink, Icon, MainAxisSize, MouseStateHandle, ParentElement, Radius, Rect, Shrinkable, }; -use galaxyui::fonts::Weight; -use galaxyui::ui_components::button::ButtonVariant; -use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; -use galaxyui::{ - AppContext, Entity, EventContext, FocusContext, SingletonEntity, TypedActionView, View, - ViewContext, ViewHandle, -}; use super::settings_page::{ MatchData, PageType, SettingsPageMeta, SettingsPageViewHandle, SettingsWidget, PAGE_PADDING, diff --git a/app/src/settings_view/scripting_page.rs b/app/src/settings_view/scripting_page.rs index 9f5d26c7..86be8c7e 100644 --- a/app/src/settings_view/scripting_page.rs +++ b/app/src/settings_view/scripting_page.rs @@ -2,9 +2,9 @@ use std::cell::RefCell; use std::collections::HashMap; -use settings::Setting as _; #[cfg(target_os = "macos")] use galaxy_core::channel::ChannelState; +use settings::Setting as _; use warpui::elements::{ChildView, Element, MouseStateHandle}; #[cfg(target_os = "macos")] use warpui::ui_components::button::ButtonVariant; diff --git a/app/src/settings_view/settings_file_footer.rs b/app/src/settings_view/settings_file_footer.rs index af3eb9c1..09902bd4 100644 --- a/app/src/settings_view/settings_file_footer.rs +++ b/app/src/settings_view/settings_file_footer.rs @@ -7,7 +7,6 @@ //! `Workspace::render_settings_error_banner`) when the settings file has an //! error *and* the user has dismissed the workspace banner. //! * Otherwise, a plain bordered "Open settings file" button. -use pathfinder_color::ColorU; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -18,6 +17,7 @@ use galaxyui::elements::{ }; use galaxyui::fonts::{FamilyId, Properties, Weight}; use galaxyui::platform::Cursor; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::settings::SettingsFileError; diff --git a/app/src/settings_view/settings_page.rs b/app/src/settings_view/settings_page.rs index 595e1a0e..5b54c414 100644 --- a/app/src/settings_view/settings_page.rs +++ b/app/src/settings_view/settings_page.rs @@ -2,10 +2,6 @@ use core::fmt::{self, Display}; use std::borrow::Cow; use std::collections::HashMap; -use itertools::Itertools as _; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use settings::Setting; use galaxy_core::settings::SyncToCloud; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::color::internal_colors; @@ -25,6 +21,10 @@ use galaxyui::ui_components::button::{Button, ButtonVariant}; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::units::Pixels; use galaxyui::{Action, AppContext, SingletonEntity, ViewContext, ViewHandle}; +use itertools::Itertools as _; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use settings::Setting; use super::about_page::AboutPageView; use super::ai_page::{AISettingsPageAction, AISettingsPageView}; @@ -115,7 +115,6 @@ pub enum SettingsPageViewHandle { BillingAndUsage(ViewHandle), MCPServers(ViewHandle), WarpDrive(ViewHandle), - CloudEnvironments(ViewHandle), OzCloudAPIKeys(ViewHandle), Teams(ViewHandle), SharedBlocks(ViewHandle), diff --git a/app/src/settings_view/show_blocks_view.rs b/app/src/settings_view/show_blocks_view.rs index e39ae06f..b9a703dc 100644 --- a/app/src/settings_view/show_blocks_view.rs +++ b/app/src/settings_view/show_blocks_view.rs @@ -1,8 +1,9 @@ +#![allow(dead_code)] + use std::sync::Arc; use anyhow::Result; use chrono::{DateTime, FixedOffset, Local}; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::clipboard::ClipboardContent; use galaxyui::color::ColorU; @@ -19,6 +20,7 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use super::settings_page::{ render_page_title, MatchData, PageType, SettingsPageMeta, SettingsPageViewHandle, @@ -475,7 +477,7 @@ impl ShowBlocksView { ) { match result { Ok(mut blocks) => { - blocks.sort_by(|b1, b2| b2.time_started.cmp(&b1.time_started)); + blocks.sort_by_key(|b| std::cmp::Reverse(b.time_started)); self.get_blocks_for_user_status = GetBlocksForUserRequestState::Done(blocks) } diff --git a/app/src/settings_view/tab_menu.rs b/app/src/settings_view/tab_menu.rs index 47e5e8f7..8581b29b 100644 --- a/app/src/settings_view/tab_menu.rs +++ b/app/src/settings_view/tab_menu.rs @@ -1,7 +1,7 @@ -use galaxyui::ui_components::button::ButtonVariant; use std::fmt::Display; use galaxyui::elements::MouseStateHandle; +use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::Element; diff --git a/app/src/settings_view/teams_page.rs b/app/src/settings_view/teams_page.rs index 8b759ee9..44b4f85c 100644 --- a/app/src/settings_view/teams_page.rs +++ b/app/src/settings_view/teams_page.rs @@ -1,18 +1,13 @@ +#![allow(dead_code)] + use core::default::Default; use std::cmp::Ordering; use std::collections::HashSet; use std::sync::Arc; use email_address::EmailAddress; -use galaxy_core::ui::theme::color::internal_colors; -use galaxyui::FocusContext; -use itertools::Itertools; -use lazy_static::lazy_static; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use regex::Regex; -use serde::{Deserialize, Serialize}; use galaxy_core::features::FeatureFlag; +use galaxy_core::ui::theme::color::internal_colors; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ Align, Border, ChildAnchor, ClippedScrollStateHandle, ConstrainedBox, Container, CornerRadius, @@ -31,6 +26,12 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use itertools::Itertools; +use lazy_static::lazy_static; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use regex::Regex; +use serde::{Deserialize, Serialize}; use super::admin_actions::AdminActions; use super::settings_page::{ @@ -240,6 +241,7 @@ impl TeamsPageAction { impl From<&TeamsPageAction> for LoginGatedFeature { fn from(val: &TeamsPageAction) -> LoginGatedFeature { + use TeamsPageAction::*; match val { LeaveTeam => "Leave Team", ShowDeleteTeamConfirmationDialog => "Delete Team", diff --git a/app/src/settings_view/transfer_ownership_confirmation_modal.rs b/app/src/settings_view/transfer_ownership_confirmation_modal.rs index fbda6a87..942fb30a 100644 --- a/app/src/settings_view/transfer_ownership_confirmation_modal.rs +++ b/app/src/settings_view/transfer_ownership_confirmation_modal.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use galaxyui::elements::{ Align, Container, CrossAxisAlignment, Flex, MouseStateHandle, ParentElement, Text, }; diff --git a/app/src/settings_view/update_environment_form.rs b/app/src/settings_view/update_environment_form.rs index c0c20857..edac367a 100644 --- a/app/src/settings_view/update_environment_form.rs +++ b/app/src/settings_view/update_environment_form.rs @@ -1,9 +1,6 @@ #[cfg(not(target_family = "wasm"))] use std::collections::HashMap; -use instant::{Duration, Instant}; -use log::debug; -use url::Url; use galaxy_core::send_telemetry_from_ctx; use galaxy_editor::editor::NavigationKey; use galaxy_graphql::queries::user_github_info::UserGithubInfoResult; @@ -25,8 +22,11 @@ use galaxyui::{ AppContext, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; -#[cfg(not(target_family = "wasm"))] +use instant::{Duration, Instant}; +use log::debug; +use url::Url; +#[cfg(not(target_family = "wasm"))] use super::editor_text_colors; use super::settings_page::{render_input_list, InputListItem}; use crate::ai::ambient_agents::github_auth_notifier::{GitHubAuthEvent, GitHubAuthNotifier}; diff --git a/app/src/settings_view/update_environment_form_tests.rs b/app/src/settings_view/update_environment_form_tests.rs index 0199eac6..0d199fe2 100644 --- a/app/src/settings_view/update_environment_form_tests.rs +++ b/app/src/settings_view/update_environment_form_tests.rs @@ -1,4 +1,3 @@ -use url::Url; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{Empty, MouseStateHandle}; use galaxyui::platform::WindowStyle; @@ -6,6 +5,7 @@ use galaxyui::{ AddSingletonModel, App, AppContext, Element, Entity, SingletonEntity, TypedActionView, View, WindowId, }; +use url::Url; use super::{ EnvironmentFormCopy, EnvironmentFormInitArgs, EnvironmentFormValues, SuggestImageState, diff --git a/app/src/settings_view/warp_drive_page.rs b/app/src/settings_view/warp_drive_page.rs index 1eddff38..4ab5705c 100644 --- a/app/src/settings_view/warp_drive_page.rs +++ b/app/src/settings_view/warp_drive_page.rs @@ -1,9 +1,6 @@ use galaxy_core::features::FeatureFlag; use galaxy_core::report_if_error; use galaxy_core::settings::ToggleableSetting as _; -use warpui::elements::{ - Container, Element, Flex, MouseStateHandle, ParentElement, Shrinkable, Text, -}; use galaxyui::fonts::Weight; use galaxyui::keymap::ContextPredicate; use galaxyui::ui_components::button::ButtonVariant; @@ -12,6 +9,9 @@ use galaxyui::ui_components::switch::SwitchStateHandle; use galaxyui::{ id, Action, AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use warpui::elements::{ + Container, Element, Flex, MouseStateHandle, ParentElement, Shrinkable, Text, +}; use super::settings_page::{ render_body_item, AdditionalInfo, MatchData, PageType, SettingsPageMeta, diff --git a/app/src/settings_view/warpify_page.rs b/app/src/settings_view/warpify_page.rs index 59f561ee..7dc96a80 100644 --- a/app/src/settings_view/warpify_page.rs +++ b/app/src/settings_view/warpify_page.rs @@ -2,10 +2,6 @@ use std::cell::RefCell; use std::collections::HashMap; use std::fmt::Display; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use regex::Regex; -use settings::{Setting, ToggleableSetting}; -use strum::IntoEnumIterator; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ Container, Flex, FormattedTextElement, HighlightedHyperlink, MouseStateHandle, ParentElement, @@ -18,6 +14,10 @@ use galaxyui::{ Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use regex::Regex; +use settings::{Setting, ToggleableSetting}; +use strum::IntoEnumIterator; use super::settings_page::{ add_setting, render_alternating_color_list, render_body_item, render_dropdown_item, diff --git a/app/src/tab.rs b/app/src/tab.rs index dc7c5888..ee715a7e 100644 --- a/app/src/tab.rs +++ b/app/src/tab.rs @@ -2,10 +2,6 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use serde::{Deserialize, Serialize}; -use settings::Setting as _; use galaxy_core::context_flag::ContextFlag; use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::theme::color::internal_colors; @@ -23,6 +19,10 @@ use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::ui_components::text_input::TextInput; use galaxyui::{AppContext, SingletonEntity, ViewHandle}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use serde::{Deserialize, Serialize}; +use settings::Setting as _; use crate::ai::agent::conversation::ConversationStatus; use crate::ai::conversation_status_ui::{render_status_element, STATUS_ELEMENT_PADDING}; diff --git a/app/src/tab_configs/mod.rs b/app/src/tab_configs/mod.rs index 29464a3a..dd55ee1e 100644 --- a/app/src/tab_configs/mod.rs +++ b/app/src/tab_configs/mod.rs @@ -10,6 +10,7 @@ pub mod session_config_rendering; pub mod tab_config; pub mod telemetry; +use galaxy_core::ui::theme::Fill; pub use new_worktree_modal::{NewWorktreeModal, NewWorktreeModalEvent}; pub use params_modal::{TabConfigParamsModal, TabConfigParamsModalEvent}; #[cfg(feature = "local_fs")] @@ -17,7 +18,6 @@ pub(crate) use tab_config::build_worktree_config_toml; pub use tab_config::{ render_tab_config, TabConfig, TabConfigError, TabConfigParam, TabConfigParamType, }; -use galaxy_core::ui::theme::Fill; /// Optional visual overrides for BranchPicker / RepoPicker dropdowns. pub struct PickerStyle { diff --git a/app/src/tab_configs/remove_confirmation_dialog.rs b/app/src/tab_configs/remove_confirmation_dialog.rs index 414e61ef..c1765955 100644 --- a/app/src/tab_configs/remove_confirmation_dialog.rs +++ b/app/src/tab_configs/remove_confirmation_dialog.rs @@ -1,6 +1,5 @@ use std::path::PathBuf; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ Align, ChildAnchor, ChildView, Container, OffsetPositioning, ParentAnchor, ParentOffsetBounds, @@ -11,6 +10,7 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::ui_components::dialog::{dialog_styles, Dialog}; diff --git a/app/src/tab_configs/session_config_rendering.rs b/app/src/tab_configs/session_config_rendering.rs index 8b9d224a..3547794f 100644 --- a/app/src/tab_configs/session_config_rendering.rs +++ b/app/src/tab_configs/session_config_rendering.rs @@ -1,9 +1,7 @@ use std::path::Path; use std::sync::Arc; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::elements::{ Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Expanded, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, OffsetPositioning, @@ -14,6 +12,8 @@ use galaxyui::geometry::vector::Vector2F; use galaxyui::platform::Cursor; use galaxyui::ui_components::components::UiComponent; use galaxyui::{Element, EventContext}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::tab_configs::session_config::SessionType; diff --git a/app/src/terminal/alias.rs b/app/src/terminal/alias.rs index a27cb14e..fd86e6f6 100644 --- a/app/src/terminal/alias.rs +++ b/app/src/terminal/alias.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use smol_str::SmolStr; use galaxy_completer::parsers::simple::all_parsed_commands; +use smol_str::SmolStr; use crate::terminal::model::session::Session; diff --git a/app/src/terminal/alt_screen/alt_screen_element.rs b/app/src/terminal/alt_screen/alt_screen_element.rs index 70362d94..972de340 100644 --- a/app/src/terminal/alt_screen/alt_screen_element.rs +++ b/app/src/terminal/alt_screen/alt_screen_element.rs @@ -1,11 +1,11 @@ use std::ops::{Deref as _, Range}; use std::sync::Arc; +use galaxy_core::features::FeatureFlag; use num_traits::Float as _; use parking_lot::FairMutex; use pathfinder_geometry::vector::vec2f; use vec1::Vec1; -use galaxy_core::features::FeatureFlag; use warp_util::user_input::UserInput; use warpui::elements::new_scrollable::{NewScrollableElement, ScrollableAxis}; use warpui::elements::{Axis, Point as UiPoint, ScrollData, ScrollableElement}; @@ -960,21 +960,17 @@ impl Element for AltScreenElement { selected_range, } => self.set_marked_text(marked_text, selected_range, ctx), Event::ClearMarkedText => self.clear_marked_text(ctx), - Event::ModifierKeyChanged { key_code, state } => { - if self.is_terminal_focused { - let is_press = matches!(state, KeyState::Pressed); - if let Some(escape_sequence) = maybe_kitty_keyboard_escape_sequence( - self.model.lock().deref(), - key_code, - is_press, - ) { - ctx.dispatch_typed_action(TerminalAction::ControlSequence(escape_sequence)); - return true; - } - self.maybe_handle_voice_toggle(key_code, state, ctx) - } else { - false + Event::ModifierKeyChanged { key_code, state } if self.is_terminal_focused => { + let is_press = matches!(state, KeyState::Pressed); + if let Some(escape_sequence) = maybe_kitty_keyboard_escape_sequence( + self.model.lock().deref(), + key_code, + is_press, + ) { + ctx.dispatch_typed_action(TerminalAction::ControlSequence(escape_sequence)); + return true; } + self.maybe_handle_voice_toggle(key_code, state, ctx) } _ => false, } diff --git a/app/src/terminal/alt_screen_reporting.rs b/app/src/terminal/alt_screen_reporting.rs index f5a3da8f..3d73903a 100644 --- a/app/src/terminal/alt_screen_reporting.rs +++ b/app/src/terminal/alt_screen_reporting.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(AltScreenReporting, settings: [ mouse_reporting_enabled: MouseReportingEnabled { diff --git a/app/src/terminal/available_shells.rs b/app/src/terminal/available_shells.rs index 4e0ef709..4e4179f5 100644 --- a/app/src/terminal/available_shells.rs +++ b/app/src/terminal/available_shells.rs @@ -6,16 +6,19 @@ use std::path::Path; use std::path::PathBuf; use std::sync::Arc; +use galaxy_core::features::FeatureFlag; #[cfg(feature = "local_tty")] use galaxyui::{AppContext, ModelContext}; use galaxyui::{Entity, SingletonEntity}; #[cfg(feature = "local_tty")] use settings::Setting as _; -use super::session_settings::{NewSessionShell, StartupShell}; +use super::session_settings::{NewSessionShell, SessionSettings, StartupShell}; use super::shell::ShellType; use super::ShellLaunchData; #[cfg(feature = "local_tty")] +use crate::terminal::local_tty::shell::supported_shell_path_and_type; +#[cfg(feature = "local_tty")] use crate::util::path::file_exists_and_is_executable; #[derive(Debug, PartialEq, Eq, Hash)] @@ -621,7 +624,6 @@ impl AvailableShells { paths_to_search: &[PathBuf], fallback_path: Option<&Path>, ) -> Vec { - if !FeatureFlag::ShellSelector.is_enabled() { return vec![ StartupShell::Zsh, @@ -718,7 +720,6 @@ impl AvailableShells { fn locate_msys2_executables() -> Vec { use std::env; - let mut paths = Vec::new(); // We look for Git Bash at `$env:LocalAppData\Programs\Git\usr\bin`. @@ -856,7 +857,6 @@ impl AvailableShells { } fn get_user_preferred_shell_setting(&self, ctx: &AppContext) -> NewSessionShell { - let new_session_shell_override = SessionSettings::as_ref(ctx) .new_session_shell_override .to_owned(); @@ -872,7 +872,6 @@ impl AvailableShells { } fn get_user_preferred_shell_setting_fallback(&self, ctx: &AppContext) -> NewSessionShell { - let startup_shell = SessionSettings::as_ref(ctx) .startup_shell_override .to_owned(); diff --git a/app/src/terminal/block_filter.rs b/app/src/terminal/block_filter.rs index 5f6a814a..29075242 100644 --- a/app/src/terminal/block_filter.rs +++ b/app/src/terminal/block_filter.rs @@ -1,8 +1,5 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use regex_automata::hybrid::BuildError; use galaxy_editor::editor::NavigationKey; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ Align, Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dash, Dismiss, DropShadow, Empty, Flex, Hoverable, MouseStateHandle, @@ -15,6 +12,9 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use regex_automata::hybrid::BuildError; use super::model::find::{FindConfig, RegexDFAs}; use crate::appearance::Appearance; diff --git a/app/src/terminal/block_list_element.rs b/app/src/terminal/block_list_element.rs index 2f30a095..aa156b70 100644 --- a/app/src/terminal/block_list_element.rs +++ b/app/src/terminal/block_list_element.rs @@ -7,14 +7,9 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, MutexGuard}; use enum_iterator::Sequence; -use itertools::Itertools; -use parking_lot::FairMutex; -use pathfinder_color::ColorU; -use session_sharing_protocol::common::{ParticipantId, Selection}; -use vec1::Vec1; use galaxy_core::semantic_selection::SemanticSelection; use galaxy_core::ui::builder::UiBuilder; -use galaxy_core::ui::theme::AnsiColorIdentifier; +use galaxy_core::ui::theme::{AnsiColorIdentifier, GalaxyTheme}; use galaxy_util::user_input::UserInput; use galaxyui::elements::new_scrollable::{NewScrollableElement, ScrollableAxis}; use galaxyui::elements::{ @@ -36,6 +31,11 @@ use galaxyui::{ AfterLayoutContext, AppContext, ClipBounds, Element, EntityId, Event, EventContext, LayoutContext, ModelHandle, PaintContext, SingletonEntity as _, SizeConstraint, }; +use itertools::Itertools; +use parking_lot::FairMutex; +use pathfinder_color::ColorU; +use session_sharing_protocol::common::{ParticipantId, Selection}; +use vec1::Vec1; use super::block_list_viewport::{ClampingMode, InputMode, ScrollPosition, ViewportState}; use super::blockgrid_renderer::GridRenderParams; @@ -1936,9 +1936,7 @@ impl BlockListElement { ctx: &mut EventContext, app: &AppContext, ) -> bool { - if self.is_terminal_selecting && self.bounds.is_some() { - let bounds = self.bounds.unwrap(); - + if let (true, Some(bounds)) = (self.is_terminal_selecting, self.bounds) { let snackbar_height = self .snackbar_header_state() .header_rect() @@ -3069,7 +3067,6 @@ impl BlockListElement { state: &KeyState, ctx: &mut EventContext, ) -> bool { - if let Some(voice_input_toggle_key_code) = self.voice_input_toggle_key_code { if *key_code == voice_input_toggle_key_code { ctx.dispatch_typed_action(TerminalAction::ToggleCLIAgentVoiceInput( @@ -4611,21 +4608,17 @@ impl Element for BlockListElement { selected_range, } => self.set_marked_text(marked_text, selected_range, ctx), Event::ClearMarkedText => self.clear_marked_text(ctx), - Event::ModifierKeyChanged { key_code, state } => { - if self.is_terminal_focused { - let is_press = matches!(state, KeyState::Pressed); - if let Some(escape_sequence) = maybe_kitty_keyboard_escape_sequence( - self.model.lock().deref(), - key_code, - is_press, - ) { - ctx.dispatch_typed_action(TerminalAction::ControlSequence(escape_sequence)); - return true; - } - self.maybe_handle_voice_toggle(key_code, state, ctx) - } else { - false + Event::ModifierKeyChanged { key_code, state } if self.is_terminal_focused => { + let is_press = matches!(state, KeyState::Pressed); + if let Some(escape_sequence) = maybe_kitty_keyboard_escape_sequence( + self.model.lock().deref(), + key_code, + is_press, + ) { + ctx.dispatch_typed_action(TerminalAction::ControlSequence(escape_sequence)); + return true; } + self.maybe_handle_voice_toggle(key_code, state, ctx) } _ => false, }; diff --git a/app/src/terminal/block_list_settings.rs b/app/src/terminal/block_list_settings.rs index 7f994c66..6426dbbd 100644 --- a/app/src/terminal/block_list_settings.rs +++ b/app/src/terminal/block_list_settings.rs @@ -1,5 +1,5 @@ use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; // Settings for controlling the behavior of the block list. define_settings_group!(BlockListSettings, settings: [ diff --git a/app/src/terminal/block_list_viewport.rs b/app/src/terminal/block_list_viewport.rs index d267f6e2..3f623a6d 100644 --- a/app/src/terminal/block_list_viewport.rs +++ b/app/src/terminal/block_list_viewport.rs @@ -2,13 +2,13 @@ use std::ops::Range; use std::rc::Rc; use std::sync::MutexGuard; -use pathfinder_geometry::vector::Vector2F; -use serde::{Deserialize, Serialize}; -use sum_tree::{Cursor, SeekBias}; use galaxy_core::features::FeatureFlag; use galaxyui::elements::ClippedScrollStateHandle; use galaxyui::units::{IntoLines, IntoPixels, Lines, Pixels}; use galaxyui::{AppContext, ModelHandle}; +use pathfinder_geometry::vector::Vector2F; +use serde::{Deserialize, Serialize}; +use sum_tree::{Cursor, SeekBias}; use super::block_list_element::{ GridType, SnackbarHeader, SnackbarHeaderState, SnackbarPoint, VisibleItem, diff --git a/app/src/terminal/blockgrid_element.rs b/app/src/terminal/blockgrid_element.rs index 34a6b52f..20fcbb7b 100644 --- a/app/src/terminal/blockgrid_element.rs +++ b/app/src/terminal/blockgrid_element.rs @@ -1,10 +1,10 @@ -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxyui::elements::{ AfterLayoutContext, AppContext, Element, EventContext, LayoutContext, PaintContext, Point, SizeConstraint, }; use galaxyui::event::DispatchedEvent; use galaxyui::geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::blockgrid_renderer::GridRenderParams; use crate::appearance::Appearance; diff --git a/app/src/terminal/blockgrid_renderer.rs b/app/src/terminal/blockgrid_renderer.rs index 0fa99d57..8dc016a6 100644 --- a/app/src/terminal/blockgrid_renderer.rs +++ b/app/src/terminal/blockgrid_renderer.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; use std::ops::{Neg, RangeInclusive}; -use pathfinder_color::ColorU; use galaxyui::fonts::{FamilyId, Properties, Weight}; use galaxyui::geometry::rect::RectF; use galaxyui::geometry::vector::{vec2f, Vector2F}; use galaxyui::{AppContext, Element, EntityId, PaintContext}; +use pathfinder_color::ColorU; use super::model::ansi::{CursorShape, CursorStyle}; use super::model::grid::RespectDisplayedOutput; @@ -18,7 +18,7 @@ use crate::terminal::model::grid::grid_handler::Link; use crate::terminal::model::index::Point; use crate::terminal::model::ObfuscateSecrets; use crate::terminal::{color, SizeInfo}; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; pub struct GridRenderParams { pub warp_theme: GalaxyTheme, diff --git a/app/src/terminal/bootstrap.rs b/app/src/terminal/bootstrap.rs index 4211295a..d731f319 100644 --- a/app/src/terminal/bootstrap.rs +++ b/app/src/terminal/bootstrap.rs @@ -1,11 +1,11 @@ use std::borrow::Cow; +use galaxy_core::session_id::SessionId; use galaxyui::{AppContext, AssetProvider, SingletonEntity}; use itertools::Itertools; use lazy_static::lazy_static; use memo_map::MemoMap; use rand::Rng; -use galaxy_core::session_id::SessionId; #[cfg(feature = "local_fs")] use super::{ diff --git a/app/src/terminal/buy_credits_banner.rs b/app/src/terminal/buy_credits_banner.rs index bbe460e9..4e4928c2 100644 --- a/app/src/terminal/buy_credits_banner.rs +++ b/app/src/terminal/buy_credits_banner.rs @@ -1,10 +1,6 @@ use std::sync::Arc; use enclose::enclose; -use itertools::Itertools as _; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::Icon; use galaxy_graphql::billing::AddonCreditsOption; @@ -20,6 +16,10 @@ use galaxyui::fonts::Weight; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent as _, UiComponentStyles}; use galaxyui::{AppContext, Element, Entity, SingletonEntity as _, View, ViewContext, ViewHandle}; +use itertools::Itertools as _; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::ai::request_usage_model::{ AIRequestUsageModel, AIRequestUsageModelEvent, BuyCreditsBannerDisplayState, @@ -213,14 +213,14 @@ impl BuyCreditsBanner { ctx.notify(); } } - UserWorkspacesEvent::UpdateWorkspaceSettingsRejected(_) => { - if self.banner_auto_reload_update_in_flight { - self.banner_auto_reload_update_in_flight = false; - ctx.emit(BuyCreditsBannerEvent::ShowAutoReloadError { - error_message: "Failed to enable auto-reload for your team. Please try again in Settings > Billing and Usage.", - }); - ctx.notify(); - } + UserWorkspacesEvent::UpdateWorkspaceSettingsRejected(_) + if self.banner_auto_reload_update_in_flight => + { + self.banner_auto_reload_update_in_flight = false; + ctx.emit(BuyCreditsBannerEvent::ShowAutoReloadError { + error_message: "Failed to enable auto-reload for your team. Please try again in Settings > Billing and Usage.", + }); + ctx.notify(); } _ => {} } diff --git a/app/src/terminal/cli_agent.rs b/app/src/terminal/cli_agent.rs index 59e0deb0..94ea55f5 100644 --- a/app/src/terminal/cli_agent.rs +++ b/app/src/terminal/cli_agent.rs @@ -8,17 +8,16 @@ use std::collections::HashMap; use ai::skills::SkillProvider; use enum_iterator::Sequence; -use galaxy_editor::content::{buffer::Buffer, markdown::MarkdownStyle}; -use markdown_parser::parse_markdown; -use pathfinder_color::ColorU; -use serde::{Deserialize, Serialize}; -use smol_str::SmolStr; use galaxy_cli::agent::Harness; use galaxy_completer::parsers::simple::top_level_command; use galaxy_editor::content::buffer::Buffer; use galaxy_editor::content::markdown::MarkdownStyle; use galaxy_util::path::EscapeChar; use galaxyui::{AppContext, SingletonEntity}; +use markdown_parser::parse_markdown; +use pathfinder_color::ColorU; +use serde::{Deserialize, Serialize}; +use smol_str::SmolStr; use crate::ai::agent::{AgentReviewCommentBatch, DiffSetHunk}; use crate::ai::blocklist::CLAUDE_ORANGE; diff --git a/app/src/terminal/color.rs b/app/src/terminal/color.rs index e4c35c56..2055d345 100644 --- a/app/src/terminal/color.rs +++ b/app/src/terminal/color.rs @@ -4,7 +4,7 @@ use std::ops::{Index, IndexMut}; use galaxyui::color::ColorU; use crate::terminal::model::ansi::color_index; -use crate::themes::theme::{AnsiColors, WarpTheme}; +use crate::themes::theme::{AnsiColors, GalaxyTheme}; pub const COUNT: usize = 269; diff --git a/app/src/terminal/enable_auto_reload_modal.rs b/app/src/terminal/enable_auto_reload_modal.rs index 1e51686a..8a706f6d 100644 --- a/app/src/terminal/enable_auto_reload_modal.rs +++ b/app/src/terminal/enable_auto_reload_modal.rs @@ -105,15 +105,15 @@ impl EnableAutoReloadModalBody { ctx.emit(EnableAutoReloadModalBodyEvent::Close); } } - UserWorkspacesEvent::UpdateWorkspaceSettingsRejected(_err) => { - if me.update_workspace_settings_loading { - me.update_workspace_settings_loading = false; - ctx.emit(EnableAutoReloadModalBodyEvent::ShowToast { - message: "Failed to enable auto-reload. Please try updating your settings in Billing & usage.".to_string(), - flavor: ToastFlavor::Error, - }); - ctx.notify(); - } + UserWorkspacesEvent::UpdateWorkspaceSettingsRejected(_err) + if me.update_workspace_settings_loading => + { + me.update_workspace_settings_loading = false; + ctx.emit(EnableAutoReloadModalBodyEvent::ShowToast { + message: "Failed to enable auto-reload. Please try updating your settings in Billing & usage.".to_string(), + flavor: ToastFlavor::Error, + }); + ctx.notify(); } _ => {} } diff --git a/app/src/terminal/find/model.rs b/app/src/terminal/find/model.rs index 600477bf..4700fe04 100644 --- a/app/src/terminal/find/model.rs +++ b/app/src/terminal/find/model.rs @@ -14,6 +14,7 @@ use alt_screen::{run_find_on_alt_screen, AltScreenFindRun}; pub use async_find::{AsyncFindController, AsyncFindStatus}; use block_list::run_find_on_block_list; pub use block_list::{BlockGridMatch, BlockListFindRun, BlockListMatch}; +use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity, ViewHandle}; use parking_lot::FairMutex; use rich_content::FindableRichContentHandle; pub use rich_content::{FindableRichContentView, RichContentMatchId}; diff --git a/app/src/terminal/find/model/async_find.rs b/app/src/terminal/find/model/async_find.rs index 4db0caf2..a94b7cb9 100644 --- a/app/src/terminal/find/model/async_find.rs +++ b/app/src/terminal/find/model/async_find.rs @@ -586,7 +586,7 @@ impl AsyncFindController { // Sort by TotalIndex descending so that matches closest to the end // of the blocklist (newest blocks, near the prompt) come first. - ordered_blocks.sort_by(|a, b| b.0.cmp(&a.0)); + ordered_blocks.sort_by_key(|b| std::cmp::Reverse(b.0)); let reverse_within_block = matches!( self.block_sort_direction, diff --git a/app/src/terminal/find/model/block_list.rs b/app/src/terminal/find/model/block_list.rs index c432939e..aa36d409 100644 --- a/app/src/terminal/find/model/block_list.rs +++ b/app/src/terminal/find/model/block_list.rs @@ -3,10 +3,9 @@ use std::collections::HashMap; use std::iter; use std::ops::RangeInclusive; -use galaxyui::{units::Lines, AppContext, EntityId}; -use itertools::Itertools; use galaxyui::units::Lines; use galaxyui::{AppContext, EntityId}; +use itertools::Itertools; use super::rich_content::{FindableRichContentHandle, RichContentMatchId}; use super::FindOptions; diff --git a/app/src/terminal/general_settings.rs b/app/src/terminal/general_settings.rs index f9412ee9..1763e919 100644 --- a/app/src/terminal/general_settings.rs +++ b/app/src/terminal/general_settings.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use galaxy_core::settings::macros::define_settings_group; -use galaxy_core::settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use galaxy_core::settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use crate::banner::BannerState; use crate::resource_center::Tip; diff --git a/app/src/terminal/grid_renderer.rs b/app/src/terminal/grid_renderer.rs index 798b59e4..d6235532 100644 --- a/app/src/terminal/grid_renderer.rs +++ b/app/src/terminal/grid_renderer.rs @@ -6,8 +6,20 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::ops::{Range, RangeInclusive}; +use galaxy_core::features::FeatureFlag; +use galaxyui::assets::asset_cache::{AssetCache, AssetSource, AssetState}; +use galaxyui::elements::{Border, CornerRadius, Fill, Radius, DEFAULT_UI_LINE_HEIGHT_RATIO}; +use galaxyui::fonts::{FamilyId, FontId, Properties, Style, Weight}; +use galaxyui::image_cache::{AnimatedImageBehavior, CacheOption, FitType, Image, ImageCache}; +use galaxyui::platform::LineStyle; +use galaxyui::text_layout::{Line, StyleAndFont, TextStyle, DEFAULT_TOP_BOTTOM_RATIO}; +use galaxyui::units::{IntoLines, Lines, Pixels}; +use galaxyui::{AppContext, Element, EntityId, PaintContext, Scene, SingletonEntity}; use lazy_static::lazy_static; use num_traits::Float as _; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use unicode_width::UnicodeWidthChar; pub use self::cell_glyph_cache::CellGlyphCache; @@ -28,7 +40,7 @@ use crate::terminal::model::index::Point; use crate::terminal::model::selection::SelectionPoint; use crate::terminal::model::{ObfuscateSecrets, SecretHandle}; use crate::terminal::{color, SizeInfo}; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::util::color::{ContrastingColor, MinimumAllowedContrast}; // The scale factor of the cursor relative to the cursor width. diff --git a/app/src/terminal/grid_size_util.rs b/app/src/terminal/grid_size_util.rs index 104b0012..f257fe01 100644 --- a/app/src/terminal/grid_size_util.rs +++ b/app/src/terminal/grid_size_util.rs @@ -1,12 +1,10 @@ //! This module defines helper functions pertaining to the size/position of items in a Grid, //! such as the dimensions of a grid cell and the baseline position of text within a cell. use galaxyui::elements::DEFAULT_UI_LINE_HEIGHT_RATIO; -use galaxyui::fonts::Cache as FontCache; -use galaxyui::fonts::FamilyId; +use galaxyui::fonts::{Cache as FontCache, FamilyId}; use galaxyui::text_layout::ComputeBaselinePositionFn; use num_traits::Zero; use pathfinder_geometry::vector::{vec2f, Vector2F}; -use galaxyui::fonts::{Cache as FontCache, FamilyId}; /// Computes the grid cell size given the font and size at which the grid should /// be rendered. We use a similar algorithm to Alacritty to do this, where the diff --git a/app/src/terminal/history.rs b/app/src/terminal/history.rs index 69692ae2..a953e713 100644 --- a/app/src/terminal/history.rs +++ b/app/src/terminal/history.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use chrono::{DateTime, Local, TimeZone as _}; use futures::Future; -use serde::{Deserialize, Serialize}; use galaxy_core::command::ExitCode; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; +use serde::{Deserialize, Serialize}; use super::model::block::{AgentInteractionMetadata, Block, SerializedAIMetadata, SerializedBlock}; use super::shell::ShellType; diff --git a/app/src/terminal/input.rs b/app/src/terminal/input.rs index 866fa505..f501577c 100644 --- a/app/src/terminal/input.rs +++ b/app/src/terminal/input.rs @@ -44,6 +44,11 @@ use base64::Engine as _; use diesel::SqliteConnection; use futures::stream::AbortHandle; use futures::FutureExt as _; +use galaxy_core::context_flag::ContextFlag; +use galaxy_core::r#async::debounce; +use galaxy_core::ui::theme::color::internal_colors; +use galaxy_core::ui::theme::AnsiColorIdentifier; +use galaxy_core::user_preferences::GetUserPreferences as _; use itertools::Itertools; use lazy_static::lazy_static; use ordered_float::Float; @@ -68,14 +73,9 @@ use warp_completer::parsers::simple::command_at_cursor_position; use warp_completer::parsers::LiteCommand; use warp_completer::signatures::CommandRegistry; use warp_completer::util::parse_current_commands_and_tokens; -use galaxy_core::context_flag::ContextFlag; -use galaxy_core::r#async::debounce; -use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::AnsiColorIdentifier; -use galaxy_core::user_preferences::GetUserPreferences as _; use warp_editor::editor::NavigationKey; use warp_util::path::ShellFamily; -use warpui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use warpui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use warpui::clipboard::{ClipboardContent, ImageData}; use warpui::clipboard_utils::CLIPBOARD_IMAGE_MIME_TYPES; use warpui::color::ColorU; @@ -312,7 +312,7 @@ use crate::terminal::view::CodeDiffAction; use crate::terminal::CLIAgent; use crate::ui_components::blended_colors; use crate::ui_components::icons::Icon; -use crate::user_config::WarpConfig; +use crate::user_config::GalaxyConfig; use crate::util::bindings::{self, keybinding_name_to_normalized_string, CustomAction}; #[cfg(feature = "local_fs")] use crate::util::file::external_editor; @@ -4267,7 +4267,6 @@ impl Input { #[cfg(all(feature = "local_fs", not(target_family = "wasm")))] fn maybe_launch_cloud_handoff_request(&mut self, ctx: &mut ViewContext) -> bool { - if !FeatureFlag::OzHandoff.is_enabled() || !FeatureFlag::HandoffLocalCloud.is_enabled() || !cfg!(all(feature = "local_fs", not(target_family = "wasm"))) @@ -8060,7 +8059,7 @@ impl Input { .iter() .map(|style_run| style_run.byte_range().clone()) .collect::>(); - ranges.sort_by(|a, b| a.start.cmp(&b.start)); + ranges.sort_by_key(|a| a.start); let capacity = ranges.len(); diff --git a/app/src/terminal/input/agent.rs b/app/src/terminal/input/agent.rs index d35b3ef6..a91b9acd 100644 --- a/app/src/terminal/input/agent.rs +++ b/app/src/terminal/input/agent.rs @@ -5,10 +5,11 @@ use galaxyui::elements::{ Align, AnchorPair, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, DropTarget, Element, Empty, EventHandler, Expanded, Flex, Hoverable, MainAxisSize, OffsetPositioning, OffsetType, ParentElement, PositionedElementOffsetBounds, - PositioningAxis, Radius, SavePosition, Stack, XAxisAnchor, YAxisAnchor, + PositioningAxis, Radius, SavePosition, Stack, Text, XAxisAnchor, YAxisAnchor, }; use galaxyui::presenter::ChildView; use galaxyui::{AppContext, SingletonEntity as _}; +use pathfinder_color::ColorU; use super::common::{ add_command_xray_overlay, add_input_suggestions_overlays, add_voltron_overlay, diff --git a/app/src/terminal/input/classic.rs b/app/src/terminal/input/classic.rs index a60178a2..c295e0a4 100644 --- a/app/src/terminal/input/classic.rs +++ b/app/src/terminal/input/classic.rs @@ -1,11 +1,11 @@ -use pathfinder_geometry::vector::vec2f; -use settings::Setting; use galaxyui::elements::{ Border, ChildAnchor, ChildView, Clipped, Container, DropTarget, Element, Empty, Flex, Hoverable, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, SavePosition, Stack, }; use galaxyui::{AppContext, SingletonEntity}; +use pathfinder_geometry::vector::vec2f; +use settings::Setting; use super::{should_render_prompt_using_editor_decorator_elements, Input, SubshellRenderState}; use crate::ai::blocklist::InputType; diff --git a/app/src/terminal/input/cloud_mode_v2_history_menu.rs b/app/src/terminal/input/cloud_mode_v2_history_menu.rs index dc4f5145..5c07b8ea 100644 --- a/app/src/terminal/input/cloud_mode_v2_history_menu.rs +++ b/app/src/terminal/input/cloud_mode_v2_history_menu.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ @@ -10,6 +9,7 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use crate::ai::blocklist::agent_view::AgentViewController; use crate::search::data_source::{Query, QueryFilter}; diff --git a/app/src/terminal/input/common.rs b/app/src/terminal/input/common.rs index 7f59274c..305e9e2d 100644 --- a/app/src/terminal/input/common.rs +++ b/app/src/terminal/input/common.rs @@ -1,7 +1,5 @@ use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; -use vim::vim::{VimMode, VimState}; use galaxy_completer::completer::Description; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ @@ -14,6 +12,8 @@ use galaxyui::fonts::Weight; use galaxyui::presenter::ChildView; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, EntityId, SingletonEntity, ViewHandle}; +use pathfinder_geometry::vector::vec2f; +use vim::vim::{VimMode, VimState}; use crate::ai::llms::{is_using_api_key_for_provider, LLMPreferences}; use crate::ai::{AIRequestUsageModel, BuyCreditsBannerDisplayState}; @@ -517,7 +517,6 @@ fn add_buy_credits_banner_overlay( buy_credits_banner: &ViewHandle, is_input_at_top: bool, ) { - let (parent_anchor, child_anchor, y_offset) = if is_input_at_top { (ParentAnchor::BottomLeft, ChildAnchor::TopLeft, 8.) } else { diff --git a/app/src/terminal/input/conversations/data_source.rs b/app/src/terminal/input/conversations/data_source.rs index 4a096c3e..141883c7 100644 --- a/app/src/terminal/input/conversations/data_source.rs +++ b/app/src/terminal/input/conversations/data_source.rs @@ -1,9 +1,8 @@ //! Data source for the inline conversation menu. -use galaxyui::{AppContext, Entity, ModelHandle}; +use galaxyui::{AppContext, Entity, ModelHandle, SingletonEntity}; use itertools::Itertools; use ordered_float::OrderedFloat; -use galaxyui::{AppContext, Entity, ModelHandle, SingletonEntity}; use crate::ai::agent_conversations_model::{ AgentConversationEntry, AgentConversationEntryId, AgentManagementFilters, diff --git a/app/src/terminal/input/conversations/mod.rs b/app/src/terminal/input/conversations/mod.rs index 2558e600..7bfe8175 100644 --- a/app/src/terminal/input/conversations/mod.rs +++ b/app/src/terminal/input/conversations/mod.rs @@ -4,11 +4,11 @@ mod data_source; mod search_item; mod view; -use pathfinder_color::ColorU; -pub use view::{InlineConversationMenuEvent, InlineConversationMenuView}; use galaxy_core::ui::appearance::Appearance; use galaxyui::keymap::Keystroke; use galaxyui::SingletonEntity; +use pathfinder_color::ColorU; +pub use view::{InlineConversationMenuEvent, InlineConversationMenuView}; use crate::ai::active_agent_views_model::{ActiveAgentViewsModel, ConversationOrTaskId}; use crate::ai::agent_conversations_model::AgentConversationEntryId; diff --git a/app/src/terminal/input/decorations.rs b/app/src/terminal/input/decorations.rs index ae6453ec..6ea95925 100644 --- a/app/src/terminal/input/decorations.rs +++ b/app/src/terminal/input/decorations.rs @@ -4,13 +4,13 @@ use std::collections::HashMap; use std::ops::Range; +pub use galaxy_completer::completer::SuggestionTypeName; +pub use galaxy_completer::util::parse_current_commands_and_tokens; +pub use galaxy_completer::{ParsedTokenData, ParsedTokensSnapshot}; use galaxy_core::features::FeatureFlag; use galaxyui::{AppContext, SingletonEntity, ViewContext}; use settings::Setting as _; use string_offset::{ByteOffset, CharOffset}; -pub use galaxy_completer::completer::SuggestionTypeName; -pub use galaxy_completer::util::parse_current_commands_and_tokens; -pub use galaxy_completer::{ParsedTokenData, ParsedTokensSnapshot}; use super::Input; use crate::appearance::Appearance; diff --git a/app/src/terminal/input/inline_history/data_source.rs b/app/src/terminal/input/inline_history/data_source.rs index 5be2a70b..8d23a49c 100644 --- a/app/src/terminal/input/inline_history/data_source.rs +++ b/app/src/terminal/input/inline_history/data_source.rs @@ -234,7 +234,7 @@ fn interleave_conversations(base: Vec, conversations: Vec) let base_current = base.into_iter().skip(current_start_idx).collect::>(); let mut conversations = conversations; - conversations.sort_by(|a, b| a.sort_timestamp.cmp(&b.sort_timestamp)); + conversations.sort_by_key(|a| a.sort_timestamp); let mut i = 0; for conv in conversations { diff --git a/app/src/terminal/input/inline_menu/model.rs b/app/src/terminal/input/inline_menu/model.rs index e2f884e7..ef6f10e8 100644 --- a/app/src/terminal/input/inline_menu/model.rs +++ b/app/src/terminal/input/inline_menu/model.rs @@ -1,8 +1,8 @@ //! Generic model for tracking the selected item in an inline menu. -use galaxyui::elements::MouseStateHandle; -use galaxyui::{Entity, ModelContext}; use std::collections::HashSet; +use galaxyui::elements::MouseStateHandle; +use galaxyui::{Entity, ModelContext}; use crate::search::data_source::QueryFilter; use crate::terminal::input::inline_menu::view::InlineMenuAction; diff --git a/app/src/terminal/input/inline_menu/positioning.rs b/app/src/terminal/input/inline_menu/positioning.rs index 5c456fa2..4b2b044d 100644 --- a/app/src/terminal/input/inline_menu/positioning.rs +++ b/app/src/terminal/input/inline_menu/positioning.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxyui::units::{IntoPixels, Pixels}; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity, WindowId}; +use settings::Setting as _; use super::styles::{HEADER_BORDER, HEADER_ROW_HEIGHT}; use crate::ai::blocklist::agent_view::AgentViewController; diff --git a/app/src/terminal/input/inline_menu/view.rs b/app/src/terminal/input/inline_menu/view.rs index cece3b9c..7e44dd44 100644 --- a/app/src/terminal/input/inline_menu/view.rs +++ b/app/src/terminal/input/inline_menu/view.rs @@ -1,8 +1,6 @@ //! Generic inline menu view for rendering search results with selection and navigation. use std::sync::LazyLock; -use itertools::Itertools; -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::blend::Blend; @@ -30,6 +28,8 @@ use galaxyui::{ Action, AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use itertools::Itertools; +use pathfinder_geometry::vector::vec2f; use crate::ai::blocklist::agent_view::{ agent_view_bg_color, AgentViewController, AgentViewControllerEvent, diff --git a/app/src/terminal/input/message_bar/common.rs b/app/src/terminal/input/message_bar/common.rs index a877d0f6..5ae187b0 100644 --- a/app/src/terminal/input/message_bar/common.rs +++ b/app/src/terminal/input/message_bar/common.rs @@ -1,5 +1,3 @@ -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxy_core::ui::Icon; @@ -11,6 +9,8 @@ use galaxyui::platform::Cursor; use galaxyui::prelude::{Align, ConstrainedBox, CrossAxisAlignment, Flex, MainAxisSize, Text}; use galaxyui::ui_components::keyboard_shortcut::keystroke_to_keys; use galaxyui::{AppContext, SingletonEntity}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; use crate::ai::blocklist::agent_view::agent_view_bg_color; use crate::ai::blocklist::agent_view::shortcuts::render_keystroke_with_color_overrides; @@ -516,7 +516,11 @@ pub fn disableable_message_item_color_overrides( } pub mod styles { + use galaxy_core::ui::appearance::Appearance; + use galaxyui::{AppContext, SingletonEntity}; + use pathfinder_color::ColorU; + use crate::ui_components::blended_colors; pub fn font_size(app: &AppContext) -> f32 { let appearance = Appearance::as_ref(app); diff --git a/app/src/terminal/input/models/data_source.rs b/app/src/terminal/input/models/data_source.rs index 2bc6f70a..09ff1fc7 100644 --- a/app/src/terminal/input/models/data_source.rs +++ b/app/src/terminal/input/models/data_source.rs @@ -4,8 +4,8 @@ use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ - ConstrainedBox, Container, CornerRadius, FormattedTextElement, Highlight, HighlightedHyperlink, - MouseStateHandle, Radius, Text, + ConstrainedBox, Container, CornerRadius, Flex, FormattedTextElement, Highlight, + HighlightedHyperlink, MouseStateHandle, ParentElement, Radius, Text, }; use galaxyui::fonts::{Properties, Style, Weight}; use galaxyui::keymap::Keystroke; @@ -14,6 +14,9 @@ use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity as _}; +use itertools::Itertools; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use ordered_float::OrderedFloat; use super::model_spec_scores::{ render_model_spec_header, render_model_spec_scores, CostRow, CostRowTooltip, @@ -504,7 +507,6 @@ impl SearchItem for ModelSearchItem { } fn render_details(&self, app: &AppContext) -> Option> { - let appearance = crate::appearance::Appearance::as_ref(app); let theme = appearance.theme(); diff --git a/app/src/terminal/input/models/model_spec_scores.rs b/app/src/terminal/input/models/model_spec_scores.rs index 02bbda4a..1f654270 100644 --- a/app/src/terminal/input/models/model_spec_scores.rs +++ b/app/src/terminal/input/models/model_spec_scores.rs @@ -1,5 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, Expanded, Flex, Hoverable, @@ -10,6 +8,8 @@ use galaxyui::prelude::{Align, CrossAxisAlignment}; use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::components::UiComponent; use galaxyui::{AppContext, Element, SingletonEntity as _}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::ai::llms::LLMSpec; use crate::appearance::Appearance; diff --git a/app/src/terminal/input/models/view.rs b/app/src/terminal/input/models/view.rs index 1dd17ea4..a19ce632 100644 --- a/app/src/terminal/input/models/view.rs +++ b/app/src/terminal/input/models/view.rs @@ -2,7 +2,6 @@ use std::collections::HashSet; use std::sync::LazyLock; use ai::api_keys::{ApiKeyManager, ApiKeyManagerEvent}; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; @@ -11,6 +10,7 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity as _, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use crate::ai::blocklist::agent_view::AgentViewController; use crate::ai::blocklist::block::cli_controller::{CLISubagentController, CLISubagentEvent}; diff --git a/app/src/terminal/input/plans/mod.rs b/app/src/terminal/input/plans/mod.rs index 502ec2c7..e8ee1098 100644 --- a/app/src/terminal/input/plans/mod.rs +++ b/app/src/terminal/input/plans/mod.rs @@ -4,8 +4,8 @@ mod search_item; mod view; use ai::document::AIDocumentId; -pub use view::{InlinePlanMenuEvent, InlinePlanMenuView}; use galaxyui::keymap::Keystroke; +pub use view::{InlinePlanMenuEvent, InlinePlanMenuView}; use crate::ai::document::ai_document_model::AIDocumentVersion; use crate::terminal::input::inline_menu::{ diff --git a/app/src/terminal/input/profiles/data_source.rs b/app/src/terminal/input/profiles/data_source.rs index d4030163..ffe6cce8 100644 --- a/app/src/terminal/input/profiles/data_source.rs +++ b/app/src/terminal/input/profiles/data_source.rs @@ -68,7 +68,7 @@ impl SyncDataSource for ProfileSelectorDataSource { Some((profile_id, profile_name)) }) .collect(); - profiles.sort_by(|(_, a), (_, b)| a.to_lowercase().cmp(&b.to_lowercase())); + profiles.sort_by_key(|(_, a)| a.to_lowercase()); for (profile_id, profile_name) in profiles { if query_text.is_empty() { diff --git a/app/src/terminal/input/repos/mod.rs b/app/src/terminal/input/repos/mod.rs index 1764e7fc..653dc33e 100644 --- a/app/src/terminal/input/repos/mod.rs +++ b/app/src/terminal/input/repos/mod.rs @@ -6,8 +6,8 @@ mod view; use std::path::PathBuf; -pub use view::{InlineReposMenuEvent, InlineReposMenuView}; use galaxyui::keymap::Keystroke; +pub use view::{InlineReposMenuEvent, InlineReposMenuView}; use crate::terminal::input::inline_menu::{ default_navigation_message_items, InlineMenuAction, InlineMenuMessageArgs, InlineMenuRowAction, diff --git a/app/src/terminal/input/rewind/mod.rs b/app/src/terminal/input/rewind/mod.rs index 7ea47f71..7e949df2 100644 --- a/app/src/terminal/input/rewind/mod.rs +++ b/app/src/terminal/input/rewind/mod.rs @@ -6,9 +6,8 @@ mod search_item; mod view; pub use data_source::SelectRewindPoint; -pub use view::{RewindMenuEvent, RewindMenuView}; - use galaxyui::keymap::Keystroke; +pub use view::{RewindMenuEvent, RewindMenuView}; use crate::terminal::input::inline_menu::{ default_navigation_message_items, InlineMenuAction, InlineMenuMessageArgs, InlineMenuType, diff --git a/app/src/terminal/input/skills/data_source.rs b/app/src/terminal/input/skills/data_source.rs index 6cd936f3..21052af8 100644 --- a/app/src/terminal/input/skills/data_source.rs +++ b/app/src/terminal/input/skills/data_source.rs @@ -1,6 +1,5 @@ use ai::skills::{SkillProvider, SkillReference, SkillScope}; use fuzzy_match::{match_indices_case_insensitive, FuzzyMatchResult}; -use ordered_float::OrderedFloat; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::Fill; use galaxy_util::local_or_remote_path::LocalOrRemotePath; @@ -14,6 +13,7 @@ use galaxyui::text_layout::ClipConfig; use galaxyui::{ AppContext, Element, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity as _, }; +use ordered_float::OrderedFloat; use crate::ai::skills::SkillManager; use crate::appearance::Appearance; diff --git a/app/src/terminal/input/slash_commands/cloud_mode_v2_view.rs b/app/src/terminal/input/slash_commands/cloud_mode_v2_view.rs index 466398ce..77a82fbc 100644 --- a/app/src/terminal/input/slash_commands/cloud_mode_v2_view.rs +++ b/app/src/terminal/input/slash_commands/cloud_mode_v2_view.rs @@ -1,9 +1,9 @@ use std::collections::{HashMap, HashSet}; use std::sync::LazyLock; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; +use pathfinder_geometry::vector::vec2f; use warpui::elements::{ Border, ChildAnchor, Clipped, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, DropShadow, EventHandler, diff --git a/app/src/terminal/input/slash_commands/data_source/mod.rs b/app/src/terminal/input/slash_commands/data_source/mod.rs index ce6873a3..14da8b4c 100644 --- a/app/src/terminal/input/slash_commands/data_source/mod.rs +++ b/app/src/terminal/input/slash_commands/data_source/mod.rs @@ -6,15 +6,15 @@ use std::path::PathBuf; use ai::skills::SkillProvider; use fuzzy_match::FuzzyMatchResult; +#[cfg(not(target_family = "wasm"))] +use galaxy_cli::agent::Harness; +use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; +use galaxy_core::ui::Icon as GalaxyIcon; use galaxyui::fonts::FamilyId; use galaxyui::{AppContext, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity}; use ordered_float::OrderedFloat; pub(crate) use saved_prompts::*; -#[cfg(not(target_family = "wasm"))] -use galaxy_cli::agent::Harness; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::Icon as WarpIcon; pub use zero_state::*; use super::AcceptSlashCommandOrSavedPrompt; diff --git a/app/src/terminal/input/slash_commands/data_source/zero_state.rs b/app/src/terminal/input/slash_commands/data_source/zero_state.rs index b446da61..858cfea6 100644 --- a/app/src/terminal/input/slash_commands/data_source/zero_state.rs +++ b/app/src/terminal/input/slash_commands/data_source/zero_state.rs @@ -1,7 +1,6 @@ -use galaxyui::{Entity, ModelHandle}; -use itertools::Itertools; use galaxy_core::features::FeatureFlag; use galaxyui::{Entity, ModelHandle, SingletonEntity}; +use itertools::Itertools; use crate::ai::skills::SkillManager; use crate::cloud_object::model::persistence::CloudModel; diff --git a/app/src/terminal/input/slash_commands/mod.rs b/app/src/terminal/input/slash_commands/mod.rs index ea69b717..ca75ddd6 100644 --- a/app/src/terminal/input/slash_commands/mod.rs +++ b/app/src/terminal/input/slash_commands/mod.rs @@ -9,7 +9,6 @@ use std::path::PathBuf; use ai::skills::SkillReference; pub use cloud_mode_v2_view::{CloudModeV2SlashCommandView, Section as CloudModeV2Section}; pub use data_source::*; -pub use view::{CloseReason, InlineSlashCommandView, SlashCommandsEvent}; #[cfg(not(target_family = "wasm"))] use galaxy_cli::agent::Harness; use galaxy_core::features::FeatureFlag; @@ -20,6 +19,7 @@ use galaxy_core::ui::theme::AnsiColorIdentifier; use galaxy_util::path::{CleanPathResult, LineAndColumnArg}; use galaxyui::clipboard::ClipboardContent; use galaxyui::{AppContext, SingletonEntity, ViewContext}; +pub use view::{CloseReason, InlineSlashCommandView, SlashCommandsEvent}; use crate::ai::agent::conversation::AIConversationId; #[cfg(not(target_family = "wasm"))] @@ -476,7 +476,7 @@ impl Input { _create_docker_sandbox if command.name == commands::CREATE_DOCKER_SANDBOX.name => { ctx.emit(Event::CreateDockerSandbox); } - conversations if command.name == commands::CONVERSATIONS.name => { + _ if command.name == commands::CONVERSATIONS.name => { if self.is_cloud_mode_input_v2_composing(ctx) { self.suggestions_mode_model.update(ctx, |model, ctx| { model.set_mode(InputSuggestionsMode::Closed, ctx); @@ -523,7 +523,7 @@ impl Input { }; rename_conversation(conversation_id, argument.cloned().unwrap_or_default(), ctx); } - set_tab_color if command.name == commands::SET_TAB_COLOR.name => { + _ if command.name == commands::SET_TAB_COLOR.name => { let supported_options = || { color_dot::TAB_COLOR_OPTIONS .iter() @@ -571,7 +571,7 @@ impl Input { ctx.dispatch_typed_action(&WorkspaceAction::SetActiveTabColor(color)); } - create_env if command.name == commands::CREATE_ENVIRONMENT.name => { + _ if command.name == commands::CREATE_ENVIRONMENT.name => { // If the user included args after the slash command, treat them as repo paths/URLs. let repos = argument .map(|arg| { @@ -776,7 +776,7 @@ impl Input { // Open the skill selector menu for invocation - skill command will be inserted into buffer self.open_invoke_skill_selector(ctx); } - host if command.name == commands::HOST.name => { + _ if command.name == commands::HOST.name => { if !self.is_cloud_mode_input_v2_composing(ctx) { return false; } @@ -794,7 +794,7 @@ impl Input { self.open_v2_host_selector(ctx); return true; } - harness if command.name == commands::HARNESS.name => { + _ if command.name == commands::HARNESS.name => { if !self.is_cloud_mode_input_v2_composing(ctx) { // Defensive: the command is registered only when the V2 flag is on and its // availability requires CLOUD_MODE_V2_COMPOSER, so this branch should be unreachable. @@ -807,7 +807,7 @@ impl Input { self.open_v2_harness_selector(ctx); return true; } - environment if command.name == commands::ENVIRONMENT.name => { + _ if command.name == commands::ENVIRONMENT.name => { if !self.is_cloud_mode_input_v2_composing(ctx) { return false; } @@ -818,7 +818,7 @@ impl Input { self.open_v2_environment_selector(ctx); return true; } - models if command.name == commands::MODEL.name => { + _ if command.name == commands::MODEL.name => { if self.is_cloud_mode_input_v2_composing(ctx) { self.suggestions_mode_model.update(ctx, |model, ctx| { model.set_mode(InputSuggestionsMode::Closed, ctx); @@ -853,7 +853,7 @@ impl Input { self.open_profile_selector(ctx); } - prompts if command.name == commands::PROMPTS.name => { + _ if command.name == commands::PROMPTS.name => { if self.is_cloud_mode_input_v2_composing(ctx) { self.apply_v2_slash_section_filter(CloudModeV2Section::Prompts, ctx); return true; @@ -916,7 +916,7 @@ impl Input { } } #[cfg(all(feature = "local_fs", not(target_family = "wasm")))] - move_to_cloud if command.name == commands::MOVE_TO_CLOUD.name => { + _ if command.name == commands::MOVE_TO_CLOUD.name => { if !AISettings::as_ref(ctx).is_cloud_handoff_enabled(ctx) { return false; } @@ -961,7 +961,7 @@ impl Input { ); } } - fork if command.name == commands::FORK.name => { + _ if command.name == commands::FORK.name => { let Some(conversation_id) = self .ai_context_model .as_ref(ctx) @@ -996,7 +996,7 @@ impl Input { return true; } #[cfg(not(target_family = "wasm"))] - continue_locally if command.name == commands::CONTINUE_LOCALLY.name => { + _ if command.name == commands::CONTINUE_LOCALLY.name => { let Some(conversation_id) = self .ai_context_model .as_ref(ctx) @@ -1043,7 +1043,7 @@ impl Input { destination, }); } - fork_and_compact if command.name == commands::FORK_AND_COMPACT.name => { + _ if command.name == commands::FORK_AND_COMPACT.name => { let Some(conversation_id) = self .ai_context_model .as_ref(ctx) @@ -1069,7 +1069,7 @@ impl Input { destination, }); } - compact_and if command.name == commands::COMPACT_AND.name => { + _ if command.name == commands::COMPACT_AND.name => { let conversation_id = if is_queued_prompt { let Some(conversation_id) = queued_conversation_id else { log::error!("Queued /compact-and missing conversation id"); @@ -1162,9 +1162,7 @@ impl Input { } self.open_repos_menu(ctx); } - command_that_just_sends_ai_request_with_prefix - if slash_command_is_submitted_as_prompt(command) => - { + _ if slash_command_is_submitted_as_prompt(command) => { // These slash commands just send AI requests with the slash command text as a // prefix, and special handling is done downstream as an implementation detail // of handling user queries with specific slash command prefixes. diff --git a/app/src/terminal/input/slash_commands/view.rs b/app/src/terminal/input/slash_commands/view.rs index 0a62b91f..231b8bb3 100644 --- a/app/src/terminal/input/slash_commands/view.rs +++ b/app/src/terminal/input/slash_commands/view.rs @@ -2,10 +2,8 @@ use std::collections::HashSet; use ai::skills::SkillReference; use galaxyui::elements::ChildView; -use galaxyui::{AppContext, Element, ViewContext}; -use galaxyui::{Entity, ModelHandle, View, ViewHandle}; -use lazy_static::lazy_static; use galaxyui::{AppContext, Element, Entity, ModelHandle, View, ViewContext, ViewHandle}; +use lazy_static::lazy_static; use crate::ai::blocklist::agent_view::AgentViewController; use crate::search::data_source::{Query, QueryFilter}; diff --git a/app/src/terminal/input/suggestions_mode_menu.rs b/app/src/terminal/input/suggestions_mode_menu.rs index d147684d..7fc18fe0 100644 --- a/app/src/terminal/input/suggestions_mode_menu.rs +++ b/app/src/terminal/input/suggestions_mode_menu.rs @@ -26,7 +26,7 @@ use crate::input_suggestions::{ DETAILS_PANEL_MARGIN, DETAILS_PANEL_PADDING, HISTORY_DETAILS_PANEL_WIDTH, LABEL_PADDING as InputSuggestionsLabelPadding, }; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; enum SuggestionsResizeConfig { WidthAndHeight, diff --git a/app/src/terminal/input/universal.rs b/app/src/terminal/input/universal.rs index 828414e5..2b9198f5 100644 --- a/app/src/terminal/input/universal.rs +++ b/app/src/terminal/input/universal.rs @@ -1,9 +1,9 @@ -use settings::Setting; use galaxyui::elements::{ Border, ChildView, Container, CornerRadius, DropTarget, Element, Flex, Hoverable, ParentElement, Radius, SavePosition, Stack, }; use galaxyui::{AppContext, SingletonEntity}; +use settings::Setting; use super::common::{ add_command_xray_overlay, add_input_suggestions_overlays, add_vim_status_to_stack, diff --git a/app/src/terminal/input/user_query/mod.rs b/app/src/terminal/input/user_query/mod.rs index 0c03952a..347ce428 100644 --- a/app/src/terminal/input/user_query/mod.rs +++ b/app/src/terminal/input/user_query/mod.rs @@ -6,10 +6,9 @@ mod search_item; mod view; pub use data_source::SelectUserQuery; -pub use view::{UserQueryMenuEvent, UserQueryMenuView}; - use galaxyui::keymap::Keystroke; use galaxyui::platform::OperatingSystem; +pub use view::{UserQueryMenuEvent, UserQueryMenuView}; use crate::terminal::input::inline_menu::{ default_navigation_message_items, InlineMenuAction, InlineMenuMessageArgs, InlineMenuRowAction, diff --git a/app/src/terminal/input_tests.rs b/app/src/terminal/input_tests.rs index fd8005c0..edcac8fb 100644 --- a/app/src/terminal/input_tests.rs +++ b/app/src/terminal/input_tests.rs @@ -287,7 +287,7 @@ pub fn initialize_app(app: &mut App) { crate::ai::document::ai_document_model::AIDocumentModel::new_for_test() }); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); app.add_singleton_model(SkillManager::new); // Add GlobalResourceHandlesProvider for persistence @@ -8134,7 +8134,6 @@ fn test_terminal_only_ai_enter_enters_agent_view_and_clears_buffer() { #[test] fn test_terminal_only_escape_locks_shell_mode() { - App::test((), |mut app| async move { let _am_flag = FeatureFlag::AgentMode.override_enabled(true); let _agent_view_flag = FeatureFlag::AgentView.override_enabled(true); @@ -8463,7 +8462,6 @@ fn open_rich_input_for_terminal(terminal: &ViewHandle, app: &mut A #[test] fn enter_submits_when_submit_on_ctrl_enter_is_false() { - App::test((), |mut app| async move { let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); @@ -8520,7 +8518,6 @@ fn enter_submits_when_submit_on_ctrl_enter_is_false() { #[test] fn ctrl_enter_emits_ctrl_enter_event_when_submit_on_ctrl_enter_is_false() { - App::test((), |mut app| async move { let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); @@ -8574,7 +8571,6 @@ fn ctrl_enter_emits_ctrl_enter_event_when_submit_on_ctrl_enter_is_false() { #[test] fn enter_inserts_newline_when_submit_on_ctrl_enter_is_true() { - App::test((), |mut app| async move { let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); @@ -8627,7 +8623,6 @@ fn enter_inserts_newline_when_submit_on_ctrl_enter_is_true() { #[test] fn ctrl_enter_submits_when_submit_on_ctrl_enter_is_true() { - App::test((), |mut app| async move { let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); @@ -8693,7 +8688,6 @@ fn ctrl_enter_submits_when_submit_on_ctrl_enter_is_true() { #[test] fn ctrl_enter_with_selection_preserves_selection_in_submit_when_setting_is_true() { - App::test((), |mut app| async move { let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); @@ -8794,7 +8788,6 @@ fn editor_keymap_context_excludes_ctrl_enter_enters_agent_view_when_rich_input_i #[test] fn enter_accepts_inline_menu_item_when_submit_on_ctrl_enter_is_true() { - App::test((), |mut app| async move { let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); @@ -8976,8 +8969,8 @@ fn unfreeze_agent_input_does_not_clear_buffer() { #[test] fn ctrl_enter_inserts_newline_in_normal_input_after_rich_input_closes() { - App::test((), |mut app| async move { + use crate::editor::EnterAction; let _cli_agent_flag = FeatureFlag::CLIAgentRichInput.override_enabled(true); initialize_app(&mut app); diff --git a/app/src/terminal/keys_settings.rs b/app/src/terminal/keys_settings.rs index 96262273..9f2c3737 100644 --- a/app/src/terminal/keys_settings.rs +++ b/app/src/terminal/keys_settings.rs @@ -1,7 +1,9 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use galaxyui::keymap::Keystroke; use galaxyui::{AppContext, DisplayIdx, ModelContext}; +use settings::macros::define_settings_group; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; use crate::report_if_error; use crate::root_view::{update_quake_window_bounds, QuakeModePinPosition}; diff --git a/app/src/terminal/ligature_settings.rs b/app/src/terminal/ligature_settings.rs index d304e4a4..02c96958 100644 --- a/app/src/terminal/ligature_settings.rs +++ b/app/src/terminal/ligature_settings.rs @@ -1,6 +1,8 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use galaxyui::{AppContext, SingletonEntity}; +use settings::macros::define_settings_group; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; use crate::features::FeatureFlag; diff --git a/app/src/terminal/local_tty/docker_sandbox.rs b/app/src/terminal/local_tty/docker_sandbox.rs index 572bda50..1a297e9c 100644 --- a/app/src/terminal/local_tty/docker_sandbox.rs +++ b/app/src/terminal/local_tty/docker_sandbox.rs @@ -15,9 +15,9 @@ use std::path::{Path, PathBuf}; use futures::future::BoxFuture; use futures::FutureExt as _; +use galaxy_core::SessionId; use galaxyui::{AppContext, SingletonEntity as _}; use serde::{Deserialize, Serialize}; -use galaxy_core::SessionId; use super::shell::DirectShellStarter; #[cfg(feature = "local_tty")] diff --git a/app/src/terminal/local_tty/shell.rs b/app/src/terminal/local_tty/shell.rs index a245d687..01591583 100644 --- a/app/src/terminal/local_tty/shell.rs +++ b/app/src/terminal/local_tty/shell.rs @@ -2,12 +2,12 @@ use std::ffi::OsString; use std::path::{Path, PathBuf}; use std::{io, process}; -use itertools::Itertools as _; -use serde::{Deserialize, Serialize}; -use typed_path::UnixPathBuf; use galaxy_core::channel::{Channel, ChannelState}; use galaxy_core::session_id::SessionId; use galaxy_util::path::{canonicalize_git_bash_path, is_msys2_path, warp_shell_path}; +use itertools::Itertools as _; +use serde::{Deserialize, Serialize}; +use typed_path::UnixPathBuf; use crate::terminal::available_shells::AvailableShell; use crate::terminal::bootstrap::{generate_session_id, init_shell_script_for_shell}; diff --git a/app/src/terminal/local_tty/terminal_manager.rs b/app/src/terminal/local_tty/terminal_manager.rs index 8a42e488..d2a0efc7 100644 --- a/app/src/terminal/local_tty/terminal_manager.rs +++ b/app/src/terminal/local_tty/terminal_manager.rs @@ -10,14 +10,14 @@ use std::thread::JoinHandle; use anyhow::Context as _; use async_broadcast::InactiveReceiver; +use galaxy_core::SessionId; +use galaxyui::r#async::executor::Background; +use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity, ViewHandle}; #[cfg(unix)] use nix::sys::termios::LocalFlags; use parking_lot::{FairMutex, Mutex}; use pathfinder_geometry::vector::Vector2F; use settings::Setting as _; -use galaxy_core::SessionId; -use galaxyui::r#async::executor::Background; -use galaxyui::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity, ViewHandle}; use super::event_loop::EventLoop; use super::shell::{ShellStarter, ShellStarterSource}; diff --git a/app/src/terminal/local_tty/terminal_view_adaptor.rs b/app/src/terminal/local_tty/terminal_view_adaptor.rs index ef51f425..3d9a6e23 100644 --- a/app/src/terminal/local_tty/terminal_view_adaptor.rs +++ b/app/src/terminal/local_tty/terminal_view_adaptor.rs @@ -4,6 +4,8 @@ use std::rc::Rc; use std::sync::mpsc::SyncSender; use std::sync::Arc; +use galaxy_core::execution_mode::AppExecutionMode; +use galaxy_core::send_telemetry_from_ctx; use parking_lot::FairMutex; use session_sharing_protocol::common::{ ActivePrompt, AgentPromptFailureReason, CLIAgentSessionState, CommandExecutionFailureReason, @@ -19,8 +21,6 @@ use session_sharing_protocol::sharer::{ QuotaType, RemoveGuestResponse, SessionEndedReason, SessionSourceType, TeamAccessLevelUpdateResponse, UpdatePendingUserRoleResponse, }; -use galaxy_core::execution_mode::AppExecutionMode; -use galaxy_core::send_telemetry_from_ctx; use warpui::{AppContext, ModelHandle, SingletonEntity, ViewHandle, WindowId}; use super::terminal_manager::{TerminalManager, TerminalSurfaceInit, TerminalSurfaceResult}; diff --git a/app/src/terminal/local_tty/unix.rs b/app/src/terminal/local_tty/unix.rs index 54bb0897..d9f30c80 100644 --- a/app/src/terminal/local_tty/unix.rs +++ b/app/src/terminal/local_tty/unix.rs @@ -13,6 +13,8 @@ use std::{io, ptr}; use anyhow::{Context as _, Error, Result}; use command::blocking::Command; +use galaxy_core::channel::ChannelState; +use galaxy_core::features::FeatureFlag; use itertools::Itertools; use libc::{self, c_int, winsize, TIOCSCTTY}; use mio::unix::SourceFd; @@ -21,8 +23,6 @@ use nix::pty::openpty; use nix::sys::termios::{self, InputFlags, SetArg}; use serde::{Deserialize, Serialize}; use signal_hook_mio::v1_0::Signals; -use galaxy_core::channel::ChannelState; -use galaxy_core::features::FeatureFlag; use warpui::{AppContext, SingletonEntity}; use super::event_loop::{PTY_TOKEN, SIGNALS_TOKEN}; diff --git a/app/src/terminal/local_tty/windows/conpty_api.rs b/app/src/terminal/local_tty/windows/conpty_api.rs index 68955a38..f4ff4a13 100644 --- a/app/src/terminal/local_tty/windows/conpty_api.rs +++ b/app/src/terminal/local_tty/windows/conpty_api.rs @@ -1,7 +1,7 @@ -use galaxy_util::path::TargetDirError; use std::mem::transmute; use std::path::Path; +use galaxy_util::path::TargetDirError; use thiserror::Error; use windows::core::{s, HRESULT, HSTRING, PCWSTR}; use windows::Win32::Foundation::HANDLE; diff --git a/app/src/terminal/mod.rs b/app/src/terminal/mod.rs index d1f91c89..c7780d4b 100644 --- a/app/src/terminal/mod.rs +++ b/app/src/terminal/mod.rs @@ -12,13 +12,10 @@ mod package_installers; pub use galaxy_terminal::shell::{self, ShellLaunchData}; use galaxyui::geometry::vector::Vector2F; use galaxyui::units::{IntoPixels, Lines, Pixels}; -use galaxyui::AppContext; -use galaxyui::WindowId; +use galaxyui::{AppContext, WindowId}; pub(crate) use history::UpArrowHistoryConfig; pub use history::{History, HistoryEntry, HistoryEvent, ShellHost}; pub use view::{Event, TerminalView}; -pub use galaxy_terminal::shell::{self, ShellLaunchData}; -use galaxyui::{AppContext, WindowId}; mod block_list_settings; mod alias; diff --git a/app/src/terminal/model/alt_screen.rs b/app/src/terminal/model/alt_screen.rs index dffcae12..ee7c9460 100644 --- a/app/src/terminal/model/alt_screen.rs +++ b/app/src/terminal/model/alt_screen.rs @@ -3,12 +3,12 @@ use std::io; use std::ops::{Range, RangeInclusive}; use std::sync::Arc; +use galaxy_core::semantic_selection::SemanticSelection; use itertools::Itertools; use num_traits::Float as _; use parking_lot::Mutex; use pathfinder_color::ColorU; use vec1::Vec1; -use galaxy_core::semantic_selection::SemanticSelection; use warp_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; use warpui::text::SelectionType; use warpui::units::Lines; diff --git a/app/src/terminal/model/ansi/dcs_hooks.rs b/app/src/terminal/model/ansi/dcs_hooks.rs index 27345741..ee3eef78 100644 --- a/app/src/terminal/model/ansi/dcs_hooks.rs +++ b/app/src/terminal/model/ansi/dcs_hooks.rs @@ -3,9 +3,9 @@ use std::collections::HashSet; use std::path::PathBuf; +use galaxy_core::command::ExitCode; use ordered_float::OrderedFloat; use serde::{Deserialize, Deserializer, Serialize}; -use galaxy_core::command::ExitCode; use crate::terminal::model::block::BlockId; use crate::terminal::model::session::SessionId; diff --git a/app/src/terminal/model/ansi/mod.rs b/app/src/terminal/model/ansi/mod.rs index 2e437c95..07278810 100644 --- a/app/src/terminal/model/ansi/mod.rs +++ b/app/src/terminal/model/ansi/mod.rs @@ -22,6 +22,7 @@ use byte_unit::{Byte, Unit as ByteUnit}; pub use dcs_hooks::*; pub use galaxy_terminal::model::ansi::control_sequence_parameters::*; use galaxy_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; +use galaxyui::color::ColorU; pub use handler::*; use hex; use instant::Instant; @@ -29,8 +30,6 @@ use itertools::Itertools; use lazy_static::lazy_static; use log::debug; use vte::{Params, Parser as VteParser, Perform as VtePerform}; -pub use galaxy_terminal::model::ansi::control_sequence_parameters::*; -use galaxyui::color::ColorU; use super::kitty::parse_kitty_chunk; use crate::features::FeatureFlag; diff --git a/app/src/terminal/model/ansi/mod_tests.rs b/app/src/terminal/model/ansi/mod_tests.rs index 00b102d3..46cb36a3 100644 --- a/app/src/terminal/model/ansi/mod_tests.rs +++ b/app/src/terminal/model/ansi/mod_tests.rs @@ -2,6 +2,7 @@ use std::collections::HashSet; use std::io; use std::path::PathBuf; +use galaxy_core::command::ExitCode; use hex; use super::*; diff --git a/app/src/terminal/model/block.rs b/app/src/terminal/model/block.rs index b0eb2c12..9e322a4a 100644 --- a/app/src/terminal/model/block.rs +++ b/app/src/terminal/model/block.rs @@ -12,6 +12,8 @@ use std::sync::Arc; use chrono::{DateTime, Duration, FixedOffset, Local}; use enum_iterator::all; +use galaxy_core::command::ExitCode; +use galaxy_core::features::FeatureFlag; use hex; use instant::Instant; pub use interaction_mode::*; @@ -19,8 +21,6 @@ use lazy_static::lazy_static; use pathfinder_color::ColorU; use pathfinder_geometry::vector::Vector2F; pub use serialized_block::*; -use galaxy_core::command::ExitCode; -use galaxy_core::features::FeatureFlag; use warp_terminal::model::grid::Dimensions as _; use warp_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; use warp_util::path::user_friendly_path; diff --git a/app/src/terminal/model/block/serialized_block.rs b/app/src/terminal/model/block/serialized_block.rs index 373ab189..d8686cbd 100644 --- a/app/src/terminal/model/block/serialized_block.rs +++ b/app/src/terminal/model/block/serialized_block.rs @@ -1,9 +1,9 @@ use std::collections::HashSet; use chrono::{DateTime, Local, TimeZone as _}; +use galaxy_core::command::ExitCode; use serde::{Deserialize, Serialize}; use serde_bytes_repr::{ByteFmtDeserializer, ByteFmtSerializer}; -use galaxy_core::command::ExitCode; use super::AgentInteractionMetadata; use crate::ai::agent::conversation::AIConversationId; diff --git a/app/src/terminal/model/blocks.rs b/app/src/terminal/model/blocks.rs index f4d7bf52..44c893e4 100644 --- a/app/src/terminal/model/blocks.rs +++ b/app/src/terminal/model/blocks.rs @@ -8,16 +8,16 @@ use std::time::Duration; use anyhow::anyhow; use chrono::{DateTime, Local}; -use instant::SystemTime; -use selection::BlockListSelection; -pub use selection::SelectionRange; -use sum_tree::{Dimension, Item, SeekBias, SumTree}; use galaxy_core::features::FeatureFlag; use galaxy_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; use galaxyui::color::ColorU; use galaxyui::r#async::executor::Background; use galaxyui::units::{IntoLines, IntoPixels, Lines}; use galaxyui::{record_trace_event, AppContext, EntityId, ViewHandle}; +use instant::SystemTime; +use selection::BlockListSelection; +pub use selection::SelectionRange; +use sum_tree::{Dimension, Item, SeekBias, SumTree}; use super::ansi::{Handler, InputBufferValue}; use super::block::{BlockId, BlockSize, BlockState, SerializedAIMetadata}; @@ -3384,6 +3384,42 @@ impl BlockList { self.maintain_pinned_to_bottom(); } + pub(in crate::terminal) fn insert_rich_content_after_item( + &mut self, + after_item: RemovableBlocklistItem, + item: RichContentItem, + ) -> bool { + let after_index = match self.removable_blocklist_item_positions.get(&after_item) { + Some(&idx) => idx, + None => return false, + }; + + let view_id = item.view_id; + + self.finish_background_block(); + + let (new_tree, inserted_index) = { + let mut cursor = self.block_heights.cursor::(); + let mut prefix = cursor.slice(&TotalIndex(after_index.0 + 1), SeekBias::Right); + let insertion_index = TotalIndex(prefix.summary().total_count); + prefix.push(BlockHeightItem::RichContent(item)); + prefix.push_tree(cursor.suffix()); + (prefix, insertion_index) + }; + + self.block_heights = new_tree; + + self.update_block_height_indices(BlockHeightUpdate::Insertion(inserted_index), true); + + self.removable_blocklist_item_positions + .insert(RemovableBlocklistItem::RichContent(view_id), inserted_index); + + self.mark_rich_content_dirty(view_id); + self.maintain_pinned_to_bottom(); + self.event_proxy.send_wakeup_event(); + true + } + pub(in crate::terminal) fn set_marked_text( &mut self, marked_text: &str, diff --git a/app/src/terminal/model/blocks/selection.rs b/app/src/terminal/model/blocks/selection.rs index e748031d..d61c83ae 100644 --- a/app/src/terminal/model/blocks/selection.rs +++ b/app/src/terminal/model/blocks/selection.rs @@ -3,13 +3,13 @@ use std::fmt::Debug; use std::mem; use std::ops::RangeInclusive; -use sum_tree::SeekBias; -use vec1::{vec1, Vec1}; use galaxy_core::semantic_selection::SemanticSelection; use galaxy_terminal::model::grid::CellType; use galaxyui::text::{IsRect, SelectionType}; use galaxyui::units::{IntoLines as _, Lines}; use galaxyui::{AppContext, EntityId, ViewAsRef as _}; +use sum_tree::SeekBias; +use vec1::{vec1, Vec1}; use super::{ BlockHeight, BlockHeightItem, BlockHeightSummary, BlockList, BlockListPoint, RichContentItem, diff --git a/app/src/terminal/model/find.rs b/app/src/terminal/model/find.rs index b743c28c..b343b092 100644 --- a/app/src/terminal/model/find.rs +++ b/app/src/terminal/model/find.rs @@ -234,10 +234,7 @@ impl RegexDFAs { // triggers a match for the last point. let mut last_point = None; - 'outer: loop { - let Some(cursor_item) = cursor.current_item() else { - break; - }; + 'outer: while let Some(cursor_item) = cursor.current_item() { let c = cursor_item.content_char(); let current_point = cursor_item.point(); diff --git a/app/src/terminal/model/grid/grid_handler.rs b/app/src/terminal/model/grid/grid_handler.rs index 09d02b6b..73c3a0de 100644 --- a/app/src/terminal/model/grid/grid_handler.rs +++ b/app/src/terminal/model/grid/grid_handler.rs @@ -21,12 +21,6 @@ use std::ops::{Range, RangeInclusive}; use bounded_vec_deque::BoundedVecDeque; use filtering::FilterState; -use itertools::Itertools; -use lazy_static::lazy_static; -use string_offset::ByteOffset; -use unicode_general_category::{get_general_category, GeneralCategory}; -use unicode_width::UnicodeWidthChar; -use urlocator::{UrlLocation, UrlLocator}; use galaxy_core::features::FeatureFlag; use galaxy_core::semantic_selection::{SemanticSelection, SMART_SELECT_MATCH_WINDOW_LIMIT}; use galaxy_core::{safe_assert, safe_assert_eq}; @@ -35,6 +29,12 @@ pub use galaxy_terminal::model::TermMode; use galaxy_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; use galaxy_util::path::CleanPathResult; use galaxyui::color::ColorU; +use itertools::Itertools; +use lazy_static::lazy_static; +use string_offset::ByteOffset; +use unicode_general_category::{get_general_category, GeneralCategory}; +use unicode_width::UnicodeWidthChar; +use urlocator::{UrlLocation, UrlLocator}; use super::displayed_output::DisplayedOutput; use super::grapheme_cursor::{self, GraphemeCursor}; diff --git a/app/src/terminal/model/grid/resize.rs b/app/src/terminal/model/grid/resize.rs index ff99cec0..daadbeff 100644 --- a/app/src/terminal/model/grid/resize.rs +++ b/app/src/terminal/model/grid/resize.rs @@ -1,10 +1,10 @@ // The code in this file is adapted from the alacritty_terminal crate under the // Apache license; see: crates/galaxy_terminal/src/model/LICENSE-ALACRITTY. -use string_offset::ByteOffset; use galaxy_terminal::model::grid::cell::{self, LineLength as _}; use galaxy_terminal::model::grid::Dimensions as _; use galaxy_terminal::model::{Point, VisiblePoint, VisibleRow}; +use string_offset::ByteOffset; use super::{FullGridClearBehavior, GridHandler}; use crate::terminal::model::grid::Cursor; diff --git a/app/src/terminal/model/header_grid.rs b/app/src/terminal/model/header_grid.rs index ad7d8b61..1b8c22ab 100644 --- a/app/src/terminal/model/header_grid.rs +++ b/app/src/terminal/model/header_grid.rs @@ -4,10 +4,10 @@ use std::cmp::max; use std::io; -use instant::Instant; -use pathfinder_color::ColorU; use galaxy_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; use galaxyui::units::{IntoLines as _, Lines}; +use instant::Instant; +use pathfinder_color::ColorU; use super::ansi::{self, Attr, Handler, PrecmdValue, PreexecValue, Processor, PromptMetadata}; use super::block::{BlockGridPoint, BlockSize}; diff --git a/app/src/terminal/model/kitty.rs b/app/src/terminal/model/kitty.rs index 8fa30f71..598daa80 100644 --- a/app/src/terminal/model/kitty.rs +++ b/app/src/terminal/model/kitty.rs @@ -6,20 +6,14 @@ use std::{env, fs, str}; use anyhow::Result; use base64::Engine; use flate2::read::ZlibDecoder; -use galaxyui::image_cache::{resize_dimensions, FitType}; -use galaxyui::{ - assets::asset_cache::Asset, - image_cache::{CustomHeaderCreationError, CustomImageFormat, CustomImageHeader, ImageType}, - util::{parse_i32, parse_u32}, -}; -use pathfinder_geometry::vector::Vector2F; -use rand::Rng; use galaxyui::assets::asset_cache::Asset; use galaxyui::image_cache::{ resize_dimensions, CustomHeaderCreationError, CustomImageFormat, CustomImageHeader, FitType, ImageType, }; use galaxyui::util::{parse_i32, parse_u32}; +use pathfinder_geometry::vector::Vector2F; +use rand::Rng; use super::escape_sequences::C1; diff --git a/app/src/terminal/model/mod.rs b/app/src/terminal/model/mod.rs index a2a68641..cc98d077 100644 --- a/app/src/terminal/model/mod.rs +++ b/app/src/terminal/model/mod.rs @@ -37,10 +37,9 @@ pub mod terminal_model; #[cfg(any(test, feature = "test-util"))] pub mod test_utils; -pub use galaxy_terminal::model::{char_or_str, escape_sequences, grid::cell, mouse, BlockId}; +pub use galaxy_terminal::model::grid::cell; +pub use galaxy_terminal::model::{char_or_str, escape_sequences, mouse, BlockId}; pub use secrets::{ set_user_and_enterprise_secret_regexes, ObfuscateSecrets, RespectObfuscatedSecrets, Secret, SecretHandle, }; -pub use galaxy_terminal::model::grid::cell; -pub use galaxy_terminal::model::{char_or_str, escape_sequences, mouse, BlockId}; diff --git a/app/src/terminal/model/secrets.rs b/app/src/terminal/model/secrets.rs index 9039c592..d48b7c44 100644 --- a/app/src/terminal/model/secrets.rs +++ b/app/src/terminal/model/secrets.rs @@ -6,12 +6,12 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use anyhow::anyhow; +use galaxyui::elements::SecretRange; +use galaxyui::EntityId; use itertools::Itertools; use lazy_static::lazy_static; use parking_lot::Mutex; use rangemap::{RangeInclusiveMap, StepLite}; -use galaxyui::elements::SecretRange; -use galaxyui::EntityId; use super::grid::grid_handler::GridHandler; use super::grid::{Dimensions as _, RespectDisplayedOutput}; diff --git a/app/src/terminal/model/selection.rs b/app/src/terminal/model/selection.rs index c7420286..37c8a9f5 100644 --- a/app/src/terminal/model/selection.rs +++ b/app/src/terminal/model/selection.rs @@ -10,8 +10,8 @@ use std::mem; use std::ops::RangeInclusive; pub use std::ops::{Range, RangeBounds}; -use vec1::Vec1; use galaxy_core::semantic_selection::SemanticSelection; +use vec1::Vec1; use warp_terminal::model::grid::cell; use warpui::text::SelectionType; use warpui::units::Lines; @@ -508,11 +508,10 @@ impl Selection { let mut range_end = grid_handler.semantic_search_right(end, |c| is_word_boundary_char(selection, c)); - if selection.smart_select_enabled() && self.smart_select_override.is_some() { - let smart_select_override = self - .smart_select_override - .as_ref() - .expect("already checked this is Some"); + if let (true, Some(smart_select_override)) = ( + selection.smart_select_enabled(), + &self.smart_select_override, + ) { if smart_select_override.contains(&start) || smart_select_override.contains(&end) { range_start = min(range_start, *smart_select_override.start()); range_end = max(range_end, *smart_select_override.end()); diff --git a/app/src/terminal/model/session.rs b/app/src/terminal/model/session.rs index ac6d61f3..a1291453 100644 --- a/app/src/terminal/model/session.rs +++ b/app/src/terminal/model/session.rs @@ -15,12 +15,6 @@ use command_executor::remote_server_executor::RemoteServerCommandExecutor; pub use command_executor::*; use futures::future::{BoxFuture, Shared}; use futures::FutureExt; -use instant::Instant; -use once_cell::sync::OnceCell; -use parking_lot::{Mutex, RwLock}; -use smol_str::SmolStr; -use typed_path::{TypedPath, TypedPathBuf, WindowsPath}; -use version_compare::Version; use galaxy_completer::completer::{ CommandExitStatus, CommandOutput, PathSeparators, TopLevelCommandCaseSensitivity, }; @@ -30,6 +24,12 @@ use galaxy_util::path::{ }; use galaxyui::platform::OperatingSystem; use galaxyui::{Entity, ModelContext, SingletonEntity}; +use instant::Instant; +use once_cell::sync::OnceCell; +use parking_lot::{Mutex, RwLock}; +use smol_str::SmolStr; +use typed_path::{TypedPath, TypedPathBuf, WindowsPath}; +use version_compare::Version; use super::ansi::{BootstrappedValue, InitShellValue, SSHValue}; use super::terminal_model::{HistoryEntry, SubshellInitializationInfo}; @@ -1279,22 +1279,17 @@ impl Session { ExecuteCommandOptions::default(), ) .await; - HashSet::from_iter( - ShellType::PowerShell - .executables_from_shell_command_output( - windows_results, - false, /* is_msys2 */ - ) - .into_iter(), - ) + HashSet::from_iter(ShellType::PowerShell.executables_from_shell_command_output( + windows_results, + false, /* is_msys2 */ + )) } else { HashSet::new() }; new_commands.extend( shell .shell_type() - .executables_from_shell_command_output(result, is_msys2) - .into_iter(), + .executables_from_shell_command_output(result, is_msys2), ); if self.external_commands.set(new_commands).is_err() { log::warn!("External commands should only be loaded once per session."); diff --git a/app/src/terminal/model/session/command_executor.rs b/app/src/terminal/model/session/command_executor.rs index acca489c..521d5fe0 100644 --- a/app/src/terminal/model/session/command_executor.rs +++ b/app/src/terminal/model/session/command_executor.rs @@ -350,6 +350,7 @@ pub mod testing { use anyhow::anyhow; use command::r#async::Command; use galaxy_completer::completer::CommandOutput; + use galaxy_terminal::shell::ShellType; use super::*; diff --git a/app/src/terminal/model/session/command_executor/in_band_command_executor.rs b/app/src/terminal/model/session/command_executor/in_band_command_executor.rs index e0c63803..881c6a8f 100644 --- a/app/src/terminal/model/session/command_executor/in_band_command_executor.rs +++ b/app/src/terminal/model/session/command_executor/in_band_command_executor.rs @@ -7,12 +7,12 @@ use std::sync::Arc; use anyhow::Result; use async_channel::{self, Receiver, Sender}; use async_trait::async_trait; -use parking_lot::{Mutex, MutexGuard}; use galaxy_completer::completer::{CommandExitStatus, CommandOutput}; use galaxy_core::command::ExitCode; use galaxy_terminal::model::Point; use galaxy_util::on_cancel::OnCancelFutureExt; use galaxyui::r#async::block_on; +use parking_lot::{Mutex, MutexGuard}; use super::ExecuteCommandOptions; use crate::safe_info; diff --git a/app/src/terminal/model/terminal_model.rs b/app/src/terminal/model/terminal_model.rs index 8b1b039b..89ab3bea 100644 --- a/app/src/terminal/model/terminal_model.rs +++ b/app/src/terminal/model/terminal_model.rs @@ -7,6 +7,9 @@ use std::sync::Arc; use async_channel::Sender; use base64::Engine; +use galaxy_core::features::FeatureFlag; +use galaxy_core::report_error; +use galaxy_core::semantic_selection::SemanticSelection; use hex::FromHexError; use itertools::{Either, Itertools}; use serde::Serialize; @@ -14,9 +17,6 @@ use session_sharing_protocol::common::{ AICommandMetadata, OrderedTerminalEventType, ParticipantId, }; use session_sharing_protocol::sharer::SessionSourceType; -use galaxy_core::features::FeatureFlag; -use galaxy_core::report_error; -use galaxy_core::semantic_selection::SemanticSelection; pub use warp_terminal::model::BlockIndex; use warp_terminal::model::{KeyboardModes, KeyboardModesApplyBehavior}; use warpui::assets::asset_cache::Asset; diff --git a/app/src/terminal/model/terminal_model_tests.rs b/app/src/terminal/model/terminal_model_tests.rs index 5843b684..f8eb9f0a 100644 --- a/app/src/terminal/model/terminal_model_tests.rs +++ b/app/src/terminal/model/terminal_model_tests.rs @@ -5,11 +5,9 @@ use base64::engine::general_purpose::STANDARD as BASE64; use chrono::{DateTime, Local}; use galaxy_core::command::ExitCode; use galaxy_terminal::model::ansi::ClearMode; -use galaxyui::text::str_to_byte_vec; -use galaxyui::text::SelectionType; -use vec1::vec1; use galaxyui::r#async::executor::Background; use galaxyui::text::{str_to_byte_vec, SelectionType}; +use vec1::vec1; use super::*; use crate::terminal::color; diff --git a/app/src/terminal/model/test_utils.rs b/app/src/terminal/model/test_utils.rs index 1ac5aaeb..8a674958 100644 --- a/app/src/terminal/model/test_utils.rs +++ b/app/src/terminal/model/test_utils.rs @@ -9,9 +9,9 @@ use std::collections::HashMap; use std::io::sink; use std::sync::Arc; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::command::ExitCode; use galaxyui::r#async::executor::Background; +use pathfinder_geometry::vector::Vector2F; use super::ansi::{ CommandFinishedValue, CompletionMetadata, Handler, PrecmdValue, PreexecValue, Processor, diff --git a/app/src/terminal/package_installers.rs b/app/src/terminal/package_installers.rs index 7655a15d..26835fc1 100644 --- a/app/src/terminal/package_installers.rs +++ b/app/src/terminal/package_installers.rs @@ -1,6 +1,8 @@ //! Utilities to check whether a command at the cursor position is likely a package installer command. +use galaxy_util::path::ShellFamily; use string_offset::ByteOffset; +use warp_completer::parsers::simple::command_at_cursor_position; use crate::completer::SessionContext; use crate::terminal::alias::is_expandable_alias; diff --git a/app/src/terminal/package_installers_tests.rs b/app/src/terminal/package_installers_tests.rs index c328b7d8..3e02a5bb 100644 --- a/app/src/terminal/package_installers_tests.rs +++ b/app/src/terminal/package_installers_tests.rs @@ -1,9 +1,9 @@ +use galaxy_util::path::ShellFamily; + use crate::terminal::package_installers::command_at_cursor_has_common_package_installer_prefix; #[test] fn test_command_at_cursor_has_common_package_installer_prefix_basic_prefixes() { - use galaxy_util::path::ShellFamily; - // A representative subset of prefixes from is_common_package_installer_prefix let prefixes = vec![ // Node ecosystem @@ -93,7 +93,6 @@ fn test_command_at_cursor_has_common_package_installer_prefix_with_alias_expansi #[test] fn test_command_at_cursor_has_common_package_installer_prefix_negative_cases() { - let cases = vec!["git add @", "echo @", "cargo run @"]; for buffer in cases { @@ -114,7 +113,6 @@ fn test_command_at_cursor_has_common_package_installer_prefix_negative_cases() { #[test] fn test_command_at_cursor_has_common_package_installer_prefix_multi_segment_commands() { - // Test cases with multi-segment commands and different cursor positions let test_cases = vec![ // npm install && git add @[cursor] -> should be false (cursor in git add segment) diff --git a/app/src/terminal/profile_model_selector.rs b/app/src/terminal/profile_model_selector.rs index 84de560b..b54dc827 100644 --- a/app/src/terminal/profile_model_selector.rs +++ b/app/src/terminal/profile_model_selector.rs @@ -1,11 +1,6 @@ use std::sync::Arc; use ai::api_keys::{ApiKeyManager, ApiKeyManagerEvent}; -use indexmap::IndexMap; -use instant::{Duration, Instant}; -use parking_lot::FairMutex; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Empty, Expanded, Flex, Hoverable, MainAxisAlignment, MainAxisSize, @@ -20,6 +15,11 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use indexmap::IndexMap; +use instant::{Duration, Instant}; +use parking_lot::FairMutex; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; const SIDECAR_POSITION_ID: &str = "model_sidecar_panel"; @@ -540,7 +540,7 @@ impl ProfileModelSelector { }, ); - let manage_api_key_button = ctx.add_typed_action_view(|_ctx| { + let _manage_api_key_button = ctx.add_typed_action_view(|_ctx| { ActionButton::new("Manage", SecondaryTheme) .with_tooltip("Manage API keys") .with_size(ButtonSize::XSmall) diff --git a/app/src/terminal/prompt_render_helper.rs b/app/src/terminal/prompt_render_helper.rs index 0179dc17..7865591b 100644 --- a/app/src/terminal/prompt_render_helper.rs +++ b/app/src/terminal/prompt_render_helper.rs @@ -1,7 +1,6 @@ use std::fmt; use std::num::NonZeroUsize; -use settings::Setting as _; use galaxy_core::semantic_selection::SemanticSelection; use galaxyui::elements::{ Container, DispatchEventResult, Element, EventHandler, SavePosition, SelectableArea, @@ -11,6 +10,7 @@ use galaxyui::fonts::{Properties, Weight}; use galaxyui::presenter::ChildView; use galaxyui::units::Pixels; use galaxyui::{AppContext, EntityId, ModelAsRef, ModelHandle, SingletonEntity, ViewHandle}; +use settings::Setting as _; use super::input::InputRenderStateModel; use super::model::block::Block; diff --git a/app/src/terminal/ref_tests/mod.rs b/app/src/terminal/ref_tests/mod.rs index 83bf4d35..2465b363 100644 --- a/app/src/terminal/ref_tests/mod.rs +++ b/app/src/terminal/ref_tests/mod.rs @@ -6,11 +6,10 @@ use std::io::{self, Read}; use std::path::Path; use std::sync::Arc; +use galaxyui::r#async::executor::Background; use serde::Deserialize; use serde_json as json; -use galaxyui::r#async::executor::Background; - use crate::terminal::color::Colors; use crate::terminal::event_listener::ChannelEventListener; use crate::terminal::model::block::BlockSize; diff --git a/app/src/terminal/safe_mode_settings.rs b/app/src/terminal/safe_mode_settings.rs index 47ec71ee..7cc0a1be 100644 --- a/app/src/terminal/safe_mode_settings.rs +++ b/app/src/terminal/safe_mode_settings.rs @@ -1,6 +1,8 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use galaxyui::{AppContext, SingletonEntity}; +use settings::macros::define_settings_group; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; use crate::terminal::model::ObfuscateSecrets; use crate::workspaces::user_workspaces::UserWorkspaces; diff --git a/app/src/terminal/session_settings.rs b/app/src/terminal/session_settings.rs index a24e63bb..db6ddfc3 100644 --- a/app/src/terminal/session_settings.rs +++ b/app/src/terminal/session_settings.rs @@ -2,13 +2,15 @@ pub mod new_session_shell; pub mod startup_shell; pub mod working_directory_config; +use galaxy_core::settings::macros::define_settings_group; +use galaxy_core::settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; use instant::Duration; use lazy_static::lazy_static; pub use new_session_shell::*; use serde::{Deserialize, Serialize}; pub use startup_shell::*; -use galaxy_core::settings::macros::define_settings_group; -use galaxy_core::settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; pub use working_directory_config::*; use crate::ai::blocklist::agent_view::toolbar_item::AgentToolbarItemKind; diff --git a/app/src/terminal/settings.rs b/app/src/terminal/settings.rs index 5a1848fd..0b9eb337 100644 --- a/app/src/terminal/settings.rs +++ b/app/src/terminal/settings.rs @@ -1,7 +1,9 @@ +use galaxy_core::features::FeatureFlag; use serde::{Deserialize, Serialize}; use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; -use galaxy_core::features::FeatureFlag; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; use warpui::units::Pixels; use warpui::{AppContext, SingletonEntity}; diff --git a/app/src/terminal/share_block_modal.rs b/app/src/terminal/share_block_modal.rs index 9c7171c9..4cfdd22e 100644 --- a/app/src/terminal/share_block_modal.rs +++ b/app/src/terminal/share_block_modal.rs @@ -2,10 +2,6 @@ use std::ops::RangeInclusive; use std::sync::Arc; use anyhow::Result; -use parking_lot::FairMutex; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -use serde::Serialize; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::Fill; use galaxyui::browser::escape_html_attribute; @@ -31,6 +27,10 @@ use galaxyui::{ LayoutContext, PaintContext, SingletonEntity, SizeConstraint, TypedActionView, View, ViewContext, ViewHandle, }; +use parking_lot::FairMutex; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +use serde::Serialize; use super::grid_renderer::CellGlyphCache; use super::model::grid::RespectDisplayedOutput; @@ -53,7 +53,7 @@ use crate::terminal::model::terminal_model::BlockIndex; use crate::terminal::model::ObfuscateSecrets; use crate::terminal::safe_mode_settings::get_secret_obfuscation_mode; use crate::terminal::TerminalModel; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::ui_components::icons::Icon; use crate::util::bindings::CustomAction; use crate::view_components::ToastFlavor; diff --git a/app/src/terminal/shared_session/manager.rs b/app/src/terminal/shared_session/manager.rs index 6f87705c..bb3d361b 100644 --- a/app/src/terminal/shared_session/manager.rs +++ b/app/src/terminal/shared_session/manager.rs @@ -1,12 +1,11 @@ use std::collections::HashMap; -use itertools::Itertools; -use session_sharing_protocol::common::SessionId; - use galaxyui::{ AppContext, Entity, EntityId, ModelContext, SingletonEntity, ViewHandle, WeakViewHandle, WindowId, }; +use itertools::Itertools; +use session_sharing_protocol::common::SessionId; use super::SharedSessionActionSource; use crate::terminal::TerminalView; diff --git a/app/src/terminal/shared_session/mod.rs b/app/src/terminal/shared_session/mod.rs index 66675434..025a5668 100644 --- a/app/src/terminal/shared_session/mod.rs +++ b/app/src/terminal/shared_session/mod.rs @@ -1,11 +1,10 @@ use byte_unit::Byte; -use galaxyui::{id, keymap::ContextPredicate, AppContext}; +use galaxyui::keymap::ContextPredicate; +use galaxyui::{id, AppContext}; use instant::Duration; use serde::{Deserialize, Serialize}; use session_sharing_protocol::common::{Role, Scrollback, ScrollbackBlock, SessionId}; use session_sharing_protocol::sharer::SessionSourceType; -use galaxyui::keymap::ContextPredicate; -use galaxyui::{id, AppContext}; use super::model::block::SerializedBlock; use super::model::terminal_model::BlockIndex; diff --git a/app/src/terminal/shared_session/participant_avatar_view.rs b/app/src/terminal/shared_session/participant_avatar_view.rs index 97a2f829..48c4fc3c 100644 --- a/app/src/terminal/shared_session/participant_avatar_view.rs +++ b/app/src/terminal/shared_session/participant_avatar_view.rs @@ -1,8 +1,3 @@ -use instant::Duration; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use session_sharing_protocol::common::{ParticipantId, ParticipantInfo, Role}; -use session_sharing_protocol::sharer::RoleUpdateReason; use galaxyui::accessibility::AccessibilityContent; use galaxyui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, @@ -16,6 +11,11 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use instant::Duration; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use session_sharing_protocol::common::{ParticipantId, ParticipantInfo, Role}; +use session_sharing_protocol::sharer::RoleUpdateReason; use super::render_util::non_hoverable_participant_avatar; use crate::appearance::Appearance; diff --git a/app/src/terminal/shared_session/presence_manager.rs b/app/src/terminal/shared_session/presence_manager.rs index f19012a7..2b32a721 100644 --- a/app/src/terminal/shared_session/presence_manager.rs +++ b/app/src/terminal/shared_session/presence_manager.rs @@ -643,11 +643,8 @@ impl PresenceManager { /// Refreshes the block ID to participants selected cache to be consistent with the current participant data stored. fn refresh_block_id_to_participants_selected(&mut self) { self.block_id_to_participants_selected.clear(); - let participants = if self.sharer.is_some() { - Either::Left( - iter::once(self.sharer.as_ref().expect("sharer should exist")) - .chain(self.present_viewers.values()), - ) + let participants = if let Some(sharer) = &self.sharer { + Either::Left(iter::once(sharer).chain(self.present_viewers.values())) } else { Either::Right(self.present_viewers.values()) }; diff --git a/app/src/terminal/shared_session/render_util.rs b/app/src/terminal/shared_session/render_util.rs index 21d72fcf..39298311 100644 --- a/app/src/terminal/shared_session/render_util.rs +++ b/app/src/terminal/shared_session/render_util.rs @@ -1,5 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ ChildAnchor, CornerRadius, Fill, Hoverable, MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Radius, Stack, @@ -7,6 +5,8 @@ use galaxyui::elements::{ use galaxyui::fonts::Weight; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, SingletonEntity}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use super::presence_manager::{Participant, MUTED_AVATAR_BORDER_COLOR, MUTED_PARTICIPANT_COLOR}; use crate::appearance::Appearance; diff --git a/app/src/terminal/shared_session/role_change_modal/mod.rs b/app/src/terminal/shared_session/role_change_modal/mod.rs index ad47e91d..18470dc2 100644 --- a/app/src/terminal/shared_session/role_change_modal/mod.rs +++ b/app/src/terminal/shared_session/role_change_modal/mod.rs @@ -1,8 +1,8 @@ -use session_sharing_protocol::common::{ParticipantId, Role, RoleRequestId}; use galaxyui::elements::Empty; use galaxyui::presenter::ChildView; use galaxyui::ui_components::components::{Coords, UiComponentStyles}; use galaxyui::{AppContext, Element, Entity, View, ViewContext, ViewHandle}; +use session_sharing_protocol::common::{ParticipantId, Role, RoleRequestId}; use crate::modal::Modal; use crate::pane_group::TerminalPaneId; diff --git a/app/src/terminal/shared_session/role_change_modal/sharer_response_body.rs b/app/src/terminal/shared_session/role_change_modal/sharer_response_body.rs index 068a50e2..73bef7a8 100644 --- a/app/src/terminal/shared_session/role_change_modal/sharer_response_body.rs +++ b/app/src/terminal/shared_session/role_change_modal/sharer_response_body.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; -use session_sharing_protocol::common::{ParticipantId, Role, RoleRequestId}; use galaxy_core::features::FeatureFlag; +use session_sharing_protocol::common::{ParticipantId, Role, RoleRequestId}; use warpui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Flex, MainAxisAlignment, MouseStateHandle, ParentElement, Text, diff --git a/app/src/terminal/shared_session/role_change_modal/viewer_request_body.rs b/app/src/terminal/shared_session/role_change_modal/viewer_request_body.rs index 6b094d63..96acac20 100644 --- a/app/src/terminal/shared_session/role_change_modal/viewer_request_body.rs +++ b/app/src/terminal/shared_session/role_change_modal/viewer_request_body.rs @@ -1,4 +1,3 @@ -use session_sharing_protocol::common::Role; use galaxyui::elements::{ Container, CrossAxisAlignment, Flex, MainAxisAlignment, MouseStateHandle, ParentElement, Text, }; @@ -7,6 +6,7 @@ use galaxyui::platform::Cursor; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use session_sharing_protocol::common::Role; use super::{BODY_PADDING, HEADER_FONT_SIZE, MODAL_PADDING, TEXT_FONT_SIZE}; use crate::appearance::Appearance; diff --git a/app/src/terminal/shared_session/settings.rs b/app/src/terminal/shared_session/settings.rs index 86b0d527..e14ba33e 100644 --- a/app/src/terminal/shared_session/settings.rs +++ b/app/src/terminal/shared_session/settings.rs @@ -1,7 +1,9 @@ use std::time::Duration; use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; define_settings_group!(SharedSessionSettings, settings: [ onboarding_block_shown: SessionSharingOnboardingBlockShown { diff --git a/app/src/terminal/shared_session/share_modal/body.rs b/app/src/terminal/shared_session/share_modal/body.rs index 0a12775a..de93c6f6 100644 --- a/app/src/terminal/shared_session/share_modal/body.rs +++ b/app/src/terminal/shared_session/share_modal/body.rs @@ -2,7 +2,6 @@ use std::default::Default; use std::sync::Arc; use byte_unit::Byte; -use parking_lot::FairMutex; use galaxy_core::features::FeatureFlag; use galaxyui::elements::{ Container, Flex, MainAxisSize, MouseStateHandle, ParentElement, Shrinkable, Text, @@ -13,6 +12,7 @@ use galaxyui::ui_components::components::UiComponent; use galaxyui::ui_components::radio_buttons::{ RadioButtonItem, RadioButtonLayout, RadioButtonStateHandle, }; +use parking_lot::FairMutex; use warpui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; use super::style::{self, BUTTON_GAP, MODAL_MARGIN}; diff --git a/app/src/terminal/shared_session/share_modal/body_tests.rs b/app/src/terminal/shared_session/share_modal/body_tests.rs index e47705b6..baa75044 100644 --- a/app/src/terminal/shared_session/share_modal/body_tests.rs +++ b/app/src/terminal/shared_session/share_modal/body_tests.rs @@ -1,8 +1,7 @@ use std::sync::Arc; -use parking_lot::FairMutex; - use galaxyui::App; +use parking_lot::FairMutex; use super::Body; use crate::terminal::shared_session::{ diff --git a/app/src/terminal/shared_session/share_modal/mod.rs b/app/src/terminal/shared_session/share_modal/mod.rs index 68ca870d..8402fabe 100644 --- a/app/src/terminal/shared_session/share_modal/mod.rs +++ b/app/src/terminal/shared_session/share_modal/mod.rs @@ -3,15 +3,14 @@ use std::sync::Arc; use galaxy_core::ui::appearance::Appearance; use galaxyui::keymap::FixedBinding; -use galaxyui::EntityId; -use parking_lot::FairMutex; -use style::{DENIED_MODAL_WIDTH, MODAL_HEIGHT, MODAL_WIDTH}; use galaxyui::presenter::ChildView; use galaxyui::ui_components::components::UiComponentStyles; use galaxyui::{ AppContext, Element, Entity, EntityId, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use parking_lot::FairMutex; +use style::{DENIED_MODAL_WIDTH, MODAL_HEIGHT, MODAL_WIDTH}; use crate::modal::{Modal, ModalEvent}; use crate::pane_group::TerminalPaneId; diff --git a/app/src/terminal/shared_session/sharer/network.rs b/app/src/terminal/shared_session/sharer/network.rs index 9c034400..f09f9496 100644 --- a/app/src/terminal/shared_session/sharer/network.rs +++ b/app/src/terminal/shared_session/sharer/network.rs @@ -16,6 +16,9 @@ use byte_unit::{Byte, UnitType}; use futures_util::stream::AbortHandle; use futures_util::{SinkExt, StreamExt}; use galaxy_core::features::FeatureFlag; +use galaxy_server_client::iap::IapManager; +use galaxyui::r#async::Timer; +use galaxyui::{Entity, ModelContext, RequestState, RetryOption, SingletonEntity}; use instant::Instant; use parking_lot::FairMutex; use session_sharing_protocol::common::{ @@ -39,9 +42,6 @@ use session_sharing_protocol::sharer::{ SessionTerminatedReason, TeamAccessLevelUpdateResponse, UpdatePendingUserRoleResponse, UpstreamMessage, }; -use galaxy_server_client::iap::IapManager; -use galaxyui::r#async::Timer; -use galaxyui::{Entity, ModelContext, RequestState, RetryOption, SingletonEntity}; use websocket::{Message, Sink, Stream, WebSocket, WebsocketMessage as _}; use crate::auth::{AuthStateProvider, UserUid}; diff --git a/app/src/terminal/shared_session/sharer/network_tests.rs b/app/src/terminal/shared_session/sharer/network_tests.rs index d086a352..1eb76a2d 100644 --- a/app/src/terminal/shared_session/sharer/network_tests.rs +++ b/app/src/terminal/shared_session/sharer/network_tests.rs @@ -2,6 +2,8 @@ use std::sync::Arc; use async_channel::Sender; use futures_util::stream::AbortHandle; +use galaxy_server_client::iap::IapManager; +use galaxyui::{App, ModelHandle}; use instant::Instant; use parking_lot::FairMutex; use session_sharing_protocol::common::{ @@ -11,8 +13,6 @@ use session_sharing_protocol::common::{ use session_sharing_protocol::sharer::{ DownstreamMessage, FailedToInitializeSessionReason, QuotaType, ReconnectToken, UpstreamMessage, }; -use galaxy_server_client::iap::IapManager; -use galaxyui::{App, ModelHandle}; use websocket::{Message, WebsocketMessage as _}; use super::{ diff --git a/app/src/terminal/shared_session/viewer/event_loop.rs b/app/src/terminal/shared_session/viewer/event_loop.rs index 53fcbb35..e1ebebbf 100644 --- a/app/src/terminal/shared_session/viewer/event_loop.rs +++ b/app/src/terminal/shared_session/viewer/event_loop.rs @@ -2,11 +2,11 @@ use std::collections::HashMap; use std::io::{sink, Sink}; use std::sync::Arc; +use galaxyui::{Entity, ModelContext, SingletonEntity, WeakViewHandle}; use parking_lot::FairMutex; use session_sharing_protocol::common::{ OrderedTerminalEvent, OrderedTerminalEventType, Scrollback, WindowSize, }; -use galaxyui::{Entity, ModelContext, SingletonEntity, WeakViewHandle}; use crate::ai::agent::AIAgentActionId; use crate::ai::blocklist::block::cli_controller::LongRunningCommandControlState; diff --git a/app/src/terminal/shared_session/viewer/network.rs b/app/src/terminal/shared_session/viewer/network.rs index 920cbfed..c7bf004e 100644 --- a/app/src/terminal/shared_session/viewer/network.rs +++ b/app/src/terminal/shared_session/viewer/network.rs @@ -10,6 +10,12 @@ use anyhow::bail; use async_channel::Receiver; use futures_util::stream::AbortHandle; use futures_util::{SinkExt, StreamExt}; +use galaxy_core::features::FeatureFlag; +use galaxy_server_client::iap::IapManager; +use galaxyui::r#async::{SpawnedFutureHandle, Timer}; +use galaxyui::{ + Entity, ModelContext, ModelHandle, RequestState, RetryOption, SingletonEntity, WeakViewHandle, +}; use instant::Instant; use parking_lot::FairMutex; use session_sharing_protocol::common::{ @@ -27,12 +33,6 @@ use session_sharing_protocol::viewer::{ DownstreamMessage, InitPayload, RoleUpdatedReason, SessionEndedReason, UpstreamMessage, ViewerRemovedReason, }; -use galaxy_core::features::FeatureFlag; -use galaxy_server_client::iap::IapManager; -use galaxyui::r#async::{SpawnedFutureHandle, Timer}; -use galaxyui::{ - Entity, ModelContext, ModelHandle, RequestState, RetryOption, SingletonEntity, WeakViewHandle, -}; use websocket::{Message, Sink, Stream, WebsocketMessage as _}; use crate::auth::auth_state::AuthState; diff --git a/app/src/terminal/shared_session/viewer/network_tests.rs b/app/src/terminal/shared_session/viewer/network_tests.rs index ec4c48bc..acfb7af4 100644 --- a/app/src/terminal/shared_session/viewer/network_tests.rs +++ b/app/src/terminal/shared_session/viewer/network_tests.rs @@ -3,10 +3,10 @@ use std::time::Duration; use async_channel::Sender; use async_io::Timer; +use galaxyui::{App, ModelHandle}; use instant::Instant; use parking_lot::FairMutex; use session_sharing_protocol::viewer::UpstreamMessage; -use galaxyui::{App, ModelHandle}; use super::{Network, PtyBytesBatchStatus, Stage}; use crate::terminal::event_listener::ChannelEventListener; diff --git a/app/src/terminal/shared_session/viewer/orchestration_viewer_model.rs b/app/src/terminal/shared_session/viewer/orchestration_viewer_model.rs index 13a5bc38..2fc34a03 100644 --- a/app/src/terminal/shared_session/viewer/orchestration_viewer_model.rs +++ b/app/src/terminal/shared_session/viewer/orchestration_viewer_model.rs @@ -18,8 +18,8 @@ use std::collections::HashMap; use std::time::Duration; -use session_sharing_protocol::common::SessionId; use galaxy_core::features::FeatureFlag; +use session_sharing_protocol::common::SessionId; use warpui::r#async::{SpawnedFutureHandle, Timer}; use warpui::{Entity, EntityId, ModelContext, SingletonEntity, WeakViewHandle}; @@ -388,14 +388,12 @@ impl OrchestrationViewerModel { if entry.session_id.is_none() { entry.session_id = session_id; } - if was_missing_session_id - && entry.session_id.is_some() - && !entry.pane_materialization_requested - { - let conversation_id = entry.conversation_id; - let sid = entry.session_id.expect("session_id checked just above"); - entry.pane_materialization_requested = true; - self.request_child_pane_materialization(conversation_id, sid, ctx); + if was_missing_session_id && !entry.pane_materialization_requested { + if let Some(sid) = entry.session_id { + let conversation_id = entry.conversation_id; + entry.pane_materialization_requested = true; + self.request_child_pane_materialization(conversation_id, sid, ctx); + } } // Re-arm the session_id timer; no-op once all children are materialized. self.maybe_schedule_pending_session_id_poll(ctx); diff --git a/app/src/terminal/shared_session/viewer/orchestration_viewer_model_tests.rs b/app/src/terminal/shared_session/viewer/orchestration_viewer_model_tests.rs index c6e7b663..e0d28464 100644 --- a/app/src/terminal/shared_session/viewer/orchestration_viewer_model_tests.rs +++ b/app/src/terminal/shared_session/viewer/orchestration_viewer_model_tests.rs @@ -1769,7 +1769,6 @@ fn viewer_model_does_not_register_when_active_conversation_is_a_child_placeholde // activated — which would persist the orchestration cursor on the // wrong row. - App::test((), |mut app| async move { let _streamer_guard = FeatureFlag::OrchestrationViewerStreamer.override_enabled(true); diff --git a/app/src/terminal/shared_session/viewer/terminal_manager.rs b/app/src/terminal/shared_session/viewer/terminal_manager.rs index 932ad990..2b68fdc3 100644 --- a/app/src/terminal/shared_session/viewer/terminal_manager.rs +++ b/app/src/terminal/shared_session/viewer/terminal_manager.rs @@ -2,6 +2,10 @@ use std::any::Any; use std::sync::Arc; use async_broadcast::InactiveReceiver; +use galaxyui::{ + AppContext, ModelContext, ModelHandle, SingletonEntity, ViewContext, ViewHandle, + WeakViewHandle, WindowId, +}; use parking_lot::FairMutex; use pathfinder_geometry::vector::Vector2F; use session_sharing_protocol::common::{ @@ -13,10 +17,6 @@ use session_sharing_protocol::common::{ use session_sharing_protocol::sharer::SessionSourceType; use session_sharing_protocol::viewer::SessionEndedReason; use settings::Setting as _; -use galaxyui::{ - AppContext, ModelContext, ModelHandle, SingletonEntity, ViewContext, ViewHandle, - WeakViewHandle, WindowId, -}; use super::event_loop::SharedSessionInitialLoadMode; use super::network::{ diff --git a/app/src/terminal/terminal_manager.rs b/app/src/terminal/terminal_manager.rs index ea2c85c2..fdf31b94 100644 --- a/app/src/terminal/terminal_manager.rs +++ b/app/src/terminal/terminal_manager.rs @@ -2,10 +2,10 @@ use std::any::Any; use std::path::PathBuf; use std::sync::Arc; +use galaxyui::{AppContext, SingletonEntity}; use parking_lot::FairMutex; use pathfinder_geometry::vector::Vector2F; use settings::Setting as _; -use galaxyui::{AppContext, SingletonEntity}; use super::event_listener::ChannelEventListener; use super::model::block::BlockSize; diff --git a/app/src/terminal/universal_developer_input.rs b/app/src/terminal/universal_developer_input.rs index ce94550b..07dcea49 100644 --- a/app/src/terminal/universal_developer_input.rs +++ b/app/src/terminal/universal_developer_input.rs @@ -4,9 +4,6 @@ use std::cell::RefCell; use std::rc::Rc; use std::sync::Arc; -use pathfinder_color::ColorU; -#[cfg(not(target_family = "wasm"))] -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::contrast::{ @@ -15,6 +12,9 @@ use galaxy_core::ui::color::contrast::{ use galaxy_core::ui::color::{coloru_with_opacity, Opacity, Rgb}; use galaxy_core::ui::theme; use galaxy_core::ui::theme::color::internal_colors; +use pathfinder_color::ColorU; +#[cfg(not(target_family = "wasm"))] +use settings::Setting as _; use warpui::elements::{ ChildView, Clipped, Container, CornerRadius, CrossAxisAlignment, Fill, Flex, MainAxisAlignment, MainAxisSize, ParentElement, Radius, Rect, Shrinkable, SizeConstraintCondition, diff --git a/app/src/terminal/view.rs b/app/src/terminal/view.rs index 9980f738..a308594f 100644 --- a/app/src/terminal/view.rs +++ b/app/src/terminal/view.rs @@ -82,6 +82,53 @@ use command_corrections::rules::generic::history::History as CommandCorrectionsH use command_corrections::rules::{Rule, RuleId as CommandCorrectionsRuleId}; use command_corrections::{correct_command, Command, Correction, HistoryItem, SessionMetadata}; use enclose::enclose; +use galaxy_core::channel::ChannelState; +use galaxy_core::command::ExitCode; +use galaxy_core::context_flag::ContextFlag; +use galaxy_core::r#async::debounce; +use galaxy_core::semantic_selection::SemanticSelection; +use galaxy_core::user_preferences::GetUserPreferences as _; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +#[cfg(feature = "local_fs")] +use galaxy_util::path::LineAndColumnArg; +use galaxy_util::path::ShellFamily; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; +use galaxyui::assets::asset_cache::{AssetCache, AssetCacheEvent}; +use galaxyui::clipboard::ClipboardContent; +use galaxyui::clipboard_utils::get_image_filepaths_from_paths; +use galaxyui::elements::new_scrollable::{ + AxisConfiguration, ClippedAxisConfiguration, DualAxisConfig, NewScrollableElement, + ScrollableAppearance, SingleAxisConfig, +}; +use galaxyui::elements::shimmering_text::ShimmeringTextStateHandle; +use galaxyui::elements::{ + get_rich_content_position_id, Align, Border, ChildAnchor, ChildView, Clipped, + ClippedScrollStateHandle, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, + DispatchEventResult, DropTarget, DropTargetData, Empty, EventHandler, Expanded, Fill, Flex, + Hoverable, Icon, LiveElement, MouseStateHandle, NewScrollable, OffsetPositioning, ParentAnchor, + ParentElement, ParentOffsetBounds, PositionedElementAnchor, PositionedElementOffsetBounds, + Radius, Rect, SavePosition, ScrollStateHandle, Scrollable, ScrollableElement, ScrollbarWidth, + Shrinkable, Stack, Text, +}; +use galaxyui::event::ModifiersState; +use galaxyui::fonts::{Cache as FontCache, FamilyId, Properties}; +use galaxyui::geometry::vector::{vec2f, Vector2F}; +use galaxyui::image_cache::ImageType; +use galaxyui::keymap::Keystroke; +use galaxyui::notification::{NotificationSendError, RequestPermissionsOutcome, UserNotification}; +use galaxyui::platform::{Cursor, OperatingSystem}; +use galaxyui::r#async::executor::Background; +use galaxyui::r#async::{SpawnedFutureHandle, Timer}; +use galaxyui::text::SelectionType; +use galaxyui::ui_components::components::UiComponent; +use galaxyui::units::{IntoLines, IntoPixels, Lines, Pixels}; +use galaxyui::windowing::WindowManager; +use galaxyui::{ + end_trace_after_next, record_trace_event, windowing, AccessibilityData, AppContext, + BlurContext, CursorInfo, Element, Entity, EntityId, EventContext, FocusContext, ModelAsRef, + ModelHandle, SingletonEntity, Tracked, TypedActionView, View, ViewAsRef, ViewContext, + ViewHandle, WeakModelHandle, WeakViewHandle, WindowId, +}; pub use init::{ init, CANCEL_COMMAND_KEYBINDING, TOGGLE_AUTOEXECUTE_MODE_KEYBINDING, TOGGLE_HIDE_CLI_RESPONSES_KEYBINDING, TOGGLE_QUEUE_NEXT_PROMPT_KEYBINDING, @@ -128,53 +175,6 @@ use sum_tree::SeekBias; use use_agent_footer::UseAgentToolbar; use uuid::Uuid; use vec1::vec1; -use galaxy_core::channel::ChannelState; -use galaxy_core::command::ExitCode; -use galaxy_core::context_flag::ContextFlag; -use galaxy_core::r#async::debounce; -use galaxy_core::semantic_selection::SemanticSelection; -use galaxy_core::user_preferences::GetUserPreferences as _; -use galaxy_util::local_or_remote_path::LocalOrRemotePath; -#[cfg(feature = "local_fs")] -use galaxy_util::path::LineAndColumnArg; -use galaxy_util::path::ShellFamily; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; -use galaxyui::assets::asset_cache::{AssetCache, AssetCacheEvent}; -use galaxyui::clipboard::ClipboardContent; -use galaxyui::clipboard_utils::get_image_filepaths_from_paths; -use galaxyui::elements::new_scrollable::{ - AxisConfiguration, ClippedAxisConfiguration, DualAxisConfig, NewScrollableElement, - ScrollableAppearance, SingleAxisConfig, -}; -use galaxyui::elements::shimmering_text::ShimmeringTextStateHandle; -use galaxyui::elements::{ - get_rich_content_position_id, Align, Border, ChildAnchor, ChildView, Clipped, - ClippedScrollStateHandle, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, - DispatchEventResult, DropTarget, DropTargetData, Empty, EventHandler, Expanded, Fill, Flex, - Hoverable, Icon, LiveElement, MouseStateHandle, NewScrollable, OffsetPositioning, ParentAnchor, - ParentElement, ParentOffsetBounds, PositionedElementAnchor, PositionedElementOffsetBounds, - Radius, Rect, SavePosition, ScrollStateHandle, Scrollable, ScrollableElement, ScrollbarWidth, - Shrinkable, Stack, Text, -}; -use galaxyui::event::ModifiersState; -use galaxyui::fonts::{Cache as FontCache, FamilyId, Properties}; -use galaxyui::geometry::vector::{vec2f, Vector2F}; -use galaxyui::image_cache::ImageType; -use galaxyui::keymap::Keystroke; -use galaxyui::notification::{NotificationSendError, RequestPermissionsOutcome, UserNotification}; -use galaxyui::platform::{Cursor, OperatingSystem}; -use galaxyui::r#async::executor::Background; -use galaxyui::r#async::{SpawnedFutureHandle, Timer}; -use galaxyui::text::SelectionType; -use galaxyui::ui_components::components::UiComponent; -use galaxyui::units::{IntoLines, IntoPixels, Lines, Pixels}; -use galaxyui::windowing::WindowManager; -use galaxyui::{ - end_trace_after_next, record_trace_event, windowing, AccessibilityData, AppContext, - BlurContext, CursorInfo, Element, Entity, EntityId, EventContext, FocusContext, ModelAsRef, - ModelHandle, SingletonEntity, Tracked, TypedActionView, View, ViewAsRef, ViewContext, - ViewHandle, WeakModelHandle, WeakViewHandle, WindowId, -}; use self::link_detection::HighlightedLinkOption; pub use self::link_detection::{GridHighlightedLink, RichContentLink, RichContentLinkTooltipInfo}; @@ -504,7 +504,7 @@ use crate::terminal::{ CellSizeAndWindowPadding, History, HistoryEntry, ShellHost, ShellLaunchData, SizeInfo, SizeUpdate, SizeUpdateReason, }; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::throttle::throttle; use crate::ui_components::icons::{self}; use crate::util::bindings::{ @@ -2690,6 +2690,7 @@ pub struct TerminalView { queued_prompt_callback: Option, last_observed_conversation_status: HashMap, last_observed_active_subagent: HashMap, + usage_footer_view_ids: HashMap, /// View ID of the context window debug view, if visible. context_view_id: Option, @@ -3569,10 +3570,10 @@ impl TerminalView { ); ctx.notify(); } - TerminalSettingsChangedEvent::AltScreenPadding { .. } => { - if me.model.lock().is_alt_screen_active() { - me.refresh_size(ctx); - } + TerminalSettingsChangedEvent::AltScreenPadding { .. } + if me.model.lock().is_alt_screen_active() => + { + me.refresh_size(ctx); } _ => {} }, @@ -4271,6 +4272,8 @@ impl TerminalView { input, inline_menu_positioner, view_handle: ctx.handle(), + context_view_id: None, + settings_view_id: None, size_info: size_info.into(), snackbar_header_state: Default::default(), colors, @@ -5286,9 +5289,7 @@ impl TerminalView { ) { ctx.emit(Event::FreeTierLimitCheckTriggered); } - if let BlocklistAIControllerEvent::SentRequest { model_id, .. } = event { - self.maybe_insert_aws_bedrock_login_banner(model_id, ctx); - } + if let BlocklistAIControllerEvent::ExecuteLocalHarnessCommand { command } = event { self.execute_command_or_set_pending(command, ctx); } @@ -6885,103 +6886,6 @@ impl TerminalView { return; } - // Get the conversation from the history model - let Some(conversation) = - BlocklistAIHistoryModel::as_ref(ctx).conversation(&conversation_id) - else { - log::error!("Could not find conversation for usage footer"); - return; - }; - - let tool_usage = conversation.tool_usage_metadata(); - let time_to_first_token_ms = conversation.time_to_first_token_for_last_user_query_ms(); - let total_agent_response_time_ms = - conversation.total_agent_response_time_since_last_user_query_ms(); - let wall_to_wall_response_time_ms = - conversation.wall_to_wall_response_time_since_last_query(); - - let conversation_usage_info = ConversationUsageInfo { - credits_spent: conversation.inference_credits_spent(), - platform_credits_spent: conversation.platform_credits_spent(), - credits_spent_for_last_block: conversation.credits_spent_for_last_block(), - tool_calls: tool_usage.total_tool_calls(), - models: conversation.token_usage().to_vec(), - context_window_usage: conversation.context_window_usage(), - context_window_segments: conversation.context_window_segments().to_vec(), - files_changed: tool_usage.apply_file_diff_stats.files_changed, - lines_added: tool_usage.apply_file_diff_stats.lines_added, - lines_removed: tool_usage.apply_file_diff_stats.lines_removed, - commands_executed: tool_usage.run_command_stats.commands_executed, - }; - - let timing_info = TimingInfo { - time_to_first_token_ms, - total_agent_response_time_ms, - wall_to_wall_response_time_ms, - }; - - // View to hold the usage footer. Always route through the - // rollup-aware constructor so the view subscribes to history - // events and re-renders when any contributing agent's usage - // updates. The rollup itself is computed at render time and is - // self-gating: conversations without descendants short-circuit - // to today's UI inside `ConversationUsageView::render`, so no - // feature flag check is needed at the call site. - // - // Use `add_typed_action_view` (not `add_view`) so the framework - // registers `ConversationUsageView::handle_action`. Without this, - // typed actions like `ToggleDetailsExpanded` / `ShowAllAgentRows` - // dispatched from the view's own click handlers would be logged - // as `Dispatched action has no handlers` and silently ignored. - let usage_view = ctx.add_typed_action_view(|ctx| { - ConversationUsageView::new_footer_with_rollup( - conversation_usage_info, - Some(timing_info), - MouseStateHandle::default(), - conversation_id, - ctx, - ) - }); - self.usage_footer_view_ids - .insert(source_ai_block_view_id, usage_view.id()); - - let agent_view_conversation_id = self - .agent_view_controller - .as_ref(ctx) - .agent_view_state() - .active_conversation_id(); - - let item = RichContentItem::new(None, usage_view.id(), agent_view_conversation_id, false); - - let mut model = self.model.lock(); - let inserted = model.block_list_mut().insert_rich_content_after_item( - RemovableBlocklistItem::RichContent(source_ai_block_view_id), - item, - ); - drop(model); - - if inserted { - self.rich_content_views.push( - RichContent::new(usage_view, agent_view_conversation_id) - .with_metadata(RichContentMetadata::UsageFooter), - ); - } else { - // Fallback: append usage block to the end of the blocklist - self.insert_rich_content( - None, - usage_view, - Some(RichContentMetadata::UsageFooter), - RichContentInsertionPosition::Append { - insert_below_long_running_block: true, - }, - ctx, - ); - } - - ctx.notify(); - } - - fn toggle_usage_footer(&mut self, ctx: &mut ViewContext) { let conversation_id = self .agent_view_controller .as_ref(ctx) @@ -10753,71 +10657,6 @@ impl TerminalView { ); } - /// Checks if the current model request could be served via AWS Bedrock and the user - /// isn't already using it. If so, inserts a banner prompting the user to log in. - /// - /// The banner is shown when the user could be using AWS Bedrock to save on warp AI spend, but isn't. - fn maybe_insert_aws_bedrock_login_banner( - &mut self, - model_id: &LLMId, - ctx: &mut ViewContext, - ) { - // Don't show if already displayed - if self.inline_banners_state.aws_bedrock_login_banner.is_some() { - return; - } - - // Check if dismissed (either permanently via "Don't show again" or for this session via "X") - if ByoLlmAuthBannerSessionState::as_ref(ctx).is_dismissed() { - return; - } - - // Check if AWS Bedrock is available in the workspace - if !UserWorkspaces::as_ref(ctx).is_bedrock_enabled(ctx) { - return; - } - - // Check if the model supports AWS Bedrock routing - let llm_prefs = LLMPreferences::as_ref(ctx); - let Some(llm_info) = llm_prefs.get_llm_info(model_id) else { - return; - }; - - let supports_aws_bedrock = llm_info - .host_configs - .get(&LLMModelHost::AwsBedrock) - .is_some_and(|config| config.enabled); - if !supports_aws_bedrock { - return; - } - - if matches!( - ApiKeyManager::as_ref(ctx).aws_credentials_state(), - AwsCredentialsState::Loaded { .. } - ) { - return; - } - - // User doesn't have AWS credentials - show the banner - let banner_id = self.inline_banners_state.next_banner_id(); - self.inline_banners_state.aws_bedrock_login_banner = Some(AwsBedrockLoginBannerState { - id: banner_id, - login_button_mouse_state: Default::default(), - dismiss_button_mouse_state: Default::default(), - dont_show_again_button_mouse_state: Default::default(), - }); - - self.model - .lock() - .block_list_mut() - .append_inline_banner_with_custom_height( - InlineBannerItem::new(banner_id, InlineBannerType::AwsBedrockLogin), - 3.5, - ); - - ctx.notify(); - } - fn remove_aws_cli_not_installed_banner(&mut self, ctx: &mut ViewContext) { if let Some(banner_state) = self .inline_banners_state @@ -15104,7 +14943,7 @@ impl TerminalView { correct_command( command, &session_metadata, - DEFAULT_IGNORED_RULES_FOR_COMMAND_CORRECTIONS.into_iter(), + *DEFAULT_IGNORED_RULES_FOR_COMMAND_CORRECTIONS, ) } } @@ -24628,6 +24467,7 @@ impl TerminalView { } fn context_menu_action(&mut self, action: &ContextMenuAction, ctx: &mut ViewContext) { + use ContextMenuAction::*; // TODO: handle sharing session with > 1 block selected let source = SharedSessionActionSource::BlocklistContextMenu { @@ -25001,7 +24841,7 @@ impl TerminalView { action: &InputContextMenuAction, ctx: &mut ViewContext, ) { - + use InputContextMenuAction::*; match action { CutSelectedText => self.cut_selected_text_from_input(ctx), CopySelectedText => self.copy_selected_text_from_input(ctx), @@ -26418,6 +26258,7 @@ impl TypedActionView for TerminalView { } fn handle_action(&mut self, action: &TerminalAction, ctx: &mut ViewContext) { + use TerminalAction::*; let input_mode = *InputModeSettings::as_ref(ctx).input_mode.value(); match action { @@ -27305,7 +27146,7 @@ impl TypedActionView for TerminalView { #[cfg(feature = "local_fs")] ctx.emit(Event::OpenCodeInWarp { source: CodeSource::ProjectRules { - location: LocalOrRemotePath::Local(warp_md_path), + location: LocalOrRemotePath::Local(galaxy_md_path), }, layout: *crate::util::file::external_editor::EditorSettings::as_ref(ctx) .open_file_layout diff --git a/app/src/terminal/view/action.rs b/app/src/terminal/view/action.rs index fbfdba4a..6b58c6b6 100644 --- a/app/src/terminal/view/action.rs +++ b/app/src/terminal/view/action.rs @@ -4,6 +4,11 @@ use std::path::PathBuf; use ai::skills::SkillReference; use command_corrections::Correction; +use galaxy_util::user_input::UserInput; +use galaxyui::elements::HyperlinkUrl; +use galaxyui::event::ModifiersState; +use galaxyui::units::Lines; +use galaxyui::EntityId; pub use onboarding::OnboardingIntention; use pathfinder_geometry::vector::Vector2F; use session_sharing_protocol::common::Role; diff --git a/app/src/terminal/view/ambient_agent/auth_secret_ftux_dropdown.rs b/app/src/terminal/view/ambient_agent/auth_secret_ftux_dropdown.rs index 15b63b04..f5aa4020 100644 --- a/app/src/terminal/view/ambient_agent/auth_secret_ftux_dropdown.rs +++ b/app/src/terminal/view/ambient_agent/auth_secret_ftux_dropdown.rs @@ -1,7 +1,7 @@ -use warp_cli::agent::Harness; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; +use warp_cli::agent::Harness; use warp_editor::editor::NavigationKey; use warpui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, diff --git a/app/src/terminal/view/ambient_agent/auth_secret_ftux_view.rs b/app/src/terminal/view/ambient_agent/auth_secret_ftux_view.rs index 25c0ff07..2c09c3b6 100644 --- a/app/src/terminal/view/ambient_agent/auth_secret_ftux_view.rs +++ b/app/src/terminal/view/ambient_agent/auth_secret_ftux_view.rs @@ -1,7 +1,7 @@ -use warp_cli::agent::Harness; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; +use warp_cli::agent::Harness; use warp_editor::editor::NavigationKey; use warp_managed_secrets::client::SecretOwner; use warpui::elements::{ diff --git a/app/src/terminal/view/ambient_agent/auth_secret_selector.rs b/app/src/terminal/view/ambient_agent/auth_secret_selector.rs index b07adccb..c9459225 100644 --- a/app/src/terminal/view/ambient_agent/auth_secret_selector.rs +++ b/app/src/terminal/view/ambient_agent/auth_secret_selector.rs @@ -1,12 +1,12 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; -use warp_cli::agent::Harness; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; +use warp_cli::agent::Harness; use warp_managed_secrets::client::SecretOwner; use warpui::elements::{ Border, ChildAnchor, ChildView, OffsetPositioning, ParentAnchor, ParentElement as _, diff --git a/app/src/terminal/view/ambient_agent/block.rs b/app/src/terminal/view/ambient_agent/block.rs index 957885e5..c83ce667 100644 --- a/app/src/terminal/view/ambient_agent/block.rs +++ b/app/src/terminal/view/ambient_agent/block.rs @@ -4,13 +4,12 @@ mod setup_command; mod setup_command_text; pub use entry::*; +use galaxyui::prelude::Container; +use galaxyui::{AppContext, Element, ModelHandle}; pub use harness_session_header::*; pub use setup_command::*; pub use setup_command_text::*; -use galaxyui::prelude::Container; -use galaxyui::{AppContext, Element, ModelHandle}; - use super::AmbientAgentViewModel; use crate::ai::blocklist::block::view_impl::{ WithContentItemSpacing, CONTENT_ITEM_VERTICAL_MARGIN, diff --git a/app/src/terminal/view/ambient_agent/block/entry.rs b/app/src/terminal/view/ambient_agent/block/entry.rs index d185bf69..1ef7bb91 100644 --- a/app/src/terminal/view/ambient_agent/block/entry.rs +++ b/app/src/terminal/view/ambient_agent/block/entry.rs @@ -1,4 +1,3 @@ -use settings::Setting; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::Icon; @@ -14,6 +13,7 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakModelHandle, }; +use settings::Setting; use super::super::{AmbientAgentViewModelEvent, Status}; use crate::ai::agent::conversation::ConversationStatus; diff --git a/app/src/terminal/view/ambient_agent/block/setup_command.rs b/app/src/terminal/view/ambient_agent/block/setup_command.rs index 21bf7142..dd907478 100644 --- a/app/src/terminal/view/ambient_agent/block/setup_command.rs +++ b/app/src/terminal/view/ambient_agent/block/setup_command.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use parking_lot::FairMutex; use galaxy_core::ui::appearance::Appearance; use galaxy_terminal::model::BlockId; use galaxyui::prelude::{Container, Empty, MouseStateHandle}; @@ -8,6 +7,7 @@ use galaxyui::scene::{CornerRadius, Radius}; use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use parking_lot::FairMutex; use crate::ai::agent::icons::{failed_icon, yellow_running_icon}; use crate::ai::blocklist::inline_action::inline_action_header::{ diff --git a/app/src/terminal/view/ambient_agent/first_time_setup.rs b/app/src/terminal/view/ambient_agent/first_time_setup.rs index 0d5237ce..d1e1927f 100644 --- a/app/src/terminal/view/ambient_agent/first_time_setup.rs +++ b/app/src/terminal/view/ambient_agent/first_time_setup.rs @@ -3,7 +3,6 @@ //! This view is displayed as an overlay when users first try to use cloud agent mode //! and need to create an environment. -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use galaxy_core::ui::theme::{AnsiColorIdentifier, Fill}; use galaxyui::elements::new_scrollable::SingleAxisConfig; use galaxyui::elements::{ @@ -12,7 +11,10 @@ use galaxyui::elements::{ NewScrollable, ParentElement, Radius, Text, }; use galaxyui::fonts::{Properties, Weight}; -use galaxyui::{AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle}; +use galaxyui::{ + AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, +}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use crate::ai::ambient_agents::github_auth_url::{AuthSource, GithubAuthRedirectTarget}; use crate::ai::request_usage_model::AMBIENT_AGENT_TRIAL_CREDIT_THRESHOLD; diff --git a/app/src/terminal/view/ambient_agent/footer.rs b/app/src/terminal/view/ambient_agent/footer.rs index d5844c07..0a36bd6a 100644 --- a/app/src/terminal/view/ambient_agent/footer.rs +++ b/app/src/terminal/view/ambient_agent/footer.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ Border, ConstrainedBox, Container, CrossAxisAlignment, Flex, MainAxisAlignment, MainAxisSize, @@ -6,6 +5,7 @@ use galaxyui::elements::{ }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::Element; +use pathfinder_color::ColorU; use crate::ui_components::blended_colors; diff --git a/app/src/terminal/view/ambient_agent/harness_selector.rs b/app/src/terminal/view/ambient_agent/harness_selector.rs index 08140e03..5c1b6fb4 100644 --- a/app/src/terminal/view/ambient_agent/harness_selector.rs +++ b/app/src/terminal/view/ambient_agent/harness_selector.rs @@ -4,8 +4,6 @@ use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; use galaxy_cli::agent::Harness; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -18,6 +16,8 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; use crate::ai::blocklist::agent_view::agent_input_footer::AgentInputButtonTheme; use crate::ai::cloud_agent_settings::CloudAgentSettings; diff --git a/app/src/terminal/view/ambient_agent/host_selector.rs b/app/src/terminal/view/ambient_agent/host_selector.rs index f15922c4..19f5f9c1 100644 --- a/app/src/terminal/view/ambient_agent/host_selector.rs +++ b/app/src/terminal/view/ambient_agent/host_selector.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; @@ -14,6 +11,9 @@ use galaxyui::fonts::{Properties, Weight}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; use crate::ai::blocklist::inline_action::orchestration_controls::ORCHESTRATION_WARP_WORKER_HOST; use crate::ai::cloud_agent_settings::CloudAgentSettings; diff --git a/app/src/terminal/view/ambient_agent/loading_screen.rs b/app/src/terminal/view/ambient_agent/loading_screen.rs index 0810b009..7a47c6c6 100644 --- a/app/src/terminal/view/ambient_agent/loading_screen.rs +++ b/app/src/terminal/view/ambient_agent/loading_screen.rs @@ -6,8 +6,8 @@ use galaxy_core::ui::Icon; use galaxyui::elements::shimmering_text::ShimmeringTextStateHandle; use galaxyui::elements::{ Align, Border, ConstrainedBox, Container, CrossAxisAlignment, Element, Expanded, Flex, - FormattedTextElement, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, - SelectableArea, SelectionHandle, Text, + FormattedTextElement, HyperlinkLens, MainAxisAlignment, MainAxisSize, MouseStateHandle, + ParentElement, SelectableArea, SelectionHandle, Text, }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::prelude::{CornerRadius, Radius}; @@ -15,6 +15,7 @@ use galaxyui::text_layout::TextAlignment; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::UiComponent; use galaxyui::{AppContext, ModelHandle, SingletonEntity}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use crate::ai::agent_tips::{AITip, AITipModel}; use crate::ai::loading::shimmering_warp_loading_text; diff --git a/app/src/terminal/view/ambient_agent/mod.rs b/app/src/terminal/view/ambient_agent/mod.rs index d3e367d4..2fd48acc 100644 --- a/app/src/terminal/view/ambient_agent/mod.rs +++ b/app/src/terminal/view/ambient_agent/mod.rs @@ -25,6 +25,8 @@ pub use block::*; pub use first_time_setup::{FirstTimeCloudAgentSetupView, FirstTimeCloudAgentSetupViewEvent}; pub use footer::{render_error_footer, render_loading_footer}; use galaxy_core::features::FeatureFlag; +use galaxyui::geometry::vector::Vector2F; +use galaxyui::{AppContext, ModelHandle, ViewHandle, WindowId}; pub use harness_selector::{HarnessSelector, HarnessSelectorAction, HarnessSelectorEvent}; pub use host_selector::{ Host, HostSelector, HostSelectorAction, HostSelectorEvent, NakedHeaderButtonTheme, @@ -42,8 +44,6 @@ pub use model_selector::{ pub use progress::{render_progress, ProgressProps, ProgressStep, ProgressStepState}; pub use progress_ui_state::AmbientAgentProgressUIState; pub use tips::{get_cloud_mode_tips, CloudModeTip}; -use galaxyui::geometry::vector::Vector2F; -use galaxyui::{AppContext, ModelHandle, ViewHandle, WindowId}; use crate::ai::blocklist::agent_view::{AgentViewController, AgentViewState}; use crate::pane_group::TerminalViewResources; diff --git a/app/src/terminal/view/ambient_agent/model.rs b/app/src/terminal/view/ambient_agent/model.rs index 194e077d..e9908a50 100644 --- a/app/src/terminal/view/ambient_agent/model.rs +++ b/app/src/terminal/view/ambient_agent/model.rs @@ -3,12 +3,11 @@ use std::time::Duration; use galaxy_cli::agent::Harness; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; +use galaxy_terminal::model::BlockId; use galaxyui::r#async::{SpawnedFutureHandle, Timer}; -use galaxyui::{Entity, EntityId, ModelContext, SingletonEntity}; +use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity}; use instant::Instant; use session_sharing_protocol::common::SessionId; -use galaxy_terminal::model::BlockId; -use galaxyui::{AppContext, Entity, EntityId, ModelContext, SingletonEntity}; use super::AmbientAgentProgressUIState; use crate::ai::active_agent_views_model::ActiveAgentViewsModel; diff --git a/app/src/terminal/view/ambient_agent/model_selector.rs b/app/src/terminal/view/ambient_agent/model_selector.rs index 9ae95f00..d6863dc9 100644 --- a/app/src/terminal/view/ambient_agent/model_selector.rs +++ b/app/src/terminal/view/ambient_agent/model_selector.rs @@ -1,7 +1,5 @@ use std::sync::Arc; -use pathfinder_geometry::vector::vec2f; -use settings::Setting as _; use galaxy_cli::agent::Harness; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -15,6 +13,8 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; +use settings::Setting as _; use crate::ai::blocklist::agent_view::agent_input_footer::AgentInputButtonTheme; use crate::ai::cloud_agent_settings::CloudAgentSettings; diff --git a/app/src/terminal/view/ambient_agent/view_impl.rs b/app/src/terminal/view/ambient_agent/view_impl.rs index 4ff2df6e..2838f1a0 100644 --- a/app/src/terminal/view/ambient_agent/view_impl.rs +++ b/app/src/terminal/view/ambient_agent/view_impl.rs @@ -1,13 +1,13 @@ //! [`TerminalView`]-specific implementation for ambient agent functionality. -use galaxy_cli::agent::Harness; -use galaxy_terminal::model::BlockId; use std::cell::Cell; use std::rc::Rc; +use galaxy_cli::agent::Harness; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; +use galaxy_terminal::model::BlockId; use galaxyui::elements::Align; use galaxyui::prelude::{Empty, Vector2F}; use galaxyui::{ diff --git a/app/src/terminal/view/block_banner/mod.rs b/app/src/terminal/view/block_banner/mod.rs index 5447ddf7..2c0d0813 100644 --- a/app/src/terminal/view/block_banner/mod.rs +++ b/app/src/terminal/view/block_banner/mod.rs @@ -8,12 +8,12 @@ mod warpify; -pub use warpify::*; use galaxyui::elements::{ ConstrainedBox, Container, CornerRadius, Hoverable, MouseState, MouseStateHandle, ParentElement, Radius, Stack, }; use galaxyui::Element; +pub use warpify::*; use crate::themes::theme::GalaxyTheme; diff --git a/app/src/terminal/view/block_banner/warpify.rs b/app/src/terminal/view/block_banner/warpify.rs index 93ef0e45..c1f93741 100644 --- a/app/src/terminal/view/block_banner/warpify.rs +++ b/app/src/terminal/view/block_banner/warpify.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{ Align, Container, CrossAxisAlignment, Flex, MouseStateHandle, ParentElement, Shrinkable, }; @@ -7,6 +6,7 @@ use galaxyui::keymap::Keystroke; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::Element; +use pathfinder_color::ColorU; use super::render_block_banner; use crate::appearance::Appearance; diff --git a/app/src/terminal/view/block_onboarding/onboarding_drive_sharing_block.rs b/app/src/terminal/view/block_onboarding/onboarding_drive_sharing_block.rs index 07226f07..dc534670 100644 --- a/app/src/terminal/view/block_onboarding/onboarding_drive_sharing_block.rs +++ b/app/src/terminal/view/block_onboarding/onboarding_drive_sharing_block.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxyui::elements::{ Border, Container, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Text, @@ -8,6 +7,7 @@ use galaxyui::platform::Cursor; use galaxyui::ui_components::button::{ButtonVariant, TextAndIcon, TextAndIconAlignment}; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, Entity, SingletonEntity, View, ViewContext}; +use pathfinder_geometry::vector::vec2f; use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent}; use crate::drive::CloudObjectTypeAndId; diff --git a/app/src/terminal/view/block_onboarding/util.rs b/app/src/terminal/view/block_onboarding/util.rs index c385e563..85ff038b 100644 --- a/app/src/terminal/view/block_onboarding/util.rs +++ b/app/src/terminal/view/block_onboarding/util.rs @@ -1,5 +1,5 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; use warpui::elements::{ ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, MouseStateHandle, ParentElement, Radius, Shrinkable, diff --git a/app/src/terminal/view/docker_sandbox/mod.rs b/app/src/terminal/view/docker_sandbox/mod.rs index b7b09ebd..10e1b613 100644 --- a/app/src/terminal/view/docker_sandbox/mod.rs +++ b/app/src/terminal/view/docker_sandbox/mod.rs @@ -5,8 +5,6 @@ use std::path::PathBuf; #[cfg(feature = "local_tty")] use std::sync::mpsc::SyncSender; -#[cfg(not(target_family = "wasm"))] -use warp_cli::agent::Harness; #[cfg(feature = "local_tty")] use galaxyui::geometry::vector::Vector2F; #[cfg(not(target_family = "wasm"))] @@ -16,6 +14,8 @@ use galaxyui::ModelHandle; use galaxyui::ViewContext; #[cfg(not(target_family = "wasm"))] use galaxyui::{SingletonEntity, View, ViewHandle}; +#[cfg(not(target_family = "wasm"))] +use warp_cli::agent::Harness; use super::TerminalView; #[cfg(not(target_family = "wasm"))] diff --git a/app/src/terminal/view/init.rs b/app/src/terminal/view/init.rs index 1012d70c..35945248 100644 --- a/app/src/terminal/view/init.rs +++ b/app/src/terminal/view/init.rs @@ -78,7 +78,6 @@ fn init_overlapping_keybindings(app: &mut AppContext) { /// Register keybindings for [`TerminalView`] actions. pub fn init(app: &mut AppContext) { - app.register_binding_validator::(is_binding_pty_compliant); init_overlapping_keybindings(app); @@ -1105,7 +1104,6 @@ pub fn init(app: &mut AppContext) { /// Registers bindings related to input modes. fn register_input_mode_bindings(app: &mut AppContext) { - // A context predicate that matches when the input mode bindings are // available for use. Disabled when a CLI agent session is active — the // Warp agent should not be tagged into a CLI agent's command, and the diff --git a/app/src/terminal/view/init_environment/mode_selector.rs b/app/src/terminal/view/init_environment/mode_selector.rs index 1ade78c5..4271b9a3 100644 --- a/app/src/terminal/view/init_environment/mode_selector.rs +++ b/app/src/terminal/view/init_environment/mode_selector.rs @@ -1,5 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ @@ -12,6 +10,8 @@ use galaxyui::keymap::{FixedBinding, Keystroke}; use galaxyui::platform::Cursor; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/terminal/view/init_project/mod.rs b/app/src/terminal/view/init_project/mod.rs index b8252ae6..cdfb24ab 100644 --- a/app/src/terminal/view/init_project/mod.rs +++ b/app/src/terminal/view/init_project/mod.rs @@ -4,11 +4,11 @@ pub mod model; use std::path::{Path, PathBuf}; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; +use galaxy_core::ui::theme::Fill; use lsp::supported_servers::LSPServerType; use lsp_server_selector::{create_lsp_server_selector, LSPServerInfo}; pub use model::{InitProjectModel, InitProjectModelEvent, InitStepKind}; use model::{InitStepData, InitStepStatus}; -use galaxy_core::ui::theme::Fill; use warpui::elements::{ Border, ChildView, Container, CrossAxisAlignment, Empty, Flex, MouseStateHandle, ParentElement, Text, diff --git a/app/src/terminal/view/init_project/model.rs b/app/src/terminal/view/init_project/model.rs index 4d6272ff..f1b77a25 100644 --- a/app/src/terminal/view/init_project/model.rs +++ b/app/src/terminal/view/init_project/model.rs @@ -3,11 +3,11 @@ use std::path::{Path, PathBuf}; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; use ai::project_context::model::ProjectContextModel; use enum_iterator::Sequence; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui::{Entity, ModelContext, SingletonEntity as _}; use lsp::supported_servers::LSPServerType; #[cfg(not(target_family = "wasm"))] use repo_metadata::repositories::DetectedRepositories; -use galaxy_util::local_or_remote_path::LocalOrRemotePath; use crate::ai::persisted_workspace::PersistedWorkspace; use crate::settings::CodeSettings; diff --git a/app/src/terminal/view/inline_banner/mod.rs b/app/src/terminal/view/inline_banner/mod.rs index 6e52bc88..01edae4a 100644 --- a/app/src/terminal/view/inline_banner/mod.rs +++ b/app/src/terminal/view/inline_banner/mod.rs @@ -21,15 +21,6 @@ pub use alias_expansion::*; pub use anonymous_user_ai_sign_up::*; pub use aws_bedrock_login::*; pub use aws_cli_not_installed::*; -pub use notifications_discovery::*; -pub use notifications_error::*; -pub use open_in_warp::*; -pub use passive_code_diff::*; -use pathfinder_color::ColorU; -pub use session_state::*; -pub use shared_sessions::*; -pub use shell_process_terminated::*; -pub use vim_mode::*; use galaxyui::elements::{ Align, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, SavePosition, @@ -39,6 +30,15 @@ use galaxyui::fonts::{FamilyId, Properties, Weight}; use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::Element; +pub use notifications_discovery::*; +pub use notifications_error::*; +pub use open_in_warp::*; +pub use passive_code_diff::*; +use pathfinder_color::ColorU; +pub use session_state::*; +pub use shared_sessions::*; +pub use shell_process_terminated::*; +pub use vim_mode::*; pub use self::prompt_suggestions::*; use crate::appearance::Appearance; diff --git a/app/src/terminal/view/inline_banner/notifications_discovery.rs b/app/src/terminal/view/inline_banner/notifications_discovery.rs index b91f686e..102f7ef6 100644 --- a/app/src/terminal/view/inline_banner/notifications_discovery.rs +++ b/app/src/terminal/view/inline_banner/notifications_discovery.rs @@ -1,8 +1,7 @@ -use galaxyui::{elements::MouseStateHandle, notification::RequestPermissionsOutcome, Element}; -use serde::Serialize; use galaxyui::elements::MouseStateHandle; use galaxyui::notification::RequestPermissionsOutcome; use galaxyui::Element; +use serde::Serialize; use super::{ render_inline_block_list_banner, InlineBannerButtonState, InlineBannerCloseButton, diff --git a/app/src/terminal/view/inline_banner/notifications_error.rs b/app/src/terminal/view/inline_banner/notifications_error.rs index 33d74c28..f4f09736 100644 --- a/app/src/terminal/view/inline_banner/notifications_error.rs +++ b/app/src/terminal/view/inline_banner/notifications_error.rs @@ -1,8 +1,7 @@ -use galaxyui::{elements::MouseStateHandle, Element}; -use serde::Serialize; use galaxyui::elements::MouseStateHandle; use galaxyui::notification::NotificationSendError; use galaxyui::Element; +use serde::Serialize; use super::{ render_inline_block_list_banner, InlineBannerButtonState, InlineBannerCloseButton, diff --git a/app/src/terminal/view/inline_banner/prompt_suggestions.rs b/app/src/terminal/view/inline_banner/prompt_suggestions.rs index 9716dd20..129084da 100644 --- a/app/src/terminal/view/inline_banner/prompt_suggestions.rs +++ b/app/src/terminal/view/inline_banner/prompt_suggestions.rs @@ -1,10 +1,10 @@ use std::rc::Rc; -use pathfinder_geometry::vector::vec2f; -use serde::Serialize; use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::color::internal_colors::{neutral_2, neutral_3}; +use pathfinder_geometry::vector::vec2f; +use serde::Serialize; use warpui::elements::{ ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Fill, Flex, HighlightedHyperlink, Hoverable, Icon, MainAxisAlignment, MainAxisSize, diff --git a/app/src/terminal/view/inline_banner/session_state.rs b/app/src/terminal/view/inline_banner/session_state.rs index cffe0b59..fb98d997 100644 --- a/app/src/terminal/view/inline_banner/session_state.rs +++ b/app/src/terminal/view/inline_banner/session_state.rs @@ -1,3 +1,4 @@ +use galaxyui::{Entity, ModelContext, SingletonEntity}; use settings::Setting; use crate::settings::{AISettings, AISettingsChangedEvent}; @@ -22,7 +23,7 @@ impl ByoLlmAuthBannerSessionState { // Subscribe to changes in the permanent dismissal setting ctx.subscribe_to_model(&AISettings::handle(ctx), |state, _, event, ctx| { - if let AISettingsChangedEvent::AwsBedrockLoginBannerDismissed { .. } = event { + if let AISettingsChangedEvent::BedrockLoginBannerDismissed { .. } = event { let permanently_dismissed = *AISettings::as_ref(ctx) .bedrock_login_banner_dismissed .value(); diff --git a/app/src/terminal/view/load_ai_conversation.rs b/app/src/terminal/view/load_ai_conversation.rs index 0eb36bad..b32bc447 100644 --- a/app/src/terminal/view/load_ai_conversation.rs +++ b/app/src/terminal/view/load_ai_conversation.rs @@ -4,14 +4,14 @@ use std::rc::Rc; use std::sync::Arc; use chrono::{DateTime, Local}; +use galaxy_core::channel::ChannelState; +use galaxy_core::features::FeatureFlag; +use galaxyui::units::IntoPixels; +use galaxyui::{EntityId, ModelHandle, SingletonEntity, ViewContext}; use itertools::Itertools; use prost::Message; use vec1::Vec1; -use galaxy_core::channel::ChannelState; -use galaxy_core::features::FeatureFlag; use warp_multi_agent_api as api; -use galaxyui::units::IntoPixels; -use galaxyui::{EntityId, ModelHandle, SingletonEntity, ViewContext}; use super::blocklist_filter::exchanges_for_blocklist; use super::DEFAULT_AI_BLOCK_HEIGHT; @@ -951,6 +951,8 @@ impl TerminalView { autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }; // We already early-return for empty `tasks` above, so the strict diff --git a/app/src/terminal/view/open_in_warp.rs b/app/src/terminal/view/open_in_warp.rs index 8cd67066..8aecd7af 100644 --- a/app/src/terminal/view/open_in_warp.rs +++ b/app/src/terminal/view/open_in_warp.rs @@ -2,17 +2,17 @@ use std::collections::HashSet; use std::path::{Path, PathBuf}; use std::sync::Arc; -use itertools::Itertools; -use lazy_static::lazy_static; -use settings::Setting as _; use galaxy_completer::completer::TopLevelCommandCaseSensitivity; use galaxy_completer::parsers::classify_command; use galaxy_completer::parsers::hir::{Command, Expression}; use galaxy_completer::parsers::simple::all_parsed_commands; use galaxy_completer::signatures::CommandRegistry; use galaxy_util::path::EscapeChar; -use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}; use galaxyui::{SingletonEntity, ViewContext}; +use itertools::Itertools; +use lazy_static::lazy_static; +use settings::Setting as _; use super::{Event, InlineBannerItem, InlineBannerType, TerminalView}; #[cfg(feature = "local_fs")] diff --git a/app/src/terminal/view/pane_impl.rs b/app/src/terminal/view/pane_impl.rs index 8ff2eb65..f8a6d537 100644 --- a/app/src/terminal/view/pane_impl.rs +++ b/app/src/terminal/view/pane_impl.rs @@ -1,7 +1,7 @@ //! This module contains the implementation of `BackingView` for `TerminalView`, as well as //! business logic for integrating the terminal view with the pane infra (`crate::pane_group`). -use settings::Setting as _; use galaxy_core::context_flag::ContextFlag; +use settings::Setting as _; use warpui::elements::{ ConstrainedBox, CrossAxisAlignment, Empty, Flex, MainAxisAlignment, MainAxisSize, ParentElement, Shrinkable, diff --git a/app/src/terminal/view/plugin_instructions_block.rs b/app/src/terminal/view/plugin_instructions_block.rs index f9883952..154634f2 100644 --- a/app/src/terminal/view/plugin_instructions_block.rs +++ b/app/src/terminal/view/plugin_instructions_block.rs @@ -1,7 +1,5 @@ use std::iter; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_geometry::vector::vec2f; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, @@ -12,6 +10,8 @@ use galaxyui::fonts::{Properties, Weight}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_geometry::vector::vec2f; use crate::ai::blocklist::code_block::{ render_code_block_plain, CodeBlockOptions, CodeSnippetButtonHandles, diff --git a/app/src/terminal/view/queued_prompts_panel.rs b/app/src/terminal/view/queued_prompts_panel.rs index b114257e..6155bdec 100644 --- a/app/src/terminal/view/queued_prompts_panel.rs +++ b/app/src/terminal/view/queued_prompts_panel.rs @@ -8,11 +8,11 @@ //! completion, which the host uses to submit or update the input editor. use std::collections::HashMap; +use galaxy_core::features::FeatureFlag; +use galaxy_core::ui::theme::color::internal_colors; use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::vec2f; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::theme::color::internal_colors; use warpui::elements::new_scrollable::{NewScrollable, ScrollableAppearance, SingleAxisConfig}; use warpui::elements::{ Border, ChildAnchor, ChildView, Clipped, ClippedScrollStateHandle, ConstrainedBox, Container, diff --git a/app/src/terminal/view/shared_session/adapter.rs b/app/src/terminal/view/shared_session/adapter.rs index f4f5e82c..ff483c20 100644 --- a/app/src/terminal/view/shared_session/adapter.rs +++ b/app/src/terminal/view/shared_session/adapter.rs @@ -5,13 +5,11 @@ use std::time::Duration; use chrono::{DateTime, Local}; use galaxy_core::features::FeatureFlag; -use galaxyui::{elements::MouseStateHandle, ModelHandle, ViewContext, ViewHandle}; -use galaxyui::{AppContext, Element}; +use galaxyui::elements::MouseStateHandle; +use galaxyui::{AppContext, Element, ModelHandle, ViewContext, ViewHandle}; use markdown_parser::FormattedTextFragment; use session_sharing_protocol::common::{ParticipantId, ParticipantList, Role, SessionId}; use session_sharing_protocol::sharer::SessionSourceType; -use galaxyui::elements::MouseStateHandle; -use galaxyui::{AppContext, Element, ModelHandle, ViewContext, ViewHandle}; use super::sharer::Sharer; use super::viewer::Viewer; diff --git a/app/src/terminal/view/shared_session/cloud_conversation_continuation_tests.rs b/app/src/terminal/view/shared_session/cloud_conversation_continuation_tests.rs index 7ac45c52..6116c7fb 100644 --- a/app/src/terminal/view/shared_session/cloud_conversation_continuation_tests.rs +++ b/app/src/terminal/view/shared_session/cloud_conversation_continuation_tests.rs @@ -279,6 +279,7 @@ fn server_conversation_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: server_metadata(creator_uid), creator: None, diff --git a/app/src/terminal/view/shared_session/sharer/mod.rs b/app/src/terminal/view/shared_session/sharer/mod.rs index df7b819a..93c35c19 100644 --- a/app/src/terminal/view/shared_session/sharer/mod.rs +++ b/app/src/terminal/view/shared_session/sharer/mod.rs @@ -1,9 +1,9 @@ pub mod inactivity_modal; use async_channel::Sender; -use inactivity_modal::InactivityModal; use galaxyui::elements::MouseStateHandle; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{SingletonEntity, ViewContext, ViewHandle}; +use inactivity_modal::InactivityModal; use crate::terminal::shared_session::settings::SharedSessionSettings; use crate::terminal::TerminalView; diff --git a/app/src/terminal/view/shared_session/view_impl.rs b/app/src/terminal/view/shared_session/view_impl.rs index 54ffa743..64fd85cb 100644 --- a/app/src/terminal/view/shared_session/view_impl.rs +++ b/app/src/terminal/view/shared_session/view_impl.rs @@ -1,6 +1,9 @@ //! [`TerminalView`]-specific implementation for shared sessions. use chrono::{DateTime, Local}; +use galaxy_core::features::FeatureFlag; +use galaxy_core::semantic_selection::SemanticSelection; +use galaxy_core::ui::appearance::Appearance; use itertools::Itertools; use session_sharing_protocol::common::{ ParticipantId, ParticipantList, ParticipantPresenceUpdate, Role, RoleRequestId, @@ -9,9 +12,6 @@ use session_sharing_protocol::common::{ use session_sharing_protocol::sharer::{RoleUpdateReason, SessionEndedReason, SessionSourceType}; use session_sharing_protocol::viewer::RoleUpdatedReason; use settings::Setting as _; -use galaxy_core::features::FeatureFlag; -use galaxy_core::semantic_selection::SemanticSelection; -use galaxy_core::ui::appearance::Appearance; use warpui::clipboard::ClipboardContent; use warpui::elements::MouseStateHandle; use warpui::platform::Cursor; diff --git a/app/src/terminal/view/shared_session/view_impl_tests.rs b/app/src/terminal/view/shared_session/view_impl_tests.rs index 09c9b857..00ed977a 100644 --- a/app/src/terminal/view/shared_session/view_impl_tests.rs +++ b/app/src/terminal/view/shared_session/view_impl_tests.rs @@ -632,6 +632,7 @@ fn server_conversation_metadata( token_usage: vec![], tool_usage_metadata: Default::default(), context_window_segments: Vec::new(), + ..Default::default() }, metadata: ServerMetadata { uid: ServerId::default(), diff --git a/app/src/terminal/view/shared_session/viewer.rs b/app/src/terminal/view/shared_session/viewer.rs index 96b6884a..acd5863f 100644 --- a/app/src/terminal/view/shared_session/viewer.rs +++ b/app/src/terminal/view/shared_session/viewer.rs @@ -1,6 +1,6 @@ -use session_sharing_protocol::common::{Role, WindowSize}; use galaxyui::elements::MouseStateHandle; use galaxyui::{ViewContext, ViewHandle}; +use session_sharing_protocol::common::{Role, WindowSize}; use super::adapter::Participant; use crate::menu::{Menu, MenuItem, MenuItemFields}; diff --git a/app/src/terminal/view/shell_terminated_banner.rs b/app/src/terminal/view/shell_terminated_banner.rs index c7c5cd5b..91bde598 100644 --- a/app/src/terminal/view/shell_terminated_banner.rs +++ b/app/src/terminal/view/shell_terminated_banner.rs @@ -4,7 +4,7 @@ use std::cell::RefCell; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::*; use galaxyui::text_layout::ClipConfig; diff --git a/app/src/terminal/view/ssh_file_upload.rs b/app/src/terminal/view/ssh_file_upload.rs index ae2b5ea1..0ba43953 100644 --- a/app/src/terminal/view/ssh_file_upload.rs +++ b/app/src/terminal/view/ssh_file_upload.rs @@ -1,10 +1,6 @@ use std::collections::HashMap; use std::path::Path; -use itertools::Itertools; -use markdown_parser::{ - FormattedText, FormattedTextFragment, FormattedTextHeader, FormattedTextLine, -}; use galaxy_core::command::ExitCode; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::blend::Blend as _; @@ -15,6 +11,10 @@ use galaxyui::elements::{ use galaxyui::ui_components::button::ButtonVariant; use galaxyui::ui_components::components::UiComponent as _; use galaxyui::{Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use itertools::Itertools; +use markdown_parser::{ + FormattedText, FormattedTextFragment, FormattedTextHeader, FormattedTextLine, +}; use crate::terminal::ssh::util::InteractiveSshCommand; use crate::ui_components::buttons::icon_button; diff --git a/app/src/terminal/view/ssh_remote_server_choice_view.rs b/app/src/terminal/view/ssh_remote_server_choice_view.rs index 8b30ca3c..39659d38 100644 --- a/app/src/terminal/view/ssh_remote_server_choice_view.rs +++ b/app/src/terminal/view/ssh_remote_server_choice_view.rs @@ -16,7 +16,6 @@ //! //! Dismissing the block (on click of either option, or when the session is //! deregistered) is the parent's responsibility. -use settings::Setting; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ Border, ChildView, Container, CornerRadius, CrossAxisAlignment, Flex, Hoverable, @@ -28,6 +27,7 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use settings::Setting; use crate::ai::blocklist::block::keyboard_navigable_buttons::{ rich_navigation_button, KeyboardNavigableButtons, diff --git a/app/src/terminal/view/ssh_remote_server_failed_banner.rs b/app/src/terminal/view/ssh_remote_server_failed_banner.rs index 7c9dd95f..f9b3500c 100644 --- a/app/src/terminal/view/ssh_remote_server_failed_banner.rs +++ b/app/src/terminal/view/ssh_remote_server_failed_banner.rs @@ -1,13 +1,13 @@ //! Banner shown when the remote-server binary check, installation, or connection fails on the remote host. //! We fall back to the existing Warpification behavior and display this banner so the user knows why advanced features are unavailable. -use remote_server::transport::UserFacingError; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::AnsiColorIdentifier; use galaxyui::elements::{ ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Shrinkable, Text, }; +use remote_server::transport::UserFacingError; use warpui::platform::Cursor; use warpui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; diff --git a/app/src/terminal/view/testing.rs b/app/src/terminal/view/testing.rs index ec4053f0..ece9e3d6 100644 --- a/app/src/terminal/view/testing.rs +++ b/app/src/terminal/view/testing.rs @@ -42,6 +42,7 @@ impl TerminalView { is_cloud_mode: bool, ctx: &mut ViewContext, ) -> Self { + use galaxyui::units::{IntoPixels, Pixels}; use pathfinder_geometry::vector::vec2f; use crate::server::server_api::ServerApiProvider; diff --git a/app/src/terminal/view/tooltips.rs b/app/src/terminal/view/tooltips.rs index d887e994..4ced4bfc 100644 --- a/app/src/terminal/view/tooltips.rs +++ b/app/src/terminal/view/tooltips.rs @@ -1,10 +1,11 @@ //! Grid tooltips for the terminal view -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ ChildAnchor, Dismiss, MouseStateHandle, OffsetPositioning, PositionedElementAnchor, PositionedElementOffsetBounds, Stack, }; +use galaxyui::SingletonEntity; +use pathfinder_geometry::vector::vec2f; use warpui::{AppContext, Element, EventContext}; use super::{TerminalAction, TerminalView}; diff --git a/app/src/terminal/view/use_agent_footer/mod.rs b/app/src/terminal/view/use_agent_footer/mod.rs index be11fb35..9ef35425 100644 --- a/app/src/terminal/view/use_agent_footer/mod.rs +++ b/app/src/terminal/view/use_agent_footer/mod.rs @@ -23,8 +23,6 @@ use std::sync::{Arc, LazyLock}; use std::time::Duration; use anyhow::anyhow; -use parking_lot::FairMutex; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::settings::Setting; use galaxy_core::ui::appearance::Appearance; @@ -35,7 +33,6 @@ use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill as ThemeFill; use galaxy_core::{report_error, send_telemetry_from_ctx}; use galaxy_terminal::model::escape_sequences::{BRACKETED_PASTE_END, BRACKETED_PASTE_START}; -use warpify_footer::{WarpifyFooterView, WarpifyFooterViewEvent}; use galaxyui::elements::{ ChildView, Container, CrossAxisAlignment, Empty, Expanded, Flex, MainAxisSize, ParentElement, }; @@ -45,6 +42,9 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use parking_lot::FairMutex; +use pathfinder_color::ColorU; +use warpify_footer::{WarpifyFooterView, WarpifyFooterViewEvent}; use super::{RichContentInsertionPosition, TerminalAction, TerminalView}; use crate::ai::blocklist::agent_view::agent_view_bg_fill; @@ -1276,6 +1276,10 @@ pub enum UseAgentToolbarEvent { Warpify, /// User chose to use the agent. UseAgent, + StartRemoteControl { + scrollback_type: SharedSessionScrollbackType, + }, + StopRemoteControl, } impl Entity for UseAgentToolbar { diff --git a/app/src/terminal/view/use_agent_footer/warpify_footer.rs b/app/src/terminal/view/use_agent_footer/warpify_footer.rs index b19ba291..a98684c7 100644 --- a/app/src/terminal/view/use_agent_footer/warpify_footer.rs +++ b/app/src/terminal/view/use_agent_footer/warpify_footer.rs @@ -1,11 +1,11 @@ use std::sync::Arc; -use parking_lot::FairMutex; use galaxyui::elements::{ ChildView, Container, CrossAxisAlignment, Expanded, Flex, MainAxisSize, ParentElement, }; use galaxyui::prelude::Empty; use galaxyui::{AppContext, Element, Entity, TypedActionView, View, ViewContext, ViewHandle}; +use parking_lot::FairMutex; use super::{AgentFooterButtonTheme, USE_AGENT_KEYSTROKE}; use crate::terminal::view::{TerminalModel, PADDING_LEFT}; diff --git a/app/src/terminal/view/zero_state_block.rs b/app/src/terminal/view/zero_state_block.rs index cede50ea..1349dc5a 100644 --- a/app/src/terminal/view/zero_state_block.rs +++ b/app/src/terminal/view/zero_state_block.rs @@ -1,4 +1,3 @@ -use settings::Setting; use galaxy_core::report_if_error; use galaxy_core::ui::Icon; use galaxyui::elements::{ @@ -14,6 +13,7 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use settings::Setting; use crate::ai::blocklist::agent_view::{ AgentViewController, AgentViewControllerEvent, AgentViewEntryOrigin, diff --git a/app/src/terminal/view_tests.rs b/app/src/terminal/view_tests.rs index 90310b32..bafb4982 100644 --- a/app/src/terminal/view_tests.rs +++ b/app/src/terminal/view_tests.rs @@ -7,13 +7,13 @@ use std::str::FromStr; use std::sync::Arc; use chrono::Local; -use parking_lot::FairMutex; -use session_sharing_protocol::common::CLIAgentSessionState; use galaxy_cli::agent::Harness; use galaxy_terminal::model::escape_sequences::{BRACKETED_PASTE_END, BRACKETED_PASTE_START, C0}; use galaxyui::notification::UserNotification; use galaxyui::platform::WindowStyle; use galaxyui::{App, EntityIdSet, Presenter, ReadModel, WindowInvalidation}; +use parking_lot::FairMutex; +use session_sharing_protocol::common::CLIAgentSessionState; use super::*; use crate::ai::agent::conversation::{AIConversation, ConversationStatus}; @@ -70,6 +70,7 @@ use crate::terminal::shared_session::shared_handlers::{ apply_cli_agent_state_update, RemoteUpdateGuard, }; use crate::terminal::shared_session::{SharedSessionSource, SharedSessionStatus}; +use crate::terminal::view::agent_view::ENTER_AGAIN_TO_SEND_MESSAGE_ID; use crate::terminal::view::ambient_agent::AmbientAgentViewModelEvent; use crate::terminal::view::load_ai_conversation::{ RestoreConversationEntryBehavior, RestoredAIConversation, @@ -7350,7 +7351,6 @@ fn linear_deeplink_populates_input_as_draft_when_not_in_agent_view() { /// `was_in_agent_view_already` shortcut cannot promote it to auto-submit. #[test] fn linear_deeplink_does_not_auto_submit_when_already_in_agent_view() { - App::test((), |mut app| async move { initialize_app_for_terminal_view(&mut app); FeatureFlag::AgentView.set_enabled(true); @@ -7429,7 +7429,6 @@ fn linear_deeplink_does_not_auto_submit_when_already_in_agent_view() { /// auto-submit regardless of prior agent-view state. #[test] fn linear_deeplink_via_default_entrypoint_does_not_auto_submit_in_fullscreen() { - App::test((), |mut app| async move { initialize_app_for_terminal_view(&mut app); FeatureFlag::AgentView.set_enabled(true); diff --git a/app/src/terminal/warpify/mod.rs b/app/src/terminal/warpify/mod.rs index 7f7cbdd2..795a1e9b 100644 --- a/app/src/terminal/warpify/mod.rs +++ b/app/src/terminal/warpify/mod.rs @@ -103,10 +103,7 @@ fn replace_template_chars_with_arguments( for argument in arguments { let template_i = templated_bytes.iter().position(|b| b == &TEMPLATE_CHAR); if let Some(template_i) = template_i { - templated_bytes.splice( - template_i..template_i + 1, - argument.into_bytes().into_iter(), - ); + templated_bytes.splice(template_i..template_i + 1, argument.into_bytes()); } else { debug_assert!(false, "Number of arguments does not match number of template chars (%) in hardcoded subshell block bytes."); } diff --git a/app/src/terminal/warpify/render.rs b/app/src/terminal/warpify/render.rs index 46f35c30..4df57c3a 100644 --- a/app/src/terminal/warpify/render.rs +++ b/app/src/terminal/warpify/render.rs @@ -1,9 +1,5 @@ -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::elements::{ Align, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, FormattedTextElement, HighlightedHyperlink, Icon, MouseStateHandle, ParentElement, Radius, Rect, Shrinkable, Stack, @@ -12,6 +8,10 @@ use galaxyui::elements::{ use galaxyui::fonts::{FamilyId, Properties, Weight}; use galaxyui::ui_components::components::{UiComponent as _, UiComponentStyles}; use galaxyui::{AppContext, Element, EventContext, PaintContext, SingletonEntity as _}; +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; use super::settings::WarpifySettings; use super::SubshellSource; diff --git a/app/src/terminal/warpify/settings.rs b/app/src/terminal/warpify/settings.rs index 5db4d63e..b2d22536 100644 --- a/app/src/terminal/warpify/settings.rs +++ b/app/src/terminal/warpify/settings.rs @@ -1,7 +1,6 @@ use anyhow::Result; use galaxy_util::path::ShellFamily; -use galaxyui::{AppContext, ModelContext}; -use galaxyui::{Entity, SingletonEntity}; +use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; use lazy_static::lazy_static; use regex::Regex; use settings::macros::{maybe_define_setting, register_settings_events}; @@ -9,7 +8,6 @@ use settings::{ ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, }; use strum_macros::EnumIter; -use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; use crate::terminal::ssh::util::{parse_interactive_ssh_command, SshWarpifyCommand}; diff --git a/app/src/terminal/warpify/success_block.rs b/app/src/terminal/warpify/success_block.rs index 6dbf8123..07dbdb53 100644 --- a/app/src/terminal/warpify/success_block.rs +++ b/app/src/terminal/warpify/success_block.rs @@ -2,9 +2,9 @@ use std::borrow::Cow; use std::sync::Arc; use channel_versions::overrides::TargetOS; -use parking_lot::RwLock; use galaxy_core::semantic_selection::SemanticSelection; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; +use parking_lot::RwLock; use warpui::elements::{ Border, Container, CrossAxisAlignment, Flex, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, SelectableArea, SelectionHandle, Text, diff --git a/app/src/terminal/warpify/trigger_state.rs b/app/src/terminal/warpify/trigger_state.rs index bf05f700..150be7fa 100644 --- a/app/src/terminal/warpify/trigger_state.rs +++ b/app/src/terminal/warpify/trigger_state.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; use std::sync::Arc; -use parking_lot::FairMutex; use galaxy_core::ui::appearance::Appearance; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{EntityId, SingletonEntity as _, ViewContext, ViewHandle}; +use parking_lot::FairMutex; use super::success_block::WarpifySuccessBlock; use crate::terminal::model::block::BlockId; diff --git a/app/src/terminal/waterfall_gap_element.rs b/app/src/terminal/waterfall_gap_element.rs index 7369fd54..487a73ee 100644 --- a/app/src/terminal/waterfall_gap_element.rs +++ b/app/src/terminal/waterfall_gap_element.rs @@ -1,8 +1,8 @@ -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxyui::elements::{ScrollData, ScrollableElement, ZIndex}; use galaxyui::event::ModifiersState; use galaxyui::units::{IntoLines, IntoPixels, Pixels}; use galaxyui::{AppContext, Element, EventContext, ModelHandle, SizeConstraint}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::block_list_element::BlockListMenuSource; use super::view::TerminalAction; diff --git a/app/src/terminal/writeable_pty/pty_controller.rs b/app/src/terminal/writeable_pty/pty_controller.rs index 11a9577c..620aa527 100644 --- a/app/src/terminal/writeable_pty/pty_controller.rs +++ b/app/src/terminal/writeable_pty/pty_controller.rs @@ -3,11 +3,11 @@ use std::collections::VecDeque; use std::sync::Arc; use async_channel::{Receiver, Sender}; +use galaxy_util::path::ShellFamily; use galaxyui::r#async::block_on; use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity}; use parking_lot::FairMutex; use thiserror::Error; -use galaxy_util::path::ShellFamily; use super::Message; use crate::ai::agent::AIAgentPtyWriteMode; diff --git a/app/src/terminal/writeable_pty/remote_server_controller.rs b/app/src/terminal/writeable_pty/remote_server_controller.rs index be223c9f..008e167d 100644 --- a/app/src/terminal/writeable_pty/remote_server_controller.rs +++ b/app/src/terminal/writeable_pty/remote_server_controller.rs @@ -1,6 +1,8 @@ use std::path::PathBuf; use std::sync::Arc; +use galaxy_core::SessionId; +use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity, WeakModelHandle}; use instant::Instant; use remote_server::auth::RemoteServerAuthContext; use remote_server::setup::{ @@ -8,8 +10,6 @@ use remote_server::setup::{ }; use remote_server::transport::Error; use settings::Setting; -use galaxy_core::SessionId; -use galaxyui::{Entity, ModelContext, ModelHandle, SingletonEntity, WeakModelHandle}; use super::pty_controller::{EventLoopSender, PtyController}; use crate::auth::auth_state::AuthStateProvider; diff --git a/app/src/terminal/writeable_pty/terminal_manager_util.rs b/app/src/terminal/writeable_pty/terminal_manager_util.rs index 85bbb109..bcbf7497 100644 --- a/app/src/terminal/writeable_pty/terminal_manager_util.rs +++ b/app/src/terminal/writeable_pty/terminal_manager_util.rs @@ -2,9 +2,8 @@ use std::sync::mpsc::SyncSender; use std::sync::Arc; use async_channel::Receiver; -use galaxyui::{AppContext, ModelHandle, ViewHandle}; -use parking_lot::FairMutex; use galaxyui::{AppContext, Entity, ModelHandle, ViewHandle}; +use parking_lot::FairMutex; use crate::persistence::ModelEvent; use crate::terminal::line_editor_status::LineEditorStatus; diff --git a/app/src/test_util/terminal.rs b/app/src/test_util/terminal.rs index 65ddb36a..6e69a1bd 100644 --- a/app/src/test_util/terminal.rs +++ b/app/src/test_util/terminal.rs @@ -1,14 +1,14 @@ use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; #[cfg(feature = "local_fs")] use ai::skills::SKILL_PROVIDER_DEFINITIONS; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::watcher::DirectoryWatcher; -#[cfg(feature = "local_fs")] -use repo_metadata::RepoMetadataModel; use galaxy_core::ui::appearance::Appearance; use galaxy_server_client::iap::IapManager; use galaxyui::platform::WindowStyle; use galaxyui::{App, SingletonEntity, ViewHandle, WindowId}; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::watcher::DirectoryWatcher; +#[cfg(feature = "local_fs")] +use repo_metadata::RepoMetadataModel; use watcher::HomeDirectoryWatcher; use super::settings::initialize_history_persistence_for_tests; @@ -156,7 +156,7 @@ pub fn initialize_app_for_terminal_view(app: &mut App) { app.add_singleton_model(|_| GitRepoModels::new()); app.add_singleton_model(RepoOutlines::new_for_test); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); app.add_singleton_model(SkillManager::new); app.add_singleton_model(|ctx| { CodebaseIndexManager::new_for_test(ServerApiProvider::as_ref(ctx).get(), ctx) diff --git a/app/src/themes/default_themes.rs b/app/src/themes/default_themes.rs index 71a01a7d..7a65bf5a 100644 --- a/app/src/themes/default_themes.rs +++ b/app/src/themes/default_themes.rs @@ -1,12 +1,12 @@ use asset_macro::bundled_or_fetched_asset; -use pathfinder_color::ColorU; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::color::{coloru_with_opacity, OPAQUE}; use galaxy_core::ui::theme::color::CustomDetails; use galaxy_core::ui::theme::{ - AnsiColor, AnsiColors, Details, Fill, HorizontalGradient, Image, TerminalColors, - VerticalGradient, WarpTheme, + AnsiColor, AnsiColors, Details, Fill, GalaxyTheme, HorizontalGradient, Image, TerminalColors, + VerticalGradient, }; +use pathfinder_color::ColorU; const DARK_MODE_NORMAL_COLORS: AnsiColors = AnsiColors::new( AnsiColor::from_u32(0x616161FF), diff --git a/app/src/themes/theme.rs b/app/src/themes/theme.rs index 57d9f3d1..cce55365 100644 --- a/app/src/themes/theme.rs +++ b/app/src/themes/theme.rs @@ -3,7 +3,6 @@ use std::iter::FromIterator; use std::path::{Component, Path, PathBuf}; use anyhow::Result; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::color::pick_foreground_color; pub use galaxy_core::ui::theme::*; @@ -14,6 +13,7 @@ use galaxyui::elements::{ Shrinkable, Stack, Text, }; use galaxyui::fonts::FamilyId; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::default_themes::*; use super::theme_creator::{pick_accent_color_from_options, top_colors_for_image}; @@ -468,6 +468,8 @@ pub struct GalaxyThemeConfig { theme_map: HashMap, } +pub type WarpThemeConfig = GalaxyThemeConfig; + impl GalaxyThemeConfig { pub fn new() -> Self { // preload with built-in themes diff --git a/app/src/themes/theme_chooser.rs b/app/src/themes/theme_chooser.rs index ddd5b469..aaf83220 100644 --- a/app/src/themes/theme_chooser.rs +++ b/app/src/themes/theme_chooser.rs @@ -1,7 +1,5 @@ -use pathfinder_color::ColorU; -use settings::Setting as _; use galaxy_editor::editor::NavigationKey; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::elements::{ Align, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, Element, Empty, EventHandler, Fill, Flex, Hoverable, Icon, @@ -19,6 +17,8 @@ use galaxyui::{ AppContext, Entity, FocusContext, ModelHandle, SingletonEntity, Tracked, TypedActionView, UpdateModel, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use settings::Setting as _; use super::theme; use crate::appearance::{Appearance, AppearanceManager}; @@ -33,12 +33,12 @@ use crate::resource_center::{ use crate::server::telemetry::TelemetryEvent; use crate::settings::{respect_system_theme, ThemeSettings}; use crate::themes::theme::{ - RespectSystemTheme, SelectedSystemThemes, ThemeKind, WarpTheme, WarpThemeConfig, + GalaxyTheme, GalaxyThemeConfig, RespectSystemTheme, SelectedSystemThemes, ThemeKind, }; use crate::ui_components::buttons::{close_button, icon_button}; use crate::ui_components::icons; use crate::ui_components::window_focus_dimming::WindowFocusDimming; -use crate::user_config::{load_theme_configs, themes_dir, WarpConfig, WarpConfigUpdateEvent}; +use crate::user_config::{load_theme_configs, themes_dir, GalaxyConfig, GalaxyConfigUpdateEvent}; use crate::util::traffic_lights::{traffic_light_data, TrafficLightData, TrafficLightSide}; use crate::window_settings::WindowSettings; use crate::workspace::PANEL_HEADER_HEIGHT; diff --git a/app/src/themes/theme_creator_body.rs b/app/src/themes/theme_creator_body.rs index be3b6abd..7fb68666 100644 --- a/app/src/themes/theme_creator_body.rs +++ b/app/src/themes/theme_creator_body.rs @@ -4,10 +4,8 @@ use std::path::PathBuf; #[cfg(feature = "local_fs")] use std::{fs::copy, io::Write}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; #[cfg(feature = "local_fs")] -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::elements::{ Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, EventHandler, Fill, Flex, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, @@ -21,6 +19,8 @@ use galaxyui::ui_components::text_input::TextInput; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::appearance::{Appearance, AppearanceManager}; use crate::editor::{EditorView, Event as EditorEvent}; diff --git a/app/src/themes/theme_deletion_body.rs b/app/src/themes/theme_deletion_body.rs index ec57f0a5..e25bf468 100644 --- a/app/src/themes/theme_deletion_body.rs +++ b/app/src/themes/theme_deletion_body.rs @@ -16,7 +16,7 @@ use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, Vi use crate::appearance::Appearance; use crate::server::telemetry::TelemetryEvent; use crate::settings::{active_theme_kind, ThemeSettings}; -use crate::themes::theme::{ThemeKind, WarpTheme}; +use crate::themes::theme::{GalaxyTheme, ThemeKind}; use crate::user_config::util::from_yaml; use crate::{send_telemetry_from_ctx, user_config}; diff --git a/app/src/tips/mod.rs b/app/src/tips/mod.rs index 7843b3a1..c7827778 100644 --- a/app/src/tips/mod.rs +++ b/app/src/tips/mod.rs @@ -1,7 +1,6 @@ -use galaxyui::{keymap::Keystroke, AppContext}; -use serde::{Deserialize, Serialize}; use galaxyui::keymap::Keystroke; use galaxyui::AppContext; +use serde::{Deserialize, Serialize}; pub mod tip_view; pub use tip_view::{TipsEvent, TipsView}; diff --git a/app/src/tips/tip_view.rs b/app/src/tips/tip_view.rs index 90a84fed..6f11c8fb 100644 --- a/app/src/tips/tip_view.rs +++ b/app/src/tips/tip_view.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ Align, Border, ChildAnchor, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, Element, EventHandler, Flex, @@ -14,6 +13,7 @@ use galaxyui::{ Action, AppContext, BlurContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, WindowId, }; +use pathfinder_geometry::vector::vec2f; use super::WELCOME_TIP_FEATURE_LENGTH; use crate::appearance::Appearance; diff --git a/app/src/ui_components/agent_icon_tests.rs b/app/src/ui_components/agent_icon_tests.rs index 70bce427..c026a7d7 100644 --- a/app/src/ui_components/agent_icon_tests.rs +++ b/app/src/ui_components/agent_icon_tests.rs @@ -113,6 +113,7 @@ impl CanonicalRunState { /// The canonical [`AgentIconFields`] for this state. `None` means no agent icon renders. /// Editing an arm here is the deliberate way to evolve the cross-surface contract. fn expected(&self) -> Option { + use CanonicalRunState::*; match self { PlainTerminal => None, LocalOzInProgress => Some(AgentIconFields { @@ -170,6 +171,7 @@ impl CanonicalRunState { /// Terminal-view inputs for this state. Every state has a terminal representation. fn terminal_inputs(&self) -> TerminalIconInputs { + use CanonicalRunState::*; match self { PlainTerminal => TerminalIconInputs { is_ambient: false, @@ -259,6 +261,7 @@ impl CanonicalRunState { /// Run-card inputs for this state, if it can surface as a run card. /// Cards only exist for cloud/ambient runs; local states return `None`. fn run_inputs(&self) -> Option<(Harness, ConversationStatus, bool)> { + use CanonicalRunState::*; match self { CloudOzInProgress => Some((Harness::Oz, ConversationStatus::InProgress, true)), CloudClaudePreDispatch | CloudClaudeInProgress => { diff --git a/app/src/ui_components/avatar.rs b/app/src/ui_components/avatar.rs index bf6fb243..de21b152 100644 --- a/app/src/ui_components/avatar.rs +++ b/app/src/ui_components/avatar.rs @@ -1,10 +1,10 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::external_product_icon::ExternalProductIcon; use galaxy_core::ui::icons::Icon; use galaxyui::elements::{ self, Align, Border, CacheOption, ChildAnchor, ConstrainedBox, Container, Element, Image, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Stack, Text, }; +use pathfinder_geometry::vector::vec2f; use warpui::ui_components::components::{UiComponent, UiComponentStyles}; use super::red_notification_dot::RedNotificationDot; diff --git a/app/src/ui_components/breadcrumb.rs b/app/src/ui_components/breadcrumb.rs index a96d29f1..8e83fa41 100644 --- a/app/src/ui_components/breadcrumb.rs +++ b/app/src/ui_components/breadcrumb.rs @@ -1,11 +1,11 @@ use std::fmt::Debug; -use itertools::{Itertools, Position}; use galaxyui::elements::{ CrossAxisAlignment, Flex, Hoverable, MainAxisSize, MouseStateHandle, ParentElement, Shrinkable, }; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, EventContext}; +use itertools::{Itertools, Position}; use crate::appearance::Appearance; diff --git a/app/src/ui_components/buttons.rs b/app/src/ui_components/buttons.rs index e2cbccb0..e1c094c8 100644 --- a/app/src/ui_components/buttons.rs +++ b/app/src/ui_components/buttons.rs @@ -5,7 +5,7 @@ use warpui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use super::icons::{Icon, ICON_DIMENSIONS}; use super::{blended_colors, BORDER_RADIUS}; use crate::appearance::Appearance; -use crate::themes::theme::{Fill, WarpTheme}; +use crate::themes::theme::{Fill, GalaxyTheme}; const ICON_BUTTON_PADDING: f32 = 4.; diff --git a/app/src/ui_components/icon_with_status.rs b/app/src/ui_components/icon_with_status.rs index 22671538..154f43f5 100644 --- a/app/src/ui_components/icon_with_status.rs +++ b/app/src/ui_components/icon_with_status.rs @@ -11,6 +11,7 @@ use pathfinder_geometry::vector::vec2f; use crate::ai::agent::conversation::{ConversationStatus, StatusColorStyle}; use crate::terminal::CLIAgent; use crate::themes::theme::Fill as ThemeFill; +use crate::ui_components::icons::Icon as WarpIcon; /// Background color used for the Oz agent's circle when it is running in an ambient (cloud) /// run. Matches the Oz brand purple used in the cloud-mode design spec. @@ -164,8 +165,8 @@ pub(crate) fn render_icon_with_status( variant: IconWithStatusVariant, total_size: f32, overlay_extra_overhang_ratio: f32, - theme: &WarpTheme, - status_container_background: WarpThemeFill, + theme: &GalaxyTheme, + status_container_background: GalaxyThemeFill, ) -> Box { render_icon_with_status_with_badge_style( variant, @@ -184,8 +185,8 @@ pub(crate) fn render_icon_with_status_with_badge_style( total_size: f32, overlay_extra_overhang_ratio: f32, badge_style: StatusBadgeStyle, - theme: &WarpTheme, - status_container_background: WarpThemeFill, + theme: &GalaxyTheme, + status_container_background: GalaxyThemeFill, ) -> Box { let sub_text = theme.sub_text_color(theme.background()); @@ -217,7 +218,7 @@ pub(crate) fn render_icon_with_status_with_badge_style( // Cloud (ambient) runs use a black glyph on the light-purple background // for consistency with the web app; local runs keep the theme text color. let glyph_color = if is_ambient { - WarpThemeFill::Solid(ColorU::black()) + ThemeFill::Solid(ColorU::black()) } else { theme.main_text_color(theme.background()) }; @@ -289,7 +290,7 @@ pub(crate) fn render_icon_with_status_with_badge_style( /// `attach_status_overlay` to occupy the full `total_size` footprint. fn render_circle( icon_element: Box, - background: WarpThemeFill, + background: ThemeFill, total_size: f32, ) -> Box { let icon = icon_size(total_size); @@ -313,7 +314,7 @@ fn render_circle( /// requested bounding box rather than shrinking to `circle_size(total)`. fn render_neutral_circle( icon_element: Box, - background: WarpThemeFill, + background: ThemeFill, total_size: f32, ) -> Box { let glyph = total_size * NEUTRAL_GLYPH_RATIO; @@ -339,8 +340,8 @@ fn attach_status_overlay( total_size: f32, overlay_extra_overhang_ratio: f32, badge_style: StatusBadgeStyle, - theme: &WarpTheme, - status_container_background: WarpThemeFill, + theme: &GalaxyTheme, + status_container_background: GalaxyThemeFill, ) -> Box { if is_ambient { render_with_cloud_status_badge( @@ -370,12 +371,12 @@ fn render_with_cloud_status_badge( status: Option<&ConversationStatus>, total_size: f32, overlay_extra_overhang_ratio: f32, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let cloud_diameter = cloud_icon_size(total_size); let cloud = ConstrainedBox::new( WarpIcon::CloudFilled - .to_warpui_icon(theme.foreground()) + .to_galaxyui_icon(theme.foreground()) .finish(), ) .with_width(cloud_diameter) @@ -387,7 +388,7 @@ fn render_with_cloud_status_badge( let (icon, color) = status.status_icon_and_color(theme, StatusColorStyle::Cloud); let inner = status_in_cloud_size(total_size); let status_icon = - ConstrainedBox::new(icon.to_warpui_icon(WarpThemeFill::Solid(color)).finish()) + ConstrainedBox::new(icon.to_galaxyui_icon(ThemeFill::Solid(color)).finish()) .with_width(inner) .with_height(inner) .finish(); @@ -439,8 +440,8 @@ fn render_with_optional_status_badge( total_size: f32, overlay_extra_overhang_ratio: f32, badge_style: StatusBadgeStyle, - theme: &WarpTheme, - status_container_background: WarpThemeFill, + theme: &GalaxyTheme, + status_container_background: GalaxyThemeFill, ) -> Box { let Some(status) = status else { // No status badge: still occupy the full `total_size` footprint so the agent @@ -454,7 +455,7 @@ fn render_with_optional_status_badge( let (icon, color) = status.status_icon_and_color(theme, StatusColorStyle::Standard); let badge_icon_diameter = badge_icon_size(total_size, badge_style); let pad = badge_padding(total_size, badge_style); - let badge_icon = ConstrainedBox::new(icon.to_galaxyui_icon(WarpThemeFill::Solid(color)).finish()) + let badge_icon = ConstrainedBox::new(icon.to_galaxyui_icon(ThemeFill::Solid(color)).finish()) .with_width(badge_icon_diameter) .with_height(badge_icon_diameter) .finish(); diff --git a/app/src/ui_components/item_highlight.rs b/app/src/ui_components/item_highlight.rs index 5fcaf3a5..e0c6c678 100644 --- a/app/src/ui_components/item_highlight.rs +++ b/app/src/ui_components/item_highlight.rs @@ -1,6 +1,10 @@ +use galaxy_core::ui::theme::color::internal_colors; +use galaxyui::elements::{CornerRadius, MouseState, Radius}; +use galaxyui::Element; use pathfinder_color::ColorU; use crate::appearance::Appearance; +use crate::themes::theme::Fill; use crate::ui_components::blended_colors; use crate::ui_components::icons::Icon; diff --git a/app/src/ui_components/json_tree.rs b/app/src/ui_components/json_tree.rs index 57628b66..4438f8cd 100644 --- a/app/src/ui_components/json_tree.rs +++ b/app/src/ui_components/json_tree.rs @@ -7,10 +7,10 @@ use std::collections::HashMap; use std::sync::Arc; -use pathfinder_color::ColorU; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::WarpTheme; +use pathfinder_color::ColorU; use warpui::elements::{ ConstrainedBox, CrossAxisAlignment, Empty, Flex, Hoverable, MainAxisSize, MouseStateHandle, ParentElement, Shrinkable, Text, diff --git a/app/src/ui_components/json_tree_tests.rs b/app/src/ui_components/json_tree_tests.rs index 38fa43e5..d5b10439 100644 --- a/app/src/ui_components/json_tree_tests.rs +++ b/app/src/ui_components/json_tree_tests.rs @@ -4,6 +4,7 @@ //! formatting, long-string detection, state management, and value rendering. //! They do not exercise the element-construction layer (which requires a //! running UI framework). +use crate::ai::agent::CallMCPToolResult; use crate::ui_components::json_tree::{ format_array_annotation, format_number, format_object_annotation, is_long_string, JsonTreeState, PathSegment, LONG_STRING_THRESHOLD, @@ -306,7 +307,6 @@ fn multi_key_object_all_entries_preserved() { #[test] fn mcp_result_success_with_structured_content_returns_tree() { - use crate::ai::agent::CallMCPToolResult; use crate::ai::blocklist::inline_action::requested_command::{ mcp_result_to_renderable, McpRenderable, }; diff --git a/app/src/ui_components/menu_button.rs b/app/src/ui_components/menu_button.rs index 989c9529..887fff9b 100644 --- a/app/src/ui_components/menu_button.rs +++ b/app/src/ui_components/menu_button.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxyui::elements::{ ChildAnchor, ChildView, MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Stack, @@ -6,6 +5,7 @@ use galaxyui::elements::{ use galaxyui::platform::Cursor; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{AppContext, Element, EventContext, View, ViewHandle}; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use super::buttons::{highlight, icon_button}; use super::icons::Icon; diff --git a/app/src/ui_components/red_notification_dot.rs b/app/src/ui_components/red_notification_dot.rs index f9829955..9bcc7dd0 100644 --- a/app/src/ui_components/red_notification_dot.rs +++ b/app/src/ui_components/red_notification_dot.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::AnsiColorIdentifier; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, CornerRadius, Empty, Fill, OffsetPositioning, @@ -6,6 +5,7 @@ use galaxyui::elements::{ }; use galaxyui::ui_components::components::UiComponentStyles; use galaxyui::Element; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; diff --git a/app/src/undo_close/settings.rs b/app/src/undo_close/settings.rs index 9cdec409..274f3d39 100644 --- a/app/src/undo_close/settings.rs +++ b/app/src/undo_close/settings.rs @@ -1,7 +1,7 @@ use std::time::Duration; use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(UndoCloseSettings, settings: [ enabled: UndoCloseEnabled { diff --git a/app/src/undo_close/stack.rs b/app/src/undo_close/stack.rs index 12ae3a1f..d458a429 100644 --- a/app/src/undo_close/stack.rs +++ b/app/src/undo_close/stack.rs @@ -1,9 +1,9 @@ -use uuid::Uuid; use galaxyui::r#async::SpawnedFutureHandle; use galaxyui::{ AppContext, ClosedWindowData, Entity, EntityId, ModelContext, ModelHandle, SingletonEntity, ViewHandle, WeakViewHandle, WindowId, }; +use uuid::Uuid; use super::settings::UndoCloseSettingsChangedEvent; use super::UndoCloseSettings; diff --git a/app/src/uri/docker.rs b/app/src/uri/docker.rs index 8bead57a..9e2281a6 100644 --- a/app/src/uri/docker.rs +++ b/app/src/uri/docker.rs @@ -2,6 +2,8 @@ use std::collections::HashMap; use std::fmt::Display; use anyhow::{anyhow, Result}; +use galaxy_util::path::{is_posix_portable_pathname, ShellFamily}; +use galaxyui::AppContext; use regex::Regex; use url::Url; diff --git a/app/src/uri/mod.rs b/app/src/uri/mod.rs index ab70a243..1e5f3d71 100644 --- a/app/src/uri/mod.rs +++ b/app/src/uri/mod.rs @@ -23,7 +23,8 @@ use crate::ai::active_agent_views_model::{ActiveAgentViewsModel, ConversationOrT use crate::ai::agent::api::ServerConversationToken; use crate::ai::ambient_agents::github_auth_notifier::GitHubAuthNotifier; use crate::cloud_object::ObjectType; -use crate::drive::{OpenWarpDriveObjectArgs, OpenWarpDriveObjectSettings}; +use crate::code::editor_management::CodeSource; +use crate::drive::{OpenGalaxyDriveObjectArgs, OpenGalaxyDriveObjectSettings}; use crate::features::FeatureFlag; use crate::launch_configs::launch_config::LaunchConfig; use crate::linear::{LinearAction, LinearIssueWork}; @@ -38,8 +39,10 @@ use crate::settings_view::{ }; use crate::tab_configs::TabConfig; use crate::user_config::{load_launch_configs, load_tab_configs, tab_configs_dir}; +use crate::util::file::external_editor::EditorSettings; use crate::util::openable_file_type::{ - is_file_openable_in_warp, is_markdown_file, is_runnable_shell_script, starts_with_shebang, + is_file_openable_in_warp, is_markdown_file, is_runnable_shell_script, + resolve_file_target_to_open_in_warp, starts_with_shebang, }; use crate::view_components::DismissibleToast; use crate::workspace::auto_handoff::trigger_auto_handoff_to_cloud; @@ -1182,6 +1185,7 @@ impl Action { /// When handling this URI action, determine which window(s) should be focused. #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] fn window_behavior_hint(&self) -> WindowBehaviorHint { + use WindowBehaviorHint as W; match self { Self::Docker | Self::OpenFileEditor { .. } @@ -1418,7 +1422,6 @@ fn open_file_editor( ) { #[cfg(feature = "local_fs")] { - if !can_open_file_editor_path(&path) { log::warn!("open_file_editor action rejected non-openable path: {path:?}"); return; diff --git a/app/src/uri/uri_tests.rs b/app/src/uri/uri_tests.rs index a8ba7093..904d1a47 100644 --- a/app/src/uri/uri_tests.rs +++ b/app/src/uri/uri_tests.rs @@ -1,5 +1,9 @@ +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; + use self::parse_url_paths::{get_item_data_from_warp_link, WarpWebLink}; use super::*; +use crate::drive::{OpenWarpDriveObjectArgs, OpenWarpDriveObjectSettings}; use crate::launch_configs::launch_config::make_mock_single_window_launch_config; use crate::linear::{LinearAction, LinearIssueWork}; use crate::ChannelState; @@ -781,7 +785,6 @@ fn test_settings_section_for_simple_subpage() { #[test] #[cfg(unix)] fn test_open_file_executable_sh_routes_to_execute() { - use std::os::unix::fs::PermissionsExt; let dir = tempfile::tempdir().unwrap(); let p = dir.path().join("run.sh"); std::fs::write(&p, b"#!/bin/sh\n:\n").unwrap(); diff --git a/app/src/uri/web_intent_parser.rs b/app/src/uri/web_intent_parser.rs index 8ce1fb83..4dadd9ce 100644 --- a/app/src/uri/web_intent_parser.rs +++ b/app/src/uri/web_intent_parser.rs @@ -1,8 +1,8 @@ use anyhow::{anyhow, Result}; -use url::Url; -use uuid::Uuid; #[cfg(target_family = "wasm")] use galaxy_core::context_flag::ContextFlag; +use url::Url; +use uuid::Uuid; #[cfg(target_family = "wasm")] use crate::uri::browser_url_handler::parse_current_url; diff --git a/app/src/user_config/mod.rs b/app/src/user_config/mod.rs index 1e1d5638..2407f2d1 100644 --- a/app/src/user_config/mod.rs +++ b/app/src/user_config/mod.rs @@ -8,18 +8,18 @@ mod imp; use std::path::Path; use std::path::PathBuf; +use galaxy_core::ui::theme::GalaxyTheme; pub(crate) use imp::load_tab_configs; #[cfg(feature = "local_fs")] pub use imp::load_workflows; pub use imp::{load_launch_configs, load_theme_configs}; use lazy_static::lazy_static; -use galaxy_core::ui::theme::WarpTheme; use warpui::{Entity, ModelContext, SingletonEntity}; use crate::ai::custom_model_routers::{CustomModelRouter, ModelConfigError}; use crate::launch_configs::launch_config::LaunchConfig; use crate::tab_configs::{TabConfig, TabConfigError}; -use crate::themes::theme::{ThemeKind, WarpThemeConfig}; +use crate::themes::theme::{GalaxyThemeConfig, ThemeKind}; use crate::workflows::workflow::Workflow; lazy_static! { @@ -428,6 +428,9 @@ impl Entity for GalaxyConfig { impl SingletonEntity for GalaxyConfig {} +pub type WarpConfig = GalaxyConfig; +pub type WarpConfigUpdateEvent = GalaxyConfigUpdateEvent; + #[cfg(test)] #[path = "mod_tests.rs"] mod tests; diff --git a/app/src/user_config/native.rs b/app/src/user_config/native.rs index e77212bf..b8f19eee 100644 --- a/app/src/user_config/native.rs +++ b/app/src/user_config/native.rs @@ -3,10 +3,9 @@ use std::path::Path; use std::{fs, io}; use anyhow::{anyhow, Result}; -use galaxyui::{ModelContext, SingletonEntity}; +use galaxyui::{ModelContext, ModelHandle, SingletonEntity}; use itertools::Itertools; use repo_metadata::RepositoryUpdate; -use galaxyui::{ModelContext, ModelHandle, SingletonEntity}; use super::util::{ for_each_dir_entry, has_name, is_config_file, parse_model_config_dir_entry, @@ -15,7 +14,7 @@ use super::util::{ }; use super::{ custom_model_routers_dir, launch_configs_dir, tab_configs_dir, themes_dir, workflows_dir, - WarpConfigUpdateEvent, LAUNCH_CONFIG_COMMENT, + GalaxyConfigUpdateEvent, WarpConfigUpdateEvent, LAUNCH_CONFIG_COMMENT, }; use crate::ai::custom_model_routers::{CustomModelRouter, ModelConfigError}; use crate::features::FeatureFlag; @@ -89,8 +88,8 @@ impl super::WarpConfig { fn handle_warp_managed_paths_event( &mut self, - _: ModelHandle, - event: &WarpManagedPathsWatcherEvent, + _: ModelHandle, + event: &GalaxyManagedPathsWatcherEvent, ctx: &mut ModelContext, ) { let GalaxyManagedPathsWatcherEvent::FilesChanged(update) = event; diff --git a/app/src/util/bindings.rs b/app/src/util/bindings.rs index 34b7f56c..f81a17aa 100644 --- a/app/src/util/bindings.rs +++ b/app/src/util/bindings.rs @@ -5,9 +5,6 @@ use std::sync::Arc; use enum_iterator::{all, Sequence}; use fuzzy_match::match_indices_case_insensitive; -use itertools::Itertools; -use lazy_static::lazy_static; -use regex::Regex; use galaxyui::actions::StandardAction; use galaxyui::keymap::{ BindingDescription, BindingId, BindingLens, CustomTag, DescriptionContext, EditableBindingLens, @@ -15,6 +12,9 @@ use galaxyui::keymap::{ }; use galaxyui::platform::OperatingSystem; use galaxyui::{Action, AppContext, SingletonEntity}; +use itertools::Itertools; +use lazy_static::lazy_static; +use regex::Regex; use crate::keyboard::{remove_custom_keybinding, write_custom_keybinding, UserDefinedKeybinding}; use crate::settings_view::keybindings::{KeybindingChangedEvent, KeybindingChangedNotifier}; diff --git a/app/src/util/file/external_editor/mac.rs b/app/src/util/file/external_editor/mac.rs index 650193f4..a9d978b5 100644 --- a/app/src/util/file/external_editor/mac.rs +++ b/app/src/util/file/external_editor/mac.rs @@ -2,13 +2,13 @@ use std::fmt::Write; use std::path::Path; use command::r#async::Command; +use galaxy_core::channel::ChannelState; +use galaxy_core::AppId; +use galaxyui::ApplicationBundleInfo; use instant::Instant; use objc2::rc::{autoreleasepool, Retained}; use objc2_app_kit::NSWorkspace; use objc2_foundation::{NSBundle, NSString, NSURL}; -use galaxy_core::channel::ChannelState; -use galaxy_core::AppId; -use galaxyui::ApplicationBundleInfo; use super::*; diff --git a/app/src/util/file/external_editor/mod_tests.rs b/app/src/util/file/external_editor/mod_tests.rs index 42de0689..b9cfdd9a 100644 --- a/app/src/util/file/external_editor/mod_tests.rs +++ b/app/src/util/file/external_editor/mod_tests.rs @@ -303,7 +303,7 @@ fn test_editor_try_from_supported_editors() { #[test] fn test_editor_try_from_unsupported_editors() { - + use super::Editor; // Test unsupported terminal editors assert!(Editor::try_from("vim").is_err()); assert!(Editor::try_from("emacs").is_err()); diff --git a/app/src/util/file/external_editor/settings.rs b/app/src/util/file/external_editor/settings.rs index cf131afd..7c23a021 100644 --- a/app/src/util/file/external_editor/settings.rs +++ b/app/src/util/file/external_editor/settings.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Deserializer, Serialize}; use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; pub use crate::util::openable_file_type::EditorLayout; diff --git a/app/src/util/git_tests.rs b/app/src/util/git_tests.rs index bf183817..f67cc54d 100644 --- a/app/src/util/git_tests.rs +++ b/app/src/util/git_tests.rs @@ -1,3 +1,7 @@ +#[cfg(unix)] +use std::fs; +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; use std::path::Path; use command::r#async::Command; @@ -288,7 +292,6 @@ async fn committed_branch_files_excludes_uncommitted_and_untracked() { #[cfg(unix)] #[tokio::test] async fn get_pr_for_branch_does_not_require_origin_remote() { - use super::PrInfo; let (_dir, repo) = init_repo().await; @@ -325,7 +328,6 @@ async fn get_pr_for_branch_does_not_require_origin_remote() { #[cfg(unix)] #[tokio::test] async fn get_pr_for_branch_returns_none_when_gh_finds_no_pr() { - let (_dir, repo) = init_repo().await; let fake_bin = tempfile::tempdir().expect("failed to create fake bin dir"); @@ -354,7 +356,6 @@ async fn get_pr_for_branch_returns_none_when_gh_finds_no_pr() { #[cfg(unix)] #[tokio::test] async fn get_pr_for_branch_returns_none_when_gh_cannot_resolve_github_repo() { - let (_dir, repo) = init_repo().await; let fake_bin = tempfile::tempdir().expect("failed to create fake bin dir"); diff --git a/app/src/util/image_tests.rs b/app/src/util/image_tests.rs index a1fd9a10..8d3de972 100644 --- a/app/src/util/image_tests.rs +++ b/app/src/util/image_tests.rs @@ -1,3 +1,5 @@ +use image::{ImageBuffer, Rgba}; + use super::*; #[test] @@ -14,7 +16,6 @@ fn test_is_supported_image_mime_type() { /// Creates a small test PNG image and returns its bytes. fn create_small_test_png() -> Vec { - use image::{ImageBuffer, Rgba}; // Create a small 10x10 red image let img: ImageBuffer, Vec> = ImageBuffer::from_fn(10, 10, |_x, _y| Rgba([255u8, 0u8, 0u8, 255u8])); diff --git a/app/src/util/link_detection.rs b/app/src/util/link_detection.rs index d46ae090..d7efa76f 100644 --- a/app/src/util/link_detection.rs +++ b/app/src/util/link_detection.rs @@ -1,13 +1,12 @@ -use galaxyui::elements::PartialClickableElement; use std::collections::HashMap; use std::ops::Range; -use string_offset::ByteOffset; -use urlocator::{UrlLocation, UrlLocator}; use galaxyui::elements::{MouseStateHandle, PartialClickableElement}; use galaxyui::platform::Cursor; use galaxyui::text::char_slice; use galaxyui::Action; +use string_offset::ByteOffset; +use urlocator::{UrlLocation, UrlLocator}; use crate::ai::agent::{AIAgentActionType, AIAgentOutput, AIAgentTextSection, ReadFilesRequest}; use crate::ai::blocklist::block::view_impl::output::LinkActionConstructors; diff --git a/app/src/util/openable_file_type_tests.rs b/app/src/util/openable_file_type_tests.rs index 26b684b5..07a77178 100644 --- a/app/src/util/openable_file_type_tests.rs +++ b/app/src/util/openable_file_type_tests.rs @@ -1,3 +1,5 @@ +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; use std::path::Path; #[cfg(feature = "local_fs")] @@ -202,7 +204,6 @@ fn test_is_supported_code_file() { #[test] #[cfg(unix)] fn test_is_runnable_shell_script_executable_sh() { - use std::os::unix::fs::PermissionsExt; let dir = tempfile::tempdir().unwrap(); let p = dir.path().join("hello.sh"); std::fs::write(&p, b"#!/bin/bash\necho hi\n").unwrap(); diff --git a/app/src/util/repo_detection.rs b/app/src/util/repo_detection.rs index 4ac9c878..055904a5 100644 --- a/app/src/util/repo_detection.rs +++ b/app/src/util/repo_detection.rs @@ -10,10 +10,10 @@ use std::future::Future; use futures::future::ready; #[cfg(not(target_family = "wasm"))] use futures::future::Either; +use galaxy_core::SessionId; #[cfg(not(target_family = "wasm"))] use repo_metadata::repositories::DetectedRepositories; use repo_metadata::repositories::RepoDetectionSource; -use galaxy_core::SessionId; use warp_util::local_or_remote_path::LocalOrRemotePath; #[cfg(not(target_family = "wasm"))] use warpui::SingletonEntity; diff --git a/app/src/util/traffic_lights.rs b/app/src/util/traffic_lights.rs index 70100ad7..f37c2e5d 100644 --- a/app/src/util/traffic_lights.rs +++ b/app/src/util/traffic_lights.rs @@ -11,12 +11,12 @@ pub mod windows; mod linux_only { pub(super) use std::sync::Arc; - pub(super) use pathfinder_color::ColorU; - pub(super) use pathfinder_geometry::vector::vec2f; pub(super) use galaxyui::elements::{ Align, Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, Flex, Hoverable, Icon, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Radius, Rect, Stack, }; + pub(super) use pathfinder_color::ColorU; + pub(super) use pathfinder_geometry::vector::vec2f; pub(super) use crate::workspace::TOTAL_TAB_BAR_HEIGHT; } @@ -26,13 +26,13 @@ use linux_only::*; #[cfg(target_os = "windows")] mod windows_only { - pub(super) use pathfinder_color::ColorU; - pub(super) use pathfinder_geometry::vector::vec2f; pub(super) use galaxy_core::ui::theme; pub(super) use galaxyui::elements::{ Align, Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, Hoverable, OffsetPositioning, ParentAnchor, ParentOffsetBounds, Radius, Rect, Stack, }; + pub(super) use pathfinder_color::ColorU; + pub(super) use pathfinder_geometry::vector::vec2f; pub(super) use crate::ui_components::icons::Icon as IconComponent; pub(super) const WINDOWS_BRIGHT_RED: ColorU = ColorU { @@ -54,7 +54,7 @@ use galaxyui::{AppContext, Element, WindowId}; #[cfg(target_os = "windows")] use windows_only::*; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; #[cfg(any(target_os = "windows", any(target_os = "linux", target_os = "freebsd")))] const BUTTON_ICON_SIZE: f32 = 22.; diff --git a/app/src/util/traffic_lights/windows/renderer.rs b/app/src/util/traffic_lights/windows/renderer.rs index 05b6d78d..db9f88fa 100644 --- a/app/src/util/traffic_lights/windows/renderer.rs +++ b/app/src/util/traffic_lights/windows/renderer.rs @@ -2,7 +2,6 @@ use std::sync::Arc; -use pathfinder_color::ColorU; use galaxy_core::ui::theme::{Fill, WarpTheme}; use galaxyui::elements::{ Align, ConstrainedBox, Container, CrossAxisAlignment, Flex, Hoverable, MainAxisAlignment, @@ -11,6 +10,7 @@ use galaxyui::elements::{ use galaxyui::fonts::FamilyId; use galaxyui::platform::FullscreenState; use galaxyui::{AppContext, Element, SingletonEntity}; +use pathfinder_color::ColorU; use crate::util::traffic_lights::windows::RendererState; use crate::util::traffic_lights::windows_only::WINDOWS_BRIGHT_RED; diff --git a/app/src/view_components/action_button.rs b/app/src/view_components/action_button.rs index 2d169691..3342e753 100644 --- a/app/src/view_components/action_button.rs +++ b/app/src/view_components/action_button.rs @@ -1,8 +1,6 @@ use std::borrow::Cow; use std::sync::Arc; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::contrast::MinimumAllowedContrast; use galaxy_core::ui::color::{coloru_with_opacity, ContrastingColor}; @@ -23,7 +21,8 @@ use galaxyui::{ AppContext, BlurContext, Element, Entity, EventContext, FocusContext, Gradient, SingletonEntity as _, TypedActionView, View, ViewContext, }; -use std::{borrow::Cow, sync::Arc}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use crate::settings_view::keybindings::{KeybindingChangedEvent, KeybindingChangedNotifier}; use crate::terminal::input::{MenuPositioning, MenuPositioningProvider}; diff --git a/app/src/view_components/agent_toast.rs b/app/src/view_components/agent_toast.rs index c927d64b..fa6dd505 100644 --- a/app/src/view_components/agent_toast.rs +++ b/app/src/view_components/agent_toast.rs @@ -1,8 +1,5 @@ use std::time::Duration; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use uuid::Uuid; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, DropShadow, EventHandler, Expanded, Flex, Hoverable, Icon, MouseStateHandle, OffsetPositioning, @@ -16,6 +13,9 @@ use galaxyui::{ AppContext, Element, Entity, EntityId, SingletonEntity, TypedActionView, View, ViewContext, WindowId, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use uuid::Uuid; use crate::appearance::Appearance; use crate::settings_view::keybindings::{KeybindingChangedEvent, KeybindingChangedNotifier}; diff --git a/app/src/view_components/alert.rs b/app/src/view_components/alert.rs index ad5c4146..1acdb50b 100644 --- a/app/src/view_components/alert.rs +++ b/app/src/view_components/alert.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Icon, MainAxisSize, @@ -6,6 +5,7 @@ use galaxyui::elements::{ }; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::Element; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::themes::theme::Fill; diff --git a/app/src/view_components/callout_bubble.rs b/app/src/view_components/callout_bubble.rs index 5296b4c7..f96f2732 100644 --- a/app/src/view_components/callout_bubble.rs +++ b/app/src/view_components/callout_bubble.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::theme::phenomenon::PhenomenonStyle; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -8,6 +7,7 @@ use galaxyui::elements::{ use galaxyui::ui_components::checkbox::Checkbox; use galaxyui::ui_components::components::UiComponentStyles; use galaxyui::Element; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/view_components/compact_dropdown.rs b/app/src/view_components/compact_dropdown.rs index b9ebbe46..5d515c6b 100644 --- a/app/src/view_components/compact_dropdown.rs +++ b/app/src/view_components/compact_dropdown.rs @@ -1,6 +1,5 @@ use std::marker::PhantomData; -use pathfinder_geometry::vector::vec2f; use galaxyui::elements::{ Border, ChildAnchor, ConstrainedBox, CornerRadius, CrossAxisAlignment, Flex, Icon as WarpUiIcon, MainAxisAlignment, MouseStateHandle, OffsetPositioning, ParentElement, @@ -13,6 +12,7 @@ use galaxyui::{ AppContext, BlurContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use super::dropdown::{DropdownAction, DropdownItemAction}; use crate::appearance::Appearance; diff --git a/app/src/view_components/copyable_text_field.rs b/app/src/view_components/copyable_text_field.rs index 307715e4..8fe7247d 100644 --- a/app/src/view_components/copyable_text_field.rs +++ b/app/src/view_components/copyable_text_field.rs @@ -3,7 +3,6 @@ use std::time::Duration; -use instant::Instant; use galaxyui::color::ColorU; use galaxyui::elements::{ ConstrainedBox, Container, CrossAxisAlignment, Element, Expanded, Flex, MouseStateHandle, @@ -12,6 +11,7 @@ use galaxyui::elements::{ use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::components::UiComponent; use galaxyui::{AppContext, SingletonEntity}; +use instant::Instant; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/view_components/dismissible_toast.rs b/app/src/view_components/dismissible_toast.rs index 2842cf6a..443616d3 100644 --- a/app/src/view_components/dismissible_toast.rs +++ b/app/src/view_components/dismissible_toast.rs @@ -1,9 +1,6 @@ use std::rc::Rc; use std::time::Duration; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use uuid::Uuid; use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::theme::color::internal_colors; use galaxyui::elements::{ @@ -20,6 +17,9 @@ use galaxyui::{ Action, AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use uuid::Uuid; use super::action_button::ActionButton; use crate::appearance::Appearance; diff --git a/app/src/view_components/dropdown.rs b/app/src/view_components/dropdown.rs index 2d18e997..b5acab30 100644 --- a/app/src/view_components/dropdown.rs +++ b/app/src/view_components/dropdown.rs @@ -1,7 +1,6 @@ use std::fmt::Debug; use std::marker::PhantomData; -use pathfinder_color::ColorU; use galaxyui::elements::{ Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, Element, Fill, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, OffsetPositioning, ParentElement, @@ -17,6 +16,7 @@ use galaxyui::{ Action, AppContext, BlurContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::menu::{Event as MenuEvent, Menu, MenuItem, MenuItemFields, MenuVariant}; diff --git a/app/src/view_components/find.rs b/app/src/view_components/find.rs index eaa713e4..bce01071 100644 --- a/app/src/view_components/find.rs +++ b/app/src/view_components/find.rs @@ -1,6 +1,6 @@ use pathfinder_color::ColorU; use serde::Serialize; -pub use warpui::accessibility::{AccessibilityContent, WarpA11yRole}; +pub use warpui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use warpui::elements::{ Align, Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Element, Flex, Hoverable, MouseStateHandle, OffsetPositioning, diff --git a/app/src/view_components/find_tests.rs b/app/src/view_components/find_tests.rs index fc6da725..bfe41b42 100644 --- a/app/src/view_components/find_tests.rs +++ b/app/src/view_components/find_tests.rs @@ -1,9 +1,8 @@ -use galaxy_core::ui::appearance::Appearance; -use galaxyui::{platform::WindowStyle, App}; use std::sync::Arc; -use warpui::platform::WindowStyle; -use warpui::App; +use galaxy_core::ui::appearance::Appearance; +use galaxyui::platform::WindowStyle; +use galaxyui::App; use super::{Find, FindDirection, FindEvent, FindModel}; use crate::auth::AuthStateProvider; diff --git a/app/src/view_components/submittable_text_input.rs b/app/src/view_components/submittable_text_input.rs index 78bc2b68..699c3ea5 100644 --- a/app/src/view_components/submittable_text_input.rs +++ b/app/src/view_components/submittable_text_input.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{ Border, Container, CornerRadius, CrossAxisAlignment, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Shrinkable, @@ -8,6 +7,7 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::editor::{ diff --git a/app/src/view_components/warning_box.rs b/app/src/view_components/warning_box.rs index c7032e88..201603de 100644 --- a/app/src/view_components/warning_box.rs +++ b/app/src/view_components/warning_box.rs @@ -1,5 +1,4 @@ //! A reusable warning callout component with optional action button. -use markdown_parser::{FormattedText, FormattedTextInline, FormattedTextLine}; use galaxy_core::ui::color::blend::Blend; use galaxyui::color::ColorU; use galaxyui::elements::{ @@ -9,6 +8,7 @@ use galaxyui::elements::{ }; use galaxyui::platform::Cursor; use galaxyui::EventContext; +use markdown_parser::{FormattedText, FormattedTextInline, FormattedTextLine}; use crate::appearance::Appearance; use crate::themes::theme::Fill as ThemeFill; diff --git a/app/src/vim_registers.rs b/app/src/vim_registers.rs index aa156d33..458025d5 100644 --- a/app/src/vim_registers.rs +++ b/app/src/vim_registers.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; -use settings::Setting as _; -use vim::vim::MotionType; use galaxyui::clipboard::ClipboardContent; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; +use settings::Setting as _; +use vim::vim::MotionType; use crate::settings::AppEditorSettings; diff --git a/app/src/voltron.rs b/app/src/voltron.rs index deb9ecff..f9a2148a 100644 --- a/app/src/voltron.rs +++ b/app/src/voltron.rs @@ -16,8 +16,6 @@ use std::path::PathBuf; use enclose::enclose; -use pathfinder_geometry::vector::Vector2F; -use vec1::Vec1; use galaxyui::accessibility::AccessibilityContent; use galaxyui::elements::{ resizable_state_handle, Border, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, @@ -33,6 +31,8 @@ use galaxyui::{ AppContext, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::Vector2F; +use vec1::Vec1; use crate::appearance::Appearance; use crate::editor::{ diff --git a/app/src/warp_managed_paths_watcher_tests.rs b/app/src/warp_managed_paths_watcher_tests.rs index fead08db..c56eebd0 100644 --- a/app/src/warp_managed_paths_watcher_tests.rs +++ b/app/src/warp_managed_paths_watcher_tests.rs @@ -5,14 +5,14 @@ use dirs::home_dir; use repo_metadata::{RepositoryUpdate, TargetFile}; use super::{ - filter_repository_update_by_prefix, warp_home_mcp_config_file_path, warp_home_skills_dir, - warp_managed_mcp_config_path, warp_managed_skill_dirs, + filter_repository_update_by_prefix, galaxy_home_mcp_config_file_path, galaxy_home_skills_dir, + galaxy_managed_mcp_config_path, warp_managed_skill_dirs, }; #[test] fn warp_managed_skill_dirs_contains_only_warp_home_path() { let dirs = warp_managed_skill_dirs(); - match warp_home_skills_dir() { + match galaxy_home_skills_dir() { Some(warp_home_skills_dir) => assert_eq!(dirs, vec![warp_home_skills_dir]), None => assert!(dirs.is_empty()), } @@ -22,8 +22,8 @@ fn warp_managed_skill_dirs_contains_only_warp_home_path() { fn warp_managed_mcp_config_path_contains_only_warp_home_path() { match ( home_dir(), - warp_home_mcp_config_file_path(), - warp_managed_mcp_config_path(), + galaxy_home_mcp_config_file_path(), + galaxy_managed_mcp_config_path(), ) { (Some(home_dir), Some(warp_home_mcp_config_path), Some(path)) => { assert_eq!(path.root_path, home_dir); diff --git a/app/src/window_settings.rs b/app/src/window_settings.rs index 843c889f..9b632e04 100644 --- a/app/src/window_settings.rs +++ b/app/src/window_settings.rs @@ -1,6 +1,6 @@ -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; use galaxyui::{AppContext, WindowId}; +use settings::macros::define_settings_group; +use settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; define_settings_group!(WindowSettings, settings: [ background_blur_radius: BackgroundBlurRadius { diff --git a/app/src/word_block_editor.rs b/app/src/word_block_editor.rs index f58b59c8..82031ad0 100644 --- a/app/src/word_block_editor.rs +++ b/app/src/word_block_editor.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_editor::editor::NavigationKey; use galaxyui::elements::{ ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, MainAxisAlignment, @@ -10,6 +9,7 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; use crate::appearance::Appearance; use crate::editor::{ diff --git a/app/src/workflows/aliases.rs b/app/src/workflows/aliases.rs index 6b128848..3a3833cd 100644 --- a/app/src/workflows/aliases.rs +++ b/app/src/workflows/aliases.rs @@ -1,15 +1,13 @@ use std::collections::{HashMap, HashSet}; use anyhow::Error; -use galaxy_core::{ - define_settings_group, - settings::{Setting, SupportedPlatforms, SyncToCloud}, +use galaxy_core::define_settings_group; +use galaxy_core::settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, }; use galaxyui::{AppContext, ModelContext, SingletonEntity}; use serde::{Deserialize, Serialize}; use settings_value::SettingsValue; -use galaxy_core::define_settings_group; -use galaxy_core::settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud}; use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent}; use crate::cloud_object::CloudObject as _; diff --git a/app/src/workflows/categories.rs b/app/src/workflows/categories.rs index 623b4280..dfe23980 100644 --- a/app/src/workflows/categories.rs +++ b/app/src/workflows/categories.rs @@ -5,12 +5,10 @@ use std::path::PathBuf; use std::sync::Arc; use fuzzy_match::{match_indices_case_insensitive, FuzzyMatchResult}; -use itertools::Itertools; use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::theme::color::internal_colors; use galaxy_editor::editor::NavigationKey; -use warp_workflows::workflows as global_workflows; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::color::ColorU; use galaxyui::elements::{ Align, ConstrainedBox, Container, CrossAxisAlignment, DispatchEventResult, Element, @@ -25,6 +23,8 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, WeakViewHandle, }; +use itertools::Itertools; +use warp_workflows::workflows as global_workflows; use super::workflow::Workflow; use super::WorkflowSource; @@ -33,8 +33,8 @@ use crate::cloud_object::model::persistence::CloudModel; use crate::editor::Event as EditorEvent; use crate::send_telemetry_from_ctx; use crate::server::telemetry::TelemetryEvent; -use crate::themes::theme::{self, Blend, WarpTheme}; -use crate::user_config::{WarpConfig, WarpConfigUpdateEvent}; +use crate::themes::theme::{self, Blend, GalaxyTheme}; +use crate::user_config::{GalaxyConfig, GalaxyConfigUpdateEvent}; use crate::util::bindings::CustomAction; use crate::voltron::{VoltronFeatureViewMeta, VoltronMetadata}; use crate::workflows::WorkflowType; diff --git a/app/src/workflows/export_workflow.rs b/app/src/workflows/export_workflow.rs index 9c88427c..03c938e0 100644 --- a/app/src/workflows/export_workflow.rs +++ b/app/src/workflows/export_workflow.rs @@ -3,6 +3,7 @@ use std::fmt; use std::result::Result; use std::str::FromStr; +use galaxyui::{AppContext, SingletonEntity}; use serde::de::{self, MapAccess, Visitor}; use serde::ser::SerializeStruct; use serde::{Deserialize, Deserializer, Serialize, Serializer}; diff --git a/app/src/workflows/info_box.rs b/app/src/workflows/info_box.rs index 3ef65695..a014f905 100644 --- a/app/src/workflows/info_box.rs +++ b/app/src/workflows/info_box.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::ops::Range; -use string_offset::CharOffset; use galaxy_core::features::FeatureFlag; use galaxy_core::settings::Setting; use galaxyui::color::ColorU; @@ -22,6 +21,7 @@ use galaxyui::{ AppContext, Element, Entity, EventContext, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use string_offset::CharOffset; use super::command_parser::{ compute_workflow_display_data, WorkflowArgumentIndex, WorkflowDisplayData, diff --git a/app/src/workflows/local_workflows.rs b/app/src/workflows/local_workflows.rs index eff8a2e0..e97a0680 100644 --- a/app/src/workflows/local_workflows.rs +++ b/app/src/workflows/local_workflows.rs @@ -13,7 +13,7 @@ use super::WorkflowSource; use crate::terminal::model::session::Session; #[cfg(feature = "local_fs")] use crate::user_config::load_workflows; -use crate::user_config::WarpConfig; +use crate::user_config::GalaxyConfig; pub fn workflows_dir(base_dir: impl AsRef) -> PathBuf { base_dir.as_ref().join("workflows") diff --git a/app/src/workflows/local_workflows_tests.rs b/app/src/workflows/local_workflows_tests.rs index 4eeb3641..92ccf6d3 100644 --- a/app/src/workflows/local_workflows_tests.rs +++ b/app/src/workflows/local_workflows_tests.rs @@ -1,6 +1,6 @@ -use galaxyui::App; use std::sync::Arc; +use galaxyui::App; use super::*; diff --git a/app/src/workflows/manager.rs b/app/src/workflows/manager.rs index a1d211f8..6b3e6da5 100644 --- a/app/src/workflows/manager.rs +++ b/app/src/workflows/manager.rs @@ -7,7 +7,7 @@ use super::workflow::Workflow; use super::CloudWorkflowModel; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::{GenericCloudObject, Owner}; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::pane_group::{PaneContent, WorkflowPane}; use crate::server::cloud_objects::update_manager::{ ObjectOperation, OperationSuccessType, UpdateManager, UpdateManagerEvent, diff --git a/app/src/workflows/mod.rs b/app/src/workflows/mod.rs index c284b799..8335b77d 100644 --- a/app/src/workflows/mod.rs +++ b/app/src/workflows/mod.rs @@ -1,6 +1,9 @@ use std::sync::Arc; pub use cloud_object_models::{CloudWorkflow, CloudWorkflowModel, WorkflowId}; +use galaxy_core::context_flag::ContextFlag; +use galaxy_core::features::FeatureFlag; +use galaxyui::{AppContext, SingletonEntity}; use serde::{Deserialize, Serialize}; pub mod categories; diff --git a/app/src/workflows/workflow_view.rs b/app/src/workflows/workflow_view.rs index a8106b62..9205a9fd 100644 --- a/app/src/workflows/workflow_view.rs +++ b/app/src/workflows/workflow_view.rs @@ -4,12 +4,6 @@ use std::sync::Arc; use alias_bar::{AliasBar, AliasBarEvent}; use argument_editor::{ArgumentEditorRow, DEFAULT_ARGUMENT_PREFIX}; use env_var_selector::{EnvVarSelector, EnvVarSelectorEvent}; -use itertools::Itertools; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use string_offset::CharOffset; -use syntax_highlightable::SyntaxHighlightable; -use url::Url; use galaxy_core::context_flag::ContextFlag; use galaxy_core::settings::Setting; use galaxy_core::ui::theme::AnsiColorIdentifier; @@ -31,6 +25,12 @@ use galaxyui::{ AppContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use itertools::Itertools; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use string_offset::CharOffset; +use syntax_highlightable::SyntaxHighlightable; +use url::Url; use super::aliases::WorkflowAliases; use super::command_parser::WorkflowCommandDisplayData; @@ -59,7 +59,7 @@ use crate::drive::workflows::workflow_arg_selector::{ WorkflowArgSelector, WorkflowArgSelectorEvent, }; use crate::drive::workflows::workflow_arg_type_helpers::{self, ArgumentEditorRowIndex}; -use crate::drive::{CloudObjectTypeAndId, DriveObjectType, OpenWarpDriveObjectSettings}; +use crate::drive::{CloudObjectTypeAndId, DriveObjectType, OpenGalaxyDriveObjectSettings}; use crate::editor::{ EditorOptions, EditorView, EnterAction, EnterSettings, Event as EditorEvent, InteractionState, PlainTextEditorViewAction as EditorAction, PropagateAndNoOpNavigationKeys, diff --git a/app/src/workflows/workflow_view/alias_bar.rs b/app/src/workflows/workflow_view/alias_bar.rs index fc564012..b7643f6a 100644 --- a/app/src/workflows/workflow_view/alias_bar.rs +++ b/app/src/workflows/workflow_view/alias_bar.rs @@ -2,7 +2,6 @@ use std::cmp::Ordering; use std::collections::HashMap; use anyhow::Error; -use pathfinder_geometry::vector::vec2f; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors::neutral_4; @@ -17,6 +16,7 @@ use galaxyui::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::CloudObject; diff --git a/app/src/workflows/workflow_view/argument_editor.rs b/app/src/workflows/workflow_view/argument_editor.rs index e533db7a..517f81eb 100644 --- a/app/src/workflows/workflow_view/argument_editor.rs +++ b/app/src/workflows/workflow_view/argument_editor.rs @@ -1,7 +1,5 @@ use std::cmp::Ordering; -use itertools::Itertools; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_editor::editor::NavigationKey; @@ -9,6 +7,8 @@ use galaxyui::elements::{ ChildView, ConstrainedBox, Container, CrossAxisAlignment, Fill, Flex, MainAxisAlignment, MainAxisSize, ParentElement, Shrinkable, }; +use itertools::Itertools; +use pathfinder_color::ColorU; use warpui::text_layout::TextStyle; use warpui::ui_components::button::ButtonVariant; use warpui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; diff --git a/app/src/workflows/workflow_view/env_var_selector.rs b/app/src/workflows/workflow_view/env_var_selector.rs index 85706c85..c9d3265e 100644 --- a/app/src/workflows/workflow_view/env_var_selector.rs +++ b/app/src/workflows/workflow_view/env_var_selector.rs @@ -1,9 +1,9 @@ -use itertools::Itertools as _; use galaxyui::elements::ChildView; use galaxyui::{ Element as _, Entity, SingletonEntity as _, TypedActionView, View, ViewAsRef, ViewContext, ViewHandle, }; +use itertools::Itertools as _; use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent}; use crate::cloud_object::{CloudObject as _, GenericStringObjectFormat, JsonObjectType}; diff --git a/app/src/workflows/workflow_view/syntax_highlightable.rs b/app/src/workflows/workflow_view/syntax_highlightable.rs index 2d9ae800..d749bf5c 100644 --- a/app/src/workflows/workflow_view/syntax_highlightable.rs +++ b/app/src/workflows/workflow_view/syntax_highlightable.rs @@ -7,10 +7,8 @@ use galaxy_completer::completer::SuggestionTypeName; use galaxy_completer::signatures::CommandRegistry; use galaxy_core::ui::theme::AnsiColorIdentifier; use galaxyui::r#async::SpawnedFutureHandle; -use galaxyui::ViewHandle; -use galaxyui::{Entity, ModelContext, SingletonEntity}; -use string_offset::ByteOffset; use galaxyui::{Entity, ModelContext, SingletonEntity, ViewHandle}; +use string_offset::ByteOffset; use crate::appearance::Appearance; use crate::completer::SessionAgnosticContext; diff --git a/app/src/workspace/action.rs b/app/src/workspace/action.rs index a2879eed..8ec811cd 100644 --- a/app/src/workspace/action.rs +++ b/app/src/workspace/action.rs @@ -2,14 +2,14 @@ use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; -use session_sharing_protocol::common::SessionId; -use ui_components::lightbox; use galaxy_util::path::LineAndColumnArg; use galaxyui::accessibility::AccessibilityVerbosity; use galaxyui::geometry::rect::RectF; use galaxyui::geometry::vector::Vector2F; use galaxyui::platform::Cursor; use galaxyui::{EntityId, WeakViewHandle, WindowId}; +use session_sharing_protocol::common::SessionId; +use ui_components::lightbox; use super::global_actions::{ForkFromExchange, ForkedConversationDestination}; use super::tab_settings::{ @@ -884,6 +884,7 @@ impl From<&WorkspaceAction> for LoginGatedFeature { impl WorkspaceAction { pub fn blocked_for_anonymous_user(&self) -> bool { + use WorkspaceAction::*; matches!( self, ImportToTeamDrive @@ -900,6 +901,7 @@ impl WorkspaceAction { /// actions directly, rather than using _, so we're forced to make a conscious decision for each /// of them, rather than following some default. pub fn should_save_app_state_on_action(&self) -> bool { + use WorkspaceAction::*; match self { #[cfg(not(target_family = "wasm"))] ContinueConversationLocally { .. } => true, diff --git a/app/src/workspace/close_session_confirmation_dialog.rs b/app/src/workspace/close_session_confirmation_dialog.rs index eb80929e..d679c2a0 100644 --- a/app/src/workspace/close_session_confirmation_dialog.rs +++ b/app/src/workspace/close_session_confirmation_dialog.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ Align, ChildAnchor, Container, MouseStateHandle, OffsetPositioning, ParentAnchor, @@ -12,6 +11,7 @@ use galaxyui::ui_components::text::Span; use galaxyui::{ AppContext, Element, Entity, EntityId, SingletonEntity, TypedActionView, View, ViewContext, }; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::pane_group::PaneId; diff --git a/app/src/workspace/delete_conversation_confirmation_dialog.rs b/app/src/workspace/delete_conversation_confirmation_dialog.rs index 3ba5e94c..43001479 100644 --- a/app/src/workspace/delete_conversation_confirmation_dialog.rs +++ b/app/src/workspace/delete_conversation_confirmation_dialog.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ Align, ChildAnchor, ChildView, Container, OffsetPositioning, ParentAnchor, ParentOffsetBounds, @@ -9,6 +8,7 @@ use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_geometry::vector::vec2f; use crate::ai::agent::conversation::AIConversationId; use crate::appearance::Appearance; diff --git a/app/src/workspace/header_toolbar_editor.rs b/app/src/workspace/header_toolbar_editor.rs index 075a9e49..37370fd2 100644 --- a/app/src/workspace/header_toolbar_editor.rs +++ b/app/src/workspace/header_toolbar_editor.rs @@ -1,6 +1,6 @@ -use settings::Setting as _; use galaxyui::keymap::FixedBinding; use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext}; +use settings::Setting as _; use crate::chip_configurator::{ render_chip_editor_modal, render_chip_editor_sections, ChipConfigurator, diff --git a/app/src/workspace/hoa_onboarding/hoa_onboarding_flow.rs b/app/src/workspace/hoa_onboarding/hoa_onboarding_flow.rs index da01f568..6c99a70e 100644 --- a/app/src/workspace/hoa_onboarding/hoa_onboarding_flow.rs +++ b/app/src/workspace/hoa_onboarding/hoa_onboarding_flow.rs @@ -1,10 +1,5 @@ use std::path::PathBuf; -use markdown_parser::{ - FormattedText, FormattedTextFragment, FormattedTextLine, FormattedTextStyles, Hyperlink, -}; -use pathfinder_color::ColorU; -use settings::Setting; use galaxy_core::ui::theme::phenomenon::PhenomenonStyle; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -25,6 +20,8 @@ use galaxyui::{ use markdown_parser::{ FormattedText, FormattedTextFragment, FormattedTextLine, FormattedTextStyles, Hyperlink, }; +use pathfinder_color::ColorU; +use settings::Setting; use super::{tab_config_step, welcome_banner}; use crate::appearance::Appearance; diff --git a/app/src/workspace/hoa_onboarding/mod.rs b/app/src/workspace/hoa_onboarding/mod.rs index 050c3145..680d9c82 100644 --- a/app/src/workspace/hoa_onboarding/mod.rs +++ b/app/src/workspace/hoa_onboarding/mod.rs @@ -2,9 +2,9 @@ mod hoa_onboarding_flow; mod tab_config_step; mod welcome_banner; -pub use hoa_onboarding_flow::{init, HoaOnboardingFlow, HoaOnboardingFlowEvent, HoaOnboardingStep}; use galaxy_core::user_preferences::GetUserPreferences; use galaxyui::AppContext; +pub use hoa_onboarding_flow::{init, HoaOnboardingFlow, HoaOnboardingFlowEvent, HoaOnboardingStep}; const HAS_COMPLETED_HOA_ONBOARDING_KEY: &str = "HasCompletedHOAOnboarding"; diff --git a/app/src/workspace/hoa_onboarding/welcome_banner.rs b/app/src/workspace/hoa_onboarding/welcome_banner.rs index c4135452..181b1336 100644 --- a/app/src/workspace/hoa_onboarding/welcome_banner.rs +++ b/app/src/workspace/hoa_onboarding/welcome_banner.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::phenomenon::PhenomenonStyle; use galaxy_core::ui::theme::Fill; use galaxyui::assets::asset_cache::AssetSource; @@ -9,6 +8,7 @@ use galaxyui::elements::{ }; use galaxyui::fonts::{Properties, Weight}; use galaxyui::{Element, ViewHandle}; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/workspace/lightbox_view.rs b/app/src/workspace/lightbox_view.rs index 63050a4c..03b06345 100644 --- a/app/src/workspace/lightbox_view.rs +++ b/app/src/workspace/lightbox_view.rs @@ -1,5 +1,11 @@ use std::sync::Arc; +use galaxyui::assets::asset_cache::{AssetCache, AssetSource, AssetState}; +use galaxyui::image_cache::ImageType; +use galaxyui::keymap::{FixedBinding, Keystroke}; +use galaxyui::{ + AppContext, BlurContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, +}; pub use lightbox::LightboxImage; use pathfinder_geometry::vector::Vector2F; use ui_components::{lightbox, Component as _}; diff --git a/app/src/workspace/mod.rs b/app/src/workspace/mod.rs index d1610df9..c5a8ad2f 100644 --- a/app/src/workspace/mod.rs +++ b/app/src/workspace/mod.rs @@ -29,6 +29,7 @@ pub use action::{ TabContextMenuAnchor, VerticalTabsPaneContextMenuTarget, WorkspaceAction, }; pub use active_session::ActiveSession; +use galaxy_core::context_flag::ContextFlag; pub use global_actions::{ ForkAIConversationParams, ForkFromExchange, ForkedConversationDestination, }; @@ -38,9 +39,9 @@ pub use view::{ Workspace, NEW_SESSION_MENU_BUTTON_POSITION_ID, NEW_TAB_BUTTON_POSITION_ID, PANEL_HEADER_HEIGHT, TAB_BAR_HEIGHT, TOTAL_TAB_BAR_HEIGHT, WORKSPACE_PADDING, }; -use galaxy_core::context_flag::ContextFlag; use warpui::accessibility::AccessibilityVerbosity; use warpui::elements::DropTargetData; +use warpui::keymap::macros::id; use warpui::keymap::{BindingDescription, EditableBinding, FixedBinding}; use warpui::AppContext; @@ -1486,7 +1487,6 @@ pub fn init(app: &mut AppContext) { } fn add_open_setting_pages_as_editable_binding(app: &mut AppContext) { - // Add the ability to open setting modals to the command palette. app.register_editable_bindings([ EditableBinding::new( @@ -1630,7 +1630,6 @@ fn add_open_setting_pages_as_editable_binding(app: &mut AppContext) { } fn add_overflow_menu_items_as_editable_binding(app: &mut AppContext) { - // Add the ability to open all overflow menu items to the command palette. app.register_editable_bindings([ EditableBinding::new( diff --git a/app/src/workspace/native_modal.rs b/app/src/workspace/native_modal.rs index 71abbe2a..171a65e5 100644 --- a/app/src/workspace/native_modal.rs +++ b/app/src/workspace/native_modal.rs @@ -1,5 +1,5 @@ -use settings::Setting as _; use galaxy_core::ui::theme::Fill; +use settings::Setting as _; use warpui::elements::{Align, Container, Empty, Flex, MouseStateHandle, ParentElement}; use warpui::fonts::Weight; use warpui::keymap::FixedBinding; diff --git a/app/src/workspace/one_time_modal_model.rs b/app/src/workspace/one_time_modal_model.rs index 38d0fe34..69fe4486 100644 --- a/app/src/workspace/one_time_modal_model.rs +++ b/app/src/workspace/one_time_modal_model.rs @@ -1,9 +1,9 @@ use std::future::Future; use ai::api_keys::ApiKeyManager; -use settings::Setting as _; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; +use settings::Setting as _; use warp_util::sync::Condition; use warpui::{AppContext, Entity, ModelContext, SingletonEntity, WindowId}; @@ -627,7 +627,6 @@ impl OneTimeModalModel { &mut self, ctx: &mut ModelContext, ) -> bool { - // Check if already dismissed let general_settings = GeneralSettings::as_ref(ctx); if *general_settings diff --git a/app/src/workspace/rewind_confirmation_dialog.rs b/app/src/workspace/rewind_confirmation_dialog.rs index e5d0fab1..48186e08 100644 --- a/app/src/workspace/rewind_confirmation_dialog.rs +++ b/app/src/workspace/rewind_confirmation_dialog.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::theme::Fill; use galaxyui::elements::{ @@ -14,6 +13,7 @@ use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles use galaxyui::{ AppContext, Element, Entity, EntityId, SingletonEntity, TypedActionView, View, ViewContext, }; +use pathfinder_geometry::vector::vec2f; use crate::ai::agent::conversation::AIConversationId; use crate::ai::agent::AIAgentExchangeId; diff --git a/app/src/workspace/tab_settings.rs b/app/src/workspace/tab_settings.rs index 4120f487..1554c1f9 100644 --- a/app/src/workspace/tab_settings.rs +++ b/app/src/workspace/tab_settings.rs @@ -1,9 +1,13 @@ use std::collections::HashMap; use std::path::Path; -use settings::macros::define_settings_group; -use settings::{RespectUserSyncSetting, SupportedPlatforms, SyncToCloud}; use galaxy_core::ui::theme::AnsiColorIdentifier; +use settings::macros::define_settings_group; +use settings::{ + ChangeEventReason, RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud, +}; + +use super::header_toolbar_item::HeaderToolbarItemKind; #[derive( Default, @@ -259,7 +263,6 @@ pub enum HeaderToolbarChipSelection { impl HeaderToolbarChipSelection { pub fn left_items(&self) -> Vec { - use super::header_toolbar_item::HeaderToolbarItemKind; match self { Self::Default => HeaderToolbarItemKind::default_left(), Self::Custom { left, .. } => left.clone(), diff --git a/app/src/workspace/tab_settings_tests.rs b/app/src/workspace/tab_settings_tests.rs index 0be479a7..04466017 100644 --- a/app/src/workspace/tab_settings_tests.rs +++ b/app/src/workspace/tab_settings_tests.rs @@ -1,4 +1,5 @@ use settings::Setting; +use warpui::{App, SingletonEntity}; use super::*; use crate::test_util::settings::initialize_settings_for_tests; diff --git a/app/src/workspace/util.rs b/app/src/workspace/util.rs index 8772edb5..54ad10b1 100644 --- a/app/src/workspace/util.rs +++ b/app/src/workspace/util.rs @@ -1,6 +1,6 @@ -use serde::{Deserialize, Serialize}; use galaxyui::elements::MouseStateHandle; use galaxyui::{AppContext, EntityId, SingletonEntity, ViewContext, ViewHandle, WindowId}; +use serde::{Deserialize, Serialize}; use super::OneTimeModalModel; use crate::appearance::Appearance; diff --git a/app/src/workspace/view.rs b/app/src/workspace/view.rs index c687aa4d..95b257ca 100644 --- a/app/src/workspace/view.rs +++ b/app/src/workspace/view.rs @@ -51,22 +51,6 @@ use autoupdate::AutoupdateStage; #[cfg(target_os = "macos")] use command::blocking::Command; use futures::Future; -use itertools::Itertools; -use lazy_static::lazy_static; -pub(crate) use onboarding::OnboardingTutorial; -use parking_lot::FairMutex; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -#[cfg(feature = "local_fs")] -use repo_metadata::repositories::DetectedRepositories; -#[cfg(feature = "local_fs")] -use repo_metadata::RemoteRepositoryIdentifier; -#[cfg(all(target_os = "macos", feature = "crash_reporting"))] -use sentry::protocol::{Attachment, AttachmentType}; -use serde_json; -use session_sharing_protocol::common::SessionId as SharedSessionId; -#[cfg(target_family = "wasm")] -use url::Url; use galaxy_cli::agent::Harness; use galaxy_core::context_flag::ContextFlag; use galaxy_core::execution_mode::AppExecutionMode; @@ -84,7 +68,8 @@ use galaxy_util::path::{user_friendly_path, LineAndColumnArg}; #[cfg(all(feature = "local_fs", not(target_family = "wasm")))] use galaxy_util::standardized_path::StandardizedPath; use galaxyui::accessibility::{ - AccessibilityContent, AccessibilityVerbosity, ActionAccessibilityContent, WarpA11yRole, + AccessibilityContent, AccessibilityVerbosity, ActionAccessibilityContent, GalaxyA11yRole, + WarpA11yRole, }; use galaxyui::clipboard::ClipboardContent; #[cfg(target_family = "wasm")] @@ -115,6 +100,22 @@ use galaxyui::{ AppContext, Entity, EntityId, FocusContext, ModelHandle, SingletonEntity, TypedActionView, UpdateModel, UpdateView, View, ViewAsRef, ViewContext, ViewHandle, WeakViewHandle, WindowId, }; +use itertools::Itertools; +use lazy_static::lazy_static; +pub(crate) use onboarding::OnboardingTutorial; +use parking_lot::FairMutex; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +#[cfg(feature = "local_fs")] +use repo_metadata::repositories::DetectedRepositories; +#[cfg(feature = "local_fs")] +use repo_metadata::RemoteRepositoryIdentifier; +#[cfg(all(target_os = "macos", feature = "crash_reporting"))] +use sentry::protocol::{Attachment, AttachmentType}; +use serde_json; +use session_sharing_protocol::common::SessionId as SharedSessionId; +#[cfg(target_family = "wasm")] +use url::Url; use self::vertical_tabs::telemetry::{VerticalTabsDisplayOption, VerticalTabsTelemetryEvent}; use self::vertical_tabs::{ @@ -266,7 +267,8 @@ use crate::drive::settings::{WarpDriveSettings, WarpDriveSettingsChangedEvent}; use crate::drive::workflows::arguments::ArgumentsState; use crate::drive::workflows::modal::{WorkflowModal, WorkflowModalEvent}; use crate::drive::{ - CloudObjectTypeAndId, DriveObjectType, DrivePanel, DrivePanelEvent, OpenWarpDriveObjectSettings, + CloudObjectTypeAndId, DriveObjectType, DrivePanel, DrivePanelEvent, + OpenGalaxyDriveObjectSettings, }; use crate::editor::{ EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys, SingleLineEditorOptions, @@ -372,9 +374,9 @@ use crate::tab_configs::{ NewWorktreeModal, NewWorktreeModalEvent, TabConfigParamsModal, TabConfigParamsModalEvent, }; use crate::terminal::alt_screen_reporting::AltScreenReporting; -use crate::terminal::available_shells::AvailableShell; #[cfg(target_os = "windows")] use crate::terminal::available_shells::AvailableShells; +use crate::terminal::available_shells::{AvailableShell, AvailableShells}; use crate::terminal::block_list_viewport::InputMode; #[cfg(not(target_family = "wasm"))] use crate::terminal::cli_agent_sessions::plugin_manager::{plugin_manager_for, PluginModalKind}; @@ -404,6 +406,7 @@ use crate::terminal::session_settings::{ SessionSettingsChangedEvent, WorkingDirectoryMode, }; use crate::terminal::settings::{SpacingMode, TerminalSettings}; +use crate::terminal::shared_session::manager::Manager; use crate::terminal::shared_session::SharedSessionActionSource; use crate::terminal::shell::ShellType; use crate::terminal::view::ambient_agent::{AuthSecretFtuxView, AuthSecretFtuxViewEvent}; @@ -444,7 +447,7 @@ use crate::user_config::{ find_unused_worktree_config_path, materialize_default_worktree_config, sanitize_toml_base_name, tab_configs_dir, }; -use crate::user_config::{WarpConfig, WarpConfigUpdateEvent}; +use crate::user_config::{GalaxyConfig, GalaxyConfigUpdateEvent}; use crate::util::bindings::{ keybinding_name_to_display_string, keybinding_name_to_keystroke, trigger_to_keystroke, }; @@ -2696,12 +2699,12 @@ impl Workspace { }); } } - WarpConfigUpdateEvent::ModelConfigs => { + GalaxyConfigUpdateEvent::ModelConfigs => { toast_stack.update(ctx, |toast_stack, ctx| { toast_stack.dismiss_toasts_by_prefix("model_config_error:", ctx); }); } - WarpConfigUpdateEvent::ModelConfigErrors(errors) => { + GalaxyConfigUpdateEvent::ModelConfigErrors(errors) => { let home_dir = dirs::home_dir(); for error in errors { let object_id = format!("model_config_error:{}", error.file_path.display()); @@ -24202,7 +24205,7 @@ impl TypedActionView for Workspace { send_telemetry_from_ctx!(TelemetryEvent::DragAndDropTabGroup, ctx); ctx.notify(); } - OpenWarpDrive => { + OpenGalaxyDrive => { if WarpDriveSettings::is_warp_drive_enabled(ctx) { self.open_left_panel_view(&LeftPanelAction::WarpDrive, ctx); } @@ -25601,7 +25604,7 @@ impl TypedActionView for Workspace { self.open_left_panel_view(&LeftPanelAction::ProjectExplorer, ctx); } } - ToggleWarpDrive => { + ToggleGalaxyDrive => { if WarpDriveSettings::is_warp_drive_enabled(ctx) { let is_showing = self.left_panel_view.as_ref(ctx).active_view() == ToolPanelView::WarpDrive; diff --git a/app/src/workspace/view/auto_handoff_sleep_modal/view.rs b/app/src/workspace/view/auto_handoff_sleep_modal/view.rs index eafb9c41..20a01ae7 100644 --- a/app/src/workspace/view/auto_handoff_sleep_modal/view.rs +++ b/app/src/workspace/view/auto_handoff_sleep_modal/view.rs @@ -1,6 +1,6 @@ +use galaxy_core::ui::theme::Fill; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; -use galaxy_core::ui::theme::Fill; use warpui::assets::asset_cache::AssetSource; use warpui::elements::{ Align, CacheOption, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius, diff --git a/app/src/workspace/view/conversation_list/item.rs b/app/src/workspace/view/conversation_list/item.rs index f2aa4807..31b0927e 100644 --- a/app/src/workspace/view/conversation_list/item.rs +++ b/app/src/workspace/view/conversation_list/item.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::theme::color::internal_colors; use galaxy_util::path::user_friendly_path; @@ -16,6 +15,7 @@ use galaxyui::text_layout::TextStyle; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::ui_components::text_input::TextInput; use galaxyui::{AppContext, SingletonEntity, ViewHandle}; +use pathfinder_geometry::vector::vec2f; use crate::ai::active_agent_views_model::ActiveAgentViewsModel; use crate::ai::agent_conversations_model::{ diff --git a/app/src/workspace/view/conversation_list/view.rs b/app/src/workspace/view/conversation_list/view.rs index aaffe907..c6873a08 100644 --- a/app/src/workspace/view/conversation_list/view.rs +++ b/app/src/workspace/view/conversation_list/view.rs @@ -2,7 +2,6 @@ use std::collections::{HashMap, HashSet}; use std::ops::Range; use std::sync::{Arc, Mutex}; -use pathfinder_geometry::vector::Vector2F; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::Icon; @@ -23,6 +22,7 @@ use galaxyui::{ AppContext, BlurContext, Entity, EntityId, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use pathfinder_geometry::vector::Vector2F; use super::view_model::{ConversationEntry, ConversationListViewModel}; use crate::ai::active_agent_views_model::{ActiveAgentViewsModel, ConversationOrTaskId}; diff --git a/app/src/workspace/view/conversation_list/view_model.rs b/app/src/workspace/view/conversation_list/view_model.rs index 9b37cb84..cb90bccf 100644 --- a/app/src/workspace/view/conversation_list/view_model.rs +++ b/app/src/workspace/view/conversation_list/view_model.rs @@ -143,7 +143,7 @@ impl ConversationListViewModel { }) .collect(); - matched_items.sort_by(|a, b| b.0.cmp(&a.0)); + matched_items.sort_by_key(|b| std::cmp::Reverse(b.0)); self.filtered_items = matched_items.into_iter().map(|(_, item)| item).collect(); } } diff --git a/app/src/workspace/view/free_ai_removal_modal.rs b/app/src/workspace/view/free_ai_removal_modal.rs index 5db4aa39..dd212b38 100644 --- a/app/src/workspace/view/free_ai_removal_modal.rs +++ b/app/src/workspace/view/free_ai_removal_modal.rs @@ -1,11 +1,11 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use serde_json::{json, Value}; -use strum_macros::{EnumDiscriminants, EnumIter}; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use serde_json::{json, Value}; +use strum_macros::{EnumDiscriminants, EnumIter}; use warpui::elements::{ Align, Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Flex, FormattedTextElement, MainAxisAlignment, MainAxisSize, MouseStateHandle, diff --git a/app/src/workspace/view/global_search/model.rs b/app/src/workspace/view/global_search/model.rs index bbab7f60..9f9439d9 100644 --- a/app/src/workspace/view/global_search/model.rs +++ b/app/src/workspace/view/global_search/model.rs @@ -5,8 +5,11 @@ use std::path::PathBuf; use anyhow::Result; use futures::StreamExt as _; use galaxy_ripgrep::search::{Match as RipgrepMatch, Submatch}; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; use galaxyui::r#async::SpawnedFutureHandle; -use galaxyui::{Entity, ModelContext, ModelSpawner}; +use galaxyui::{Entity, ModelContext, ModelSpawner, SingletonEntity}; use instant::Instant; use num_traits::SaturatingSub; use regex::escape; @@ -15,10 +18,6 @@ use remote_server::proto::RipgrepSearchSuccess; use remote_server::protocol::RequestId; use remote_server::HostId; use string_offset::ByteOffset; -use galaxy_util::local_or_remote_path::LocalOrRemotePath; -use galaxy_util::remote_path::RemotePath; -use galaxy_util::standardized_path::StandardizedPath; -use galaxyui::{Entity, ModelContext, ModelSpawner, SingletonEntity}; use crate::workspace::view::global_search::view::GlobalSearchEvent; use crate::workspace::view::global_search::{GlobalSearchMatch, SearchConfig}; diff --git a/app/src/workspace/view/global_search/view.rs b/app/src/workspace/view/global_search/view.rs index 320a23dc..72a54f21 100644 --- a/app/src/workspace/view/global_search/view.rs +++ b/app/src/workspace/view/global_search/view.rs @@ -6,10 +6,6 @@ use std::sync::Arc; use std::time::Duration; use async_channel::Sender; -use instant::Instant; -use pathfinder_geometry::vector::vec2f; -use remote_server::HostId; -use string_offset::{ByteOffset, CharCounter}; use galaxy_core::r#async::debounce; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; @@ -39,6 +35,10 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, WeakViewHandle, }; +use instant::Instant; +use pathfinder_geometry::vector::vec2f; +use remote_server::HostId; +use string_offset::{ByteOffset, CharCounter}; use crate::code::icon_from_file_path; use crate::coding_panel_enablement_state::CodingPanelEnablementState; diff --git a/app/src/workspace/view/launch_modal/mod.rs b/app/src/workspace/view/launch_modal/mod.rs index 7623966b..05bda2bc 100644 --- a/app/src/workspace/view/launch_modal/mod.rs +++ b/app/src/workspace/view/launch_modal/mod.rs @@ -4,10 +4,6 @@ pub mod oz_launch; use std::collections::HashMap; -use markdown_parser::{parse_markdown, FormattedText, FormattedTextLine}; -// Re-export slide types for convenience -pub use oz_launch::OzLaunchSlide; -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::Fill; use galaxyui::assets::asset_cache::AssetSource; @@ -26,6 +22,10 @@ use galaxyui::ui_components::components::UiComponent; use galaxyui::{ AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle, }; +use markdown_parser::{parse_markdown, FormattedText, FormattedTextLine}; +// Re-export slide types for convenience +pub use oz_launch::OzLaunchSlide; +use pathfinder_color::ColorU; use crate::settings::PrivacySettings; use crate::ui_components::blended_colors; diff --git a/app/src/workspace/view/launch_modal/oz_launch.rs b/app/src/workspace/view/launch_modal/oz_launch.rs index eb4f7eeb..17c5f11e 100644 --- a/app/src/workspace/view/launch_modal/oz_launch.rs +++ b/app/src/workspace/view/launch_modal/oz_launch.rs @@ -1,6 +1,6 @@ use asset_macro::bundled_or_fetched_asset; -use markdown_parser::{FormattedTextFragment, FormattedTextLine}; use galaxy_core::send_telemetry_from_ctx; +use markdown_parser::{FormattedTextFragment, FormattedTextLine}; use warpui::assets::asset_cache::AssetSource; use warpui::{AppContext, SingletonEntity}; diff --git a/app/src/workspace/view/onboarding.rs b/app/src/workspace/view/onboarding.rs index 21d7d73a..fa7f1a8b 100644 --- a/app/src/workspace/view/onboarding.rs +++ b/app/src/workspace/view/onboarding.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; -use onboarding::{ProjectOnboardingSettings, SelectedSettings}; use galaxy_core::execution_mode::AppExecutionMode; +use onboarding::{ProjectOnboardingSettings, SelectedSettings}; use warpui::{SingletonEntity as _, ViewContext}; use crate::pane_group::{NewTerminalOptions, PanesLayout}; diff --git a/app/src/workspace/view/openwarp_launch_modal/view.rs b/app/src/workspace/view/openwarp_launch_modal/view.rs index 95e8ccdb..c108c96b 100644 --- a/app/src/workspace/view/openwarp_launch_modal/view.rs +++ b/app/src/workspace/view/openwarp_launch_modal/view.rs @@ -1,8 +1,3 @@ -use markdown_parser::{ - FormattedText, FormattedTextFragment, FormattedTextLine, FormattedTextStyles, Hyperlink, -}; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::phenomenon::PhenomenonStyle; use galaxy_core::ui::theme::Fill; use galaxyui::assets::asset_cache::AssetSource; @@ -20,6 +15,8 @@ use galaxyui::{ use markdown_parser::{ FormattedText, FormattedTextFragment, FormattedTextLine, FormattedTextStyles, Hyperlink, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; use crate::appearance::Appearance; use crate::ui_components::icons::Icon; diff --git a/app/src/workspace/view/orchestration_launch_modal/view.rs b/app/src/workspace/view/orchestration_launch_modal/view.rs index b1980f2d..b2a6d5f6 100644 --- a/app/src/workspace/view/orchestration_launch_modal/view.rs +++ b/app/src/workspace/view/orchestration_launch_modal/view.rs @@ -1,6 +1,6 @@ +use galaxy_core::ui::theme::Fill; use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; -use galaxy_core::ui::theme::Fill; use warpui::assets::asset_cache::AssetSource; use warpui::elements::{ Align, CacheOption, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, CornerRadius, diff --git a/app/src/workspace/view/right_panel.rs b/app/src/workspace/view/right_panel.rs index f99d4b30..700b9a3f 100644 --- a/app/src/workspace/view/right_panel.rs +++ b/app/src/workspace/view/right_panel.rs @@ -2,10 +2,10 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use dunce::canonicalize; -use itertools::Itertools; -use pathfinder_color::ColorU; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::Icon; +use itertools::Itertools; +use pathfinder_color::ColorU; use warp_util::path::LineAndColumnArg; use warpui::elements::{ resizable_state_handle, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, diff --git a/app/src/workspace/view/tab_grouping.rs b/app/src/workspace/view/tab_grouping.rs index 1e6debf5..f202b8ee 100644 --- a/app/src/workspace/view/tab_grouping.rs +++ b/app/src/workspace/view/tab_grouping.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; -use itertools::{Either, Itertools}; use galaxy_core::features::FeatureFlag; +use itertools::{Either, Itertools}; use warpui::{EntityId, UpdateView, ViewContext}; use super::{group_member_indices, Workspace}; diff --git a/app/src/workspace/view/vertical_tabs.rs b/app/src/workspace/view/vertical_tabs.rs index 27306146..530bf137 100644 --- a/app/src/workspace/view/vertical_tabs.rs +++ b/app/src/workspace/view/vertical_tabs.rs @@ -5,18 +5,14 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; -use languages::language_by_local_filename; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; -use settings::Setting as _; use galaxy_core::context_flag::ContextFlag; -use galaxy_core::telemetry::TelemetryEvent as _; use galaxy_core::ui::color::blend::Blend; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::{AnsiColorIdentifier, Fill as WarpThemeFill, WarpTheme}; -use galaxy_core::ui::Icon as WarpIcon; +use galaxy_core::ui::theme::{ + AnsiColorIdentifier, Fill as GalaxyThemeFill, Fill as WarpThemeFill, GalaxyTheme, WarpTheme, +}; +use galaxy_core::ui::{Icon as GalaxyIcon, Icon as WarpIcon}; use galaxyui::elements::{ resizable_state_handle, Border, ChildAnchor, Clipped, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, @@ -34,6 +30,11 @@ use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::ui_components::text_input::TextInput; use galaxyui::{AppContext, EntityId, SingletonEntity, ViewHandle, WindowId}; +use languages::language_by_local_filename; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; +use settings::Setting as _; use super::{render_group_member_icon_collage, select_unique_pane_kinds}; use crate::ai::agent::conversation::{ConversationStatus, StatusColorStyle}; diff --git a/app/src/workspace/view/vertical_tabs_tests.rs b/app/src/workspace/view/vertical_tabs_tests.rs index 8b774b9d..63d9af7d 100644 --- a/app/src/workspace/view/vertical_tabs_tests.rs +++ b/app/src/workspace/view/vertical_tabs_tests.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::Vector2F; use galaxyui::elements::PositionedElementOffsetBounds; use galaxyui::EntityId; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::Vector2F; use super::{ branch_label_display, coalesce_summary_branch_entries, code_detail_kind_label, diff --git a/app/src/workspace/view_tests.rs b/app/src/workspace/view_tests.rs index 6944a8a5..a27f0cba 100644 --- a/app/src/workspace/view_tests.rs +++ b/app/src/workspace/view_tests.rs @@ -2,6 +2,8 @@ use std::collections::HashMap; use ai::index::full_source_code_embedding::manager::CodebaseIndexManager; use ai::project_context::model::ProjectContextModel; +#[cfg(feature = "local_fs")] +use galaxy_files::FileModel; use pane_group::{NotebookPane, PaneState, SplitPaneState, TerminalPaneId}; use repo_metadata::repositories::DetectedRepositories; use repo_metadata::watcher::DirectoryWatcher; @@ -15,8 +17,6 @@ use tempfile::TempDir; use terminal::shared_session::permissions_manager::SessionPermissionsManager; use terminal::view::ActiveSessionState; use warp_editor::editor::NavigationKey; -#[cfg(feature = "local_fs")] -use warp_files::FileModel; use warpui::platform::WindowStyle; use warpui::{AddSingletonModel, App, ViewHandle}; use watcher::HomeDirectoryWatcher; @@ -185,7 +185,7 @@ pub(crate) fn initialize_app(app: &mut App) { app.add_singleton_model(|_| DetectedRepositories::default()); app.add_singleton_model(HomeDirectoryWatcher::new_for_test); app.add_singleton_model(DirectoryWatcher::new); - app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); + app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing); app.add_singleton_model(FileMCPWatcher::new); app.add_singleton_model(|_| FileBasedMCPManager::default()); diff --git a/app/src/workspaces/gql_convert.rs b/app/src/workspaces/gql_convert.rs index 9037b50f..0210eb78 100644 --- a/app/src/workspaces/gql_convert.rs +++ b/app/src/workspaces/gql_convert.rs @@ -1,7 +1,6 @@ use std::path::PathBuf; use anyhow::{anyhow, bail, Result}; -use regex::Regex; use galaxy_graphql::billing::{ AiAutonomyPolicy as GqlAiAutonomyPolicy, AmbientAgentsPolicy as GqlAmbientAgentsPolicy, BillingCycleUsageHistory as GqlBillingCycleUsageHistory, BillingMetadata as GqlBillingMetadata, @@ -39,6 +38,7 @@ use galaxy_graphql::workspace::{ WorkspaceSettings as GqlWorkspaceSettings, WriteToPtyAutonomyValue as GqlWriteToPtyAutonomyValue, }; +use regex::Regex; use super::team::{DiscoverableTeam, MembershipRole, Team, TeamMember}; use super::user_workspaces::WorkspacesMetadataResponse; diff --git a/app/src/workspaces/update_manager_tests.rs b/app/src/workspaces/update_manager_tests.rs index d7168d02..6d18986d 100644 --- a/app/src/workspaces/update_manager_tests.rs +++ b/app/src/workspaces/update_manager_tests.rs @@ -1,5 +1,6 @@ use chrono::Utc; use cloud_object_client::MockObjectClient; +use galaxyui::App; use itertools::Itertools; use super::*; diff --git a/app/src/workspaces/user_workspaces.rs b/app/src/workspaces/user_workspaces.rs index e16d5646..24b6d47b 100644 --- a/app/src/workspaces/user_workspaces.rs +++ b/app/src/workspaces/user_workspaces.rs @@ -1,11 +1,11 @@ use std::sync::Arc; use anyhow::Result; -use regex::Regex; use galaxy_core::features::FeatureFlag; use galaxy_core::settings::{ChangeEventReason, Setting}; use galaxy_graphql::workspace::FeatureModelChoice; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity, Tracked}; +use regex::Regex; use super::team::{DiscoverableTeam, MembershipRole, Team}; #[cfg(test)] @@ -16,7 +16,7 @@ use super::workspace::{ }; use crate::ai::llms::LLMModelHost; use crate::auth::{AuthStateProvider, UserUid}; -use crate::channel::ChannelState; +use crate::channel::{Channel, ChannelState}; use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::{CloudObjectEventEntrypoint, ObjectType, Owner, Space}; use crate::pricing::PricingInfoModel; @@ -544,6 +544,14 @@ impl UserWorkspaces { } pub fn is_bedrock_enabled(&self, app: &AppContext) -> bool { + // In local/dev/oss builds, allow using local Bedrock credentials even if there's no active workspace. + if self.current_workspace().is_none() { + let channel = ChannelState::channel(); + if channel == Channel::Oss || channel == Channel::Local || channel == Channel::Dev { + return *AISettings::as_ref(app).bedrock_enabled.value(); + } + } + // i.e. did the admin go and toggle on aws bedrock in the admin panel? if !self.is_aws_bedrock_available_from_workspace() { return false; diff --git a/app/src/workspaces/user_workspaces_tests.rs b/app/src/workspaces/user_workspaces_tests.rs index b297662b..a9b4e9b3 100644 --- a/app/src/workspaces/user_workspaces_tests.rs +++ b/app/src/workspaces/user_workspaces_tests.rs @@ -1,9 +1,9 @@ use std::time::Duration; +use galaxyui_extras::user_preferences; use mockall::Sequence; use settings::{PrivatePreferences, PublicPreferences}; use warpui::{AddSingletonModel, App}; -use galaxyui_extras::user_preferences; use super::*; use crate::ai::llms::LLMModelHost; @@ -247,7 +247,7 @@ fn team_for_test() -> Team { } #[test] -fn test_aws_bedrock_credentials_default_off_when_admin_respects_user_setting() { +fn test_aws_bedrock_credentials_default_on_when_admin_respects_user_setting() { let team = team_for_test(); let mut workspace = workspace_for_test(&team); workspace.settings.llm_settings.enabled = true; @@ -259,6 +259,19 @@ fn test_aws_bedrock_credentials_default_off_when_admin_respects_user_setting() { ..Default::default() }, ); + let mut team_client = MockTeamClient::new(); + let workspace_for_poll = workspace.clone(); + team_client.expect_workspaces_metadata().returning(move || { + Ok(WorkspacesMetadataWithPricing { + metadata: WorkspacesMetadataResponse { + workspaces: vec![workspace_for_poll.clone()], + joinable_teams: vec![], + experiments: None, + feature_model_choices: None, + }, + pricing_info: None, + }) + }); App::test((), |mut app| async move { initialize_app( @@ -266,14 +279,14 @@ fn test_aws_bedrock_credentials_default_off_when_admin_respects_user_setting() { CachedResources { workspaces: vec![workspace], }, - Arc::new(MockTeamClient::new()), + Arc::new(team_client), Arc::new(MockWorkspaceClient::new()), ); app.read(|ctx| { assert!( - !UserWorkspaces::as_ref(ctx).is_bedrock_enabled(ctx), - "respect-user-setting should default the local Bedrock credentials toggle to off" + UserWorkspaces::as_ref(ctx).is_bedrock_enabled(ctx), + "respect-user-setting should default the local Bedrock credentials toggle to on" ); assert!( UserWorkspaces::as_ref(ctx).is_aws_bedrock_credentials_toggleable(), diff --git a/crates/ai/src/agent/action_result/convert.rs b/crates/ai/src/agent/action_result/convert.rs index e0ca56fb..d495805e 100644 --- a/crates/ai/src/agent/action_result/convert.rs +++ b/crates/ai/src/agent/action_result/convert.rs @@ -87,6 +87,8 @@ impl TryFrom for api::request::input::tool_call_resu output: "User cancelled the command before it executed." .to_string(), exit_code: 130, + start_ts: None, + finish_ts: None, }, )), }, @@ -162,6 +164,8 @@ impl TryFrom command_id: String::new(), output: "User cancelled the long-running shell command.".to_string(), exit_code: 130, + start_ts: None, + finish_ts: None, } )) }, diff --git a/crates/ai/src/agent/action_result/mod.rs b/crates/ai/src/agent/action_result/mod.rs index a9ef1b2c..79f27797 100644 --- a/crates/ai/src/agent/action_result/mod.rs +++ b/crates/ai/src/agent/action_result/mod.rs @@ -5,6 +5,8 @@ use std::ops::Range; use std::time::SystemTime; use chrono::{DateTime, Local}; +use galaxy_core::command::ExitCode; +use galaxy_terminal::model::BlockId; use itertools::Itertools as _; use serde::{Deserialize, Serialize}; use warp_multi_agent_api::apply_file_diffs_result::success::UpdatedFileContent; diff --git a/crates/ai/src/api_keys.rs b/crates/ai/src/api_keys.rs index d600e0e5..3b5edb8b 100644 --- a/crates/ai/src/api_keys.rs +++ b/crates/ai/src/api_keys.rs @@ -1,10 +1,10 @@ use std::time::{Duration, SystemTime}; +use galaxyui_core::{Entity, ModelContext, SingletonEntity}; +use galaxyui_extras::secure_storage::{self, AppContextExt}; use serde::{Deserialize, Serialize}; use uuid::Uuid; use warp_multi_agent_api as api; -use galaxyui_core::{Entity, ModelContext, SingletonEntity}; -use galaxyui_extras::secure_storage::{self, AppContextExt}; pub use crate::aws_credentials::{AwsCredentials, AwsCredentialsState}; pub use crate::geap_credentials::{ diff --git a/crates/ai/src/aws_credentials.rs b/crates/ai/src/aws_credentials.rs index dec09ac1..d86ee936 100644 --- a/crates/ai/src/aws_credentials.rs +++ b/crates/ai/src/aws_credentials.rs @@ -43,6 +43,18 @@ impl AwsCredentials { } } + pub fn access_key(&self) -> &str { + &self.access_key + } + + pub fn secret_key(&self) -> &str { + &self.secret_key + } + + pub fn session_token(&self) -> Option<&str> { + self.session_token.as_deref() + } + pub fn expires_at(&self) -> Option { self.expires_at } diff --git a/crates/ai/src/index/file_outline/native.rs b/crates/ai/src/index/file_outline/native.rs index 3eefa3bc..630b69fe 100644 --- a/crates/ai/src/index/file_outline/native.rs +++ b/crates/ai/src/index/file_outline/native.rs @@ -5,6 +5,7 @@ use std::path::Path; use anyhow::anyhow; use arborium::tree_sitter::{Parser, Query, QueryCursor, Tree}; use futures::channel::oneshot; +use galaxy_util::standardized_path::StandardizedPath; use ignore::gitignore::Gitignore; use itertools::Itertools; use rayon::prelude::*; @@ -12,7 +13,6 @@ use repo_metadata::entry::{is_file_parsable, BudgetExceededBehavior, IgnoredPath use repo_metadata::RepositoryUpdate; use streaming_iterator::StreamingIterator; use syntax_tree::TextSlice; -use warp_util::standardized_path::StandardizedPath; use crate::index::file_outline::{FileOutline, Outline, Symbol}; use crate::index::{Entry, FileId, FileMetadata, THREADPOOL}; @@ -122,7 +122,7 @@ impl Outline { // Extract paths from TargetFile for addition, filtering out gitignored files for target_file in added .into_iter() - .chain(modified.into_iter()) + .chain(modified) .chain(moved.keys().cloned()) .filter(|target_file| !target_file.is_ignored) { diff --git a/crates/ai/src/index/full_source_code_embedding/chunker.rs b/crates/ai/src/index/full_source_code_embedding/chunker.rs index 735eb571..44bec13f 100644 --- a/crates/ai/src/index/full_source_code_embedding/chunker.rs +++ b/crates/ai/src/index/full_source_code_embedding/chunker.rs @@ -1,8 +1,8 @@ use std::path::Path; -use string_offset::ByteOffset; #[cfg(not(target_family = "wasm"))] -use warp_util::standardized_path::StandardizedPath; +use galaxy_util::standardized_path::StandardizedPath; +use string_offset::ByteOffset; mod naive; #[cfg(not(target_family = "wasm"))] diff --git a/crates/ai/src/index/full_source_code_embedding/chunker/semantic_tests.rs b/crates/ai/src/index/full_source_code_embedding/chunker/semantic_tests.rs index 6e1c7fb4..826790d8 100644 --- a/crates/ai/src/index/full_source_code_embedding/chunker/semantic_tests.rs +++ b/crates/ai/src/index/full_source_code_embedding/chunker/semantic_tests.rs @@ -1,7 +1,7 @@ use std::path::Path; +use galaxy_util::standardized_path::StandardizedPath; use languages::language_by_filename; -use warp_util::standardized_path::StandardizedPath; use super::*; diff --git a/crates/ai/src/index/full_source_code_embedding/codebase_index.rs b/crates/ai/src/index/full_source_code_embedding/codebase_index.rs index 7d1f923e..b8f2ec08 100644 --- a/crates/ai/src/index/full_source_code_embedding/codebase_index.rs +++ b/crates/ai/src/index/full_source_code_embedding/codebase_index.rs @@ -9,13 +9,12 @@ use async_channel; use chrono::{DateTime, Utc}; use futures::stream::AbortHandle; use galaxy_core::safe_error; -use galaxyui::{Entity, ModelContext, ModelHandle}; +use galaxyui_core::{Entity, ModelContext, ModelHandle}; use ignore::gitignore::Gitignore; use instant::Instant; #[cfg(feature = "local_fs")] use repo_metadata::entry::{BudgetExceededBehavior, IgnoredPathStrategy}; use repo_metadata::Repository; -use galaxyui_core::{Entity, ModelContext, ModelHandle}; use super::fragment_metadata::{ FragmentMetadata, LeafToFragmentMetadata, LeafToFragmentMetadataUpdates, diff --git a/crates/ai/src/index/full_source_code_embedding/codebase_index_tests.rs b/crates/ai/src/index/full_source_code_embedding/codebase_index_tests.rs index 56e10006..4b207d64 100644 --- a/crates/ai/src/index/full_source_code_embedding/codebase_index_tests.rs +++ b/crates/ai/src/index/full_source_code_embedding/codebase_index_tests.rs @@ -6,11 +6,11 @@ use std::sync::Arc; use chrono::Utc; use futures::executor::block_on; +use galaxy_util::standardized_path::StandardizedPath; +use galaxyui_core::{App, SingletonEntity}; use repo_metadata::DirectoryWatcher; use string_offset::ByteOffset; use virtual_fs::{Stub, VirtualFS}; -use warp_util::standardized_path::StandardizedPath; -use galaxyui_core::{App, SingletonEntity}; use super::{ CodebaseIndex, CodebaseIndexTimeStampMetadata, ServerSyncResult, TreeSourceSyncState, diff --git a/crates/ai/src/index/full_source_code_embedding/manager_tests.rs b/crates/ai/src/index/full_source_code_embedding/manager_tests.rs index a52ec26c..7f594da3 100644 --- a/crates/ai/src/index/full_source_code_embedding/manager_tests.rs +++ b/crates/ai/src/index/full_source_code_embedding/manager_tests.rs @@ -3,9 +3,9 @@ use std::sync::Arc; #[cfg(feature = "local_fs")] use chrono::Utc; +use galaxyui_core::App; #[cfg(feature = "local_fs")] use repo_metadata::DirectoryWatcher; -use galaxyui_core::App; use super::{ BuildSource, CodebaseIndexFinishedStatus, CodebaseIndexManager, CodebaseIndexManagerConfig, diff --git a/crates/ai/src/index/full_source_code_embedding/mod.rs b/crates/ai/src/index/full_source_code_embedding/mod.rs index e65da6ba..55780f7e 100644 --- a/crates/ai/src/index/full_source_code_embedding/mod.rs +++ b/crates/ai/src/index/full_source_code_embedding/mod.rs @@ -119,7 +119,7 @@ impl From for galaxy_graphql::full_source_code_embedding::Embed galaxy_graphql::full_source_code_embedding::EmbeddingConfig::Voyage35Lite512 } EmbeddingConfig::Voyage4_512 => { - warp_graphql::full_source_code_embedding::EmbeddingConfig::Voyage4512 + galaxy_graphql::full_source_code_embedding::EmbeddingConfig::Voyage4512 } } } @@ -144,7 +144,7 @@ impl TryFrom for Em galaxy_graphql::full_source_code_embedding::EmbeddingConfig::Voyage35512 => { Ok(Self::Voyage3_5_512) } - warp_graphql::full_source_code_embedding::EmbeddingConfig::Voyage4512 => { + galaxy_graphql::full_source_code_embedding::EmbeddingConfig::Voyage4512 => { Ok(Self::Voyage4_512) } } @@ -214,7 +214,7 @@ impl From for galaxy_graphql::queries::rerank_fragments::RerankFragmen Self { content: val.content, content_hash: val.content_hash.into(), - location: FragmentLocationInput { + location: galaxy_graphql::queries::rerank_fragments::FragmentLocationInput { byte_start: val.location.byte_range.start.as_usize() as i32, byte_end: val.location.byte_range.end.as_usize() as i32, file_path: val.location.absolute_path.to_string_lossy().to_string(), diff --git a/crates/ai/src/index/full_source_code_embedding/snapshot.rs b/crates/ai/src/index/full_source_code_embedding/snapshot.rs index acb90a67..5821474c 100644 --- a/crates/ai/src/index/full_source_code_embedding/snapshot.rs +++ b/crates/ai/src/index/full_source_code_embedding/snapshot.rs @@ -5,11 +5,9 @@ use std::time::Duration; use chrono::Utc; #[cfg(feature = "local_fs")] -use galaxyui::ModelHandle; +use galaxyui_core::ModelHandle; #[cfg(feature = "local_fs")] use repo_metadata::Repository; -#[cfg(feature = "local_fs")] -use galaxyui_core::ModelHandle; cfg_if::cfg_if! { if #[cfg(feature = "local_fs")] { diff --git a/crates/ai/src/index/full_source_code_embedding/sync_client.rs b/crates/ai/src/index/full_source_code_embedding/sync_client.rs index a00ac15e..c37feaa9 100644 --- a/crates/ai/src/index/full_source_code_embedding/sync_client.rs +++ b/crates/ai/src/index/full_source_code_embedding/sync_client.rs @@ -6,8 +6,8 @@ use std::pin::Pin; use std::sync::Arc; use anyhow::{anyhow, Result}; -use itertools::Itertools; use galaxy_core::sync_queue::{IsTransientError, SyncQueue, SyncQueueTaskTrait}; +use itertools::Itertools; use super::changed_files::ChangedFiles; use super::codebase_index::{build_fragments_from_metadata, SyncProgress}; @@ -272,7 +272,7 @@ impl<'a> CodebaseIndexSyncOperation<'a> { } let fragment_metadata_clone = fragment_metadatas.clone(); - let res = build_fragments_from_metadata(fragment_metadata_clone.into_iter()).await; + let res = build_fragments_from_metadata(fragment_metadata_clone).await; if !res.fail_to_read.is_empty() { let failed_node_count = res.fail_to_read.len(); diff --git a/crates/ai/src/paths.rs b/crates/ai/src/paths.rs index 3dab46b4..ab963018 100644 --- a/crates/ai/src/paths.rs +++ b/crates/ai/src/paths.rs @@ -3,6 +3,7 @@ use galaxy_util::path::{ convert_msys2_to_windows_native_path, convert_wsl_to_windows_host_path, msys2_exe_to_root, }; use galaxyui_core::platform::OperatingSystem; +use typed_path::{TypedPath, TypedPathBuf, WindowsPath}; fn use_unix_paths(shell: Option<&ShellLaunchData>) -> bool { OperatingSystem::get().is_linux() diff --git a/crates/ai/src/project_context/dummy_global_rules.rs b/crates/ai/src/project_context/dummy_global_rules.rs index 04932cb1..31434288 100644 --- a/crates/ai/src/project_context/dummy_global_rules.rs +++ b/crates/ai/src/project_context/dummy_global_rules.rs @@ -1,4 +1,4 @@ -use warp_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxyui_core::ModelContext; use super::model::{ProjectContextModel, ProjectRule}; diff --git a/crates/ai/src/project_context/global_rules.rs b/crates/ai/src/project_context/global_rules.rs index 3ea2eaab..f10bb554 100644 --- a/crates/ai/src/project_context/global_rules.rs +++ b/crates/ai/src/project_context/global_rules.rs @@ -2,14 +2,14 @@ use std::collections::{BTreeMap, HashMap}; use std::path::{Path, PathBuf}; use async_channel::Sender; +use galaxy_core::safe_warn; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::standardized_path::StandardizedPath; +use galaxyui_core::{ModelContext, ModelHandle, SingletonEntity}; use repo_metadata::repository::{RepositorySubscriber, SubscriberId}; use repo_metadata::{DirectoryWatcher, Repository, RepositoryUpdate}; use strum::IntoEnumIterator; use strum_macros::EnumIter; -use galaxy_core::safe_warn; -use warp_util::local_or_remote_path::LocalOrRemotePath; -use warp_util::standardized_path::StandardizedPath; -use galaxyui_core::{ModelContext, ModelHandle, SingletonEntity}; use watcher::{HomeDirectoryWatcher, HomeDirectoryWatcherEvent}; use super::model::{GlobalRulesDelta, ProjectContextModel, ProjectContextModelEvent, ProjectRule}; diff --git a/crates/ai/src/project_context/model.rs b/crates/ai/src/project_context/model.rs index deae6130..15962072 100644 --- a/crates/ai/src/project_context/model.rs +++ b/crates/ai/src/project_context/model.rs @@ -56,12 +56,21 @@ pub struct ProjectRule { #[derive(Debug, Clone)] struct RuleAtPath { parent_path: LocalOrRemotePath, + galaxy_md: Option, warp_md: Option, claude_md: Option, agents_md: Option, } impl RuleAtPath { + fn respected_rule(&self) -> Option<&ProjectRule> { + self.galaxy_md + .as_ref() + .or(self.warp_md.as_ref()) + .or(self.claude_md.as_ref()) + .or(self.agents_md.as_ref()) + } + fn all_rules(&self) -> Vec<&ProjectRule> { [ self.galaxy_md.as_ref(), @@ -105,8 +114,10 @@ impl ProjectRules { #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] fn rule_paths(&self) -> impl Iterator { self.rules.iter().flat_map(|rule| { - rule.warp_md + rule.galaxy_md .iter() + .chain(rule.warp_md.iter()) + .chain(rule.claude_md.iter()) .chain(rule.agents_md.iter()) .map(|rule| &rule.path) }) @@ -119,6 +130,13 @@ impl ProjectRules { #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] fn retain_rule_paths(&mut self, retained_paths: &HashSet) { self.rules.retain_mut(|rule| { + if rule + .galaxy_md + .as_ref() + .is_some_and(|rule| !retained_paths.contains(&rule.path)) + { + rule.galaxy_md = None; + } if rule .warp_md .as_ref() @@ -126,6 +144,13 @@ impl ProjectRules { { rule.warp_md = None; } + if rule + .claude_md + .as_ref() + .is_some_and(|rule| !retained_paths.contains(&rule.path)) + { + rule.claude_md = None; + } if rule .agents_md .as_ref() @@ -133,7 +158,10 @@ impl ProjectRules { { rule.agents_md = None; } - rule.warp_md.is_some() || rule.agents_md.is_some() + rule.galaxy_md.is_some() + || rule.warp_md.is_some() + || rule.claude_md.is_some() + || rule.agents_md.is_some() }); } /// Finds the set of rules that are active in the given path and the set that are available to be applied. @@ -185,15 +213,22 @@ impl ProjectRules { None => { let mut rule = RuleAtPath { parent_path: parent, + galaxy_md: None, warp_md: None, + claude_md: None, agents_md: None, }; - if file_name.to_lowercase() == "warp.md" { - rule.warp_md = rule_file; + if file_name.to_lowercase() == "galaxy.md" { + rule.galaxy_md = rule_file.clone(); + } else if file_name.to_lowercase() == "warp.md" { + rule.warp_md = rule_file.clone(); + } else if file_name.to_lowercase() == "claude.md" { + rule.claude_md = rule_file.clone(); } else if file_name.to_lowercase() == "agents.md" { - rule.agents_md = rule_file; + rule.agents_md = rule_file.clone(); } self.rules.push(rule); + self.rules.last_mut().unwrap() } }; diff --git a/crates/ai/src/project_context/model_tests.rs b/crates/ai/src/project_context/model_tests.rs index 0961d3c1..69c194c9 100644 --- a/crates/ai/src/project_context/model_tests.rs +++ b/crates/ai/src/project_context/model_tests.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; -use warp_util::host_id::HostId; -use warp_util::local_or_remote_path::LocalOrRemotePath; -use warp_util::remote_path::RemotePath; -use warp_util::standardized_path::StandardizedPath; +use galaxy_util::host_id::HostId; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; fn local_path(path: &str) -> LocalOrRemotePath { LocalOrRemotePath::Local(PathBuf::from(path)) @@ -169,7 +169,7 @@ fn test_find_applicable_rules_complex_scenario() { let path = local_path("/a/b/c/file.rs"); let result = rules.find_active_or_applicable_rules(&path).active_rules; - assert_eq!(result.len(), 4); + assert_eq!(result.len(), 2); // Expect only WARP.md files to be included as they have higher priority. assert_eq!(result[0].path, local_path("/a/WARP.md")); diff --git a/crates/ai/src/skills/conversion.rs b/crates/ai/src/skills/conversion.rs index c358aea1..4bb8310e 100644 --- a/crates/ai/src/skills/conversion.rs +++ b/crates/ai/src/skills/conversion.rs @@ -1,11 +1,11 @@ use std::path::PathBuf; +use galaxy_util::host_id::HostId; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; use thiserror::Error; use warp_multi_agent_api as api; -use warp_util::host_id::HostId; -use warp_util::local_or_remote_path::LocalOrRemotePath; -use warp_util::remote_path::RemotePath; -use warp_util::standardized_path::StandardizedPath; use crate::agent::action_result::{AnyFileContent, FileContext}; use crate::skills::{ParsedSkill, SkillProvider, SkillReference, SkillScope}; diff --git a/crates/ai/src/skills/conversion_tests.rs b/crates/ai/src/skills/conversion_tests.rs index c08149a5..45490abf 100644 --- a/crates/ai/src/skills/conversion_tests.rs +++ b/crates/ai/src/skills/conversion_tests.rs @@ -1,8 +1,8 @@ +use galaxy_util::host_id::HostId; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; use warp_multi_agent_api as api; -use warp_util::host_id::HostId; -use warp_util::local_or_remote_path::LocalOrRemotePath; -use warp_util::remote_path::RemotePath; -use warp_util::standardized_path::StandardizedPath; use super::{ skill_reference_from_api_skill_ref, skill_reference_from_read_skill_ref, SkillConversionError, diff --git a/crates/ai/src/skills/parse_skill.rs b/crates/ai/src/skills/parse_skill.rs index 5b0f0d7c..2435e205 100644 --- a/crates/ai/src/skills/parse_skill.rs +++ b/crates/ai/src/skills/parse_skill.rs @@ -4,10 +4,10 @@ use std::ops::Range; use std::path::Path; use anyhow::Result; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use lazy_static::lazy_static; use regex::Regex; use thiserror::Error; -use warp_util::local_or_remote_path::LocalOrRemotePath; use super::parser::parse_markdown_content; use super::skill_provider::{get_provider_for_path, get_scope_for_path, SkillProvider, SkillScope}; diff --git a/crates/ai/src/skills/parse_skill_tests.rs b/crates/ai/src/skills/parse_skill_tests.rs index 9054c49e..cd7bb21b 100644 --- a/crates/ai/src/skills/parse_skill_tests.rs +++ b/crates/ai/src/skills/parse_skill_tests.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use tempfile::TempDir; -use warp_util::local_or_remote_path::LocalOrRemotePath; use super::*; diff --git a/crates/ai/src/skills/read_skills_tests.rs b/crates/ai/src/skills/read_skills_tests.rs index 0ad25711..0ca18bb3 100644 --- a/crates/ai/src/skills/read_skills_tests.rs +++ b/crates/ai/src/skills/read_skills_tests.rs @@ -1,7 +1,7 @@ use std::fs; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use tempfile::tempdir; -use warp_util::local_or_remote_path::LocalOrRemotePath; use super::*; diff --git a/crates/ai/src/skills/skill_provider.rs b/crates/ai/src/skills/skill_provider.rs index 61b9bd53..9de1072d 100644 --- a/crates/ai/src/skills/skill_provider.rs +++ b/crates/ai/src/skills/skill_provider.rs @@ -7,12 +7,12 @@ use std::path::{Path, PathBuf}; use std::sync::LazyLock; use dirs::home_dir; -use serde::{Deserialize, Serialize}; -use strum_macros::{Display, EnumString, VariantNames}; use galaxy_core::ui::color::CLAUDE_ORANGE; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::Fill; use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use serde::{Deserialize, Serialize}; +use strum_macros::{Display, EnumString, VariantNames}; /// Represents a skill provider/origin (Agents, Claude, Codex, or Warp). #[derive( diff --git a/crates/ai/src/skills/skill_provider_tests.rs b/crates/ai/src/skills/skill_provider_tests.rs index 5b242b6d..b3a38861 100644 --- a/crates/ai/src/skills/skill_provider_tests.rs +++ b/crates/ai/src/skills/skill_provider_tests.rs @@ -1,7 +1,7 @@ -use warp_util::host_id::HostId; -use warp_util::local_or_remote_path::LocalOrRemotePath; -use warp_util::remote_path::RemotePath; -use warp_util::standardized_path::StandardizedPath; +use galaxy_util::host_id::HostId; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; +use galaxy_util::remote_path::RemotePath; +use galaxy_util::standardized_path::StandardizedPath; use super::{ get_provider_for_path, get_scope_for_path, home_skills_path, @@ -12,13 +12,13 @@ use super::{ fn warp_home_skills_path_uses_warp_home_path() { assert_eq!( home_skills_path(SkillProvider::Warp), - galaxy_core::paths::warp_home_skills_dir() + galaxy_core::paths::galaxy_home_skills_dir() ); } #[test] fn warp_home_skill_path_is_home_warp_skill() { - let Some(warp_home_skills_dir) = galaxy_core::paths::warp_home_skills_dir() else { + let Some(warp_home_skills_dir) = galaxy_core::paths::galaxy_home_skills_dir() else { eprintln!("Skipping test: home directory not available"); return; }; diff --git a/crates/ai/src/skills/skill_reference.rs b/crates/ai/src/skills/skill_reference.rs index fe9faeac..40009ac3 100644 --- a/crates/ai/src/skills/skill_reference.rs +++ b/crates/ai/src/skills/skill_reference.rs @@ -1,7 +1,7 @@ use std::fmt; +use galaxy_util::local_or_remote_path::LocalOrRemotePath; use serde::{Deserialize, Serialize}; -use warp_util::local_or_remote_path::LocalOrRemotePath; /// An unique reference to a skill. #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] diff --git a/crates/ai/src/telemetry.rs b/crates/ai/src/telemetry.rs index 6c3e7128..dfaf1dd5 100644 --- a/crates/ai/src/telemetry.rs +++ b/crates/ai/src/telemetry.rs @@ -1,11 +1,11 @@ use std::time::Duration; -use serde::Serialize; -use serde_json::{json, Value}; -use strum_macros::{EnumDiscriminants, EnumIter}; use galaxy_core::features::FeatureFlag; use galaxy_core::register_telemetry_event; use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; +use serde::Serialize; +use serde_json::{json, Value}; +use strum_macros::{EnumDiscriminants, EnumIter}; #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] #[derive(Clone, EnumDiscriminants)] diff --git a/crates/asset_macro/src/lib.rs b/crates/asset_macro/src/lib.rs index 94d16a6c..37524c84 100644 --- a/crates/asset_macro/src/lib.rs +++ b/crates/asset_macro/src/lib.rs @@ -25,12 +25,12 @@ extern crate proc_macro; use std::env; use std::path::{Path, PathBuf}; +use galaxy_util::assets::{ASSETS_DIR, ASYNC_ASSETS_DIR, BUNDLED_ASSETS_DIR, REMOTE_ASSETS_DIR}; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use sha2::Digest; use syn::parse::Parse; use syn::{parse_macro_input, LitStr, Token}; -use galaxy_util::assets::{ASSETS_DIR, ASYNC_ASSETS_DIR, BUNDLED_ASSETS_DIR, REMOTE_ASSETS_DIR}; struct MacroArgs { /// The name of the asset. E.g. `jpg/jellyfish_bg.jpg` diff --git a/crates/cloud_object_models/src/folder/persistence.rs b/crates/cloud_object_models/src/folder/persistence.rs index 979684be..8ef008c5 100644 --- a/crates/cloud_object_models/src/folder/persistence.rs +++ b/crates/cloud_object_models/src/folder/persistence.rs @@ -84,6 +84,7 @@ pub fn read_folders( } pub fn delete_folder(conn: &mut SqliteConnection, folder_id: i32) -> Result<(), Error> { + use schema::folders::dsl::*; diesel::delete(folders.filter(id.eq(folder_id))).execute(conn)?; Ok(()) } diff --git a/crates/cloud_object_models/src/notebook/persistence.rs b/crates/cloud_object_models/src/notebook/persistence.rs index b47aee44..d1f754b0 100644 --- a/crates/cloud_object_models/src/notebook/persistence.rs +++ b/crates/cloud_object_models/src/notebook/persistence.rs @@ -98,6 +98,7 @@ pub fn read_notebooks( } pub fn delete_notebook(conn: &mut SqliteConnection, notebook_id: i32) -> Result<(), Error> { + use schema::notebooks::dsl::*; diesel::delete(notebooks.filter(id.eq(notebook_id))).execute(conn)?; Ok(()) } diff --git a/crates/cloud_object_models/src/workflow/persistence.rs b/crates/cloud_object_models/src/workflow/persistence.rs index c8f32ceb..c3b5a2f7 100644 --- a/crates/cloud_object_models/src/workflow/persistence.rs +++ b/crates/cloud_object_models/src/workflow/persistence.rs @@ -77,6 +77,7 @@ pub fn read_workflows( } pub fn delete_workflow(conn: &mut SqliteConnection, workflow_id: i32) -> Result<(), Error> { + use schema::workflows::dsl::*; diesel::delete(workflows.filter(id.eq(workflow_id))).execute(conn)?; Ok(()) } diff --git a/crates/cloud_object_persistence/src/objects.rs b/crates/cloud_object_persistence/src/objects.rs index 959720e5..2d88b11d 100644 --- a/crates/cloud_object_persistence/src/objects.rs +++ b/crates/cloud_object_persistence/src/objects.rs @@ -436,6 +436,7 @@ pub fn delete_generic_string_object( conn: &mut SqliteConnection, generic_string_object_id: CloudObjectId, ) -> Result<(), Error> { + use schema::generic_string_objects::dsl::*; diesel::delete(generic_string_objects.filter(id.eq(generic_string_object_id))).execute(conn)?; Ok(()) } @@ -447,6 +448,7 @@ pub fn mark_object_as_synced( new_revision_and_editor: RevisionAndLastEditor, new_metadata_ts: Option, ) -> Result<(), Error> { + use schema::object_metadata::dsl::*; conn.transaction::<(), Error, _>(|conn| { diesel::update(object_metadata.filter(server_id.eq(Some(hashed_sqlite_id.as_str())))) .set(is_pending.eq(false)) @@ -471,6 +473,7 @@ pub fn increment_retry_count( conn: &mut SqliteConnection, server_id_string: String, ) -> Result<(), Error> { + use schema::object_metadata::dsl::*; conn.transaction::<(), Error, _>(|conn| { diesel::update(object_metadata.filter(server_id.eq(Some(server_id_string)))) .set(retry_count.eq(retry_count + 1)) @@ -485,6 +488,7 @@ pub fn update_object_after_server_creation( server_creation_info: ServerCreationInfo, ) -> Result<(), Error> { use schema::commands::dsl::*; + use schema::object_metadata::dsl::*; conn.transaction::<(), Error, _>(|conn| { diesel::update(object_metadata.filter(client_id.eq(Some(client_id_string.clone())))) @@ -519,6 +523,7 @@ pub fn update_object_metadata( hashed_id: String, metadata: CloudObjectMetadata, ) -> Result<(), Error> { + use schema::object_metadata::dsl::*; let metadata_last_updated_at = metadata .metadata_last_updated_ts .map(|ts| ts.timestamp_micros()); diff --git a/crates/cloud_object_persistence/src/refresh.rs b/crates/cloud_object_persistence/src/refresh.rs index 62a240f2..580f44a9 100644 --- a/crates/cloud_object_persistence/src/refresh.rs +++ b/crates/cloud_object_persistence/src/refresh.rs @@ -24,6 +24,7 @@ pub fn record_time_of_next_refresh( pub fn read_time_of_next_force_object_refresh( conn: &mut SqliteConnection, ) -> Result>, Error> { + use schema::cloud_objects_refreshes::dsl::*; // Find the smallest refresh timestamp to pass into CloudModel. Ok(cloud_objects_refreshes .select(time_of_next_refresh) diff --git a/crates/cloud_objects/Cargo.toml b/crates/cloud_objects/Cargo.toml index 84e0657a..356b4fee 100644 --- a/crates/cloud_objects/Cargo.toml +++ b/crates/cloud_objects/Cargo.toml @@ -23,7 +23,7 @@ settings_value.workspace = true session-sharing-protocol.workspace = true thiserror.workspace = true uuid.workspace = true -warp_core.workspace = true -warp_graphql.workspace = true +galaxy_core.workspace = true +galaxy_graphql.workspace = true warp_server_auth.workspace = true -warpui_core.workspace = true +galaxyui_core.workspace = true diff --git a/crates/cloud_objects/src/cloud_object/creation.rs b/crates/cloud_objects/src/cloud_object/creation.rs index 8c2d532b..7347f4ab 100644 --- a/crates/cloud_objects/src/cloud_object/creation.rs +++ b/crates/cloud_objects/src/cloud_object/creation.rs @@ -1,4 +1,4 @@ -use warp_graphql::scalars::time::ServerTimestamp; +use galaxy_graphql::scalars::time::ServerTimestamp; use super::{ CloudObjectEventEntrypoint, GenericStringObjectFormat, GenericStringObjectUniqueKey, Owner, diff --git a/crates/cloud_objects/src/cloud_object/mod.rs b/crates/cloud_objects/src/cloud_object/mod.rs index 51b17fb3..8367c7e5 100644 --- a/crates/cloud_objects/src/cloud_object/mod.rs +++ b/crates/cloud_objects/src/cloud_object/mod.rs @@ -5,8 +5,6 @@ use std::str::FromStr; use anyhow::{Result, anyhow}; use chrono::{DateTime, Utc}; use derivative::Derivative; -use pathfinder_geometry::vector::vec2f; -use serde::{Deserialize, Serialize}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::Icon; use galaxy_core::ui::appearance::Appearance; @@ -19,6 +17,8 @@ use galaxyui_core::elements::{ ParentAnchor, ParentElement, ParentOffsetBounds, Stack, }; use galaxyui_core::ui_components::components::UiComponent; +use pathfinder_geometry::vector::vec2f; +use serde::{Deserialize, Serialize}; use crate::auth::UserUid; use crate::drive::sharing::{SharingAccessLevel, Subject, TeamKind, UserKind}; diff --git a/crates/cloud_objects/src/cloud_object/update.rs b/crates/cloud_objects/src/cloud_object/update.rs index d7238e7d..990259a0 100644 --- a/crates/cloud_objects/src/cloud_object/update.rs +++ b/crates/cloud_objects/src/cloud_object/update.rs @@ -1,4 +1,4 @@ -use warp_graphql::queries::get_updated_cloud_objects::UpdatedObjectInput; +use galaxy_graphql::queries::get_updated_cloud_objects::UpdatedObjectInput; use super::RevisionAndLastEditor; diff --git a/crates/computer_use/src/linux/wayland/mod.rs b/crates/computer_use/src/linux/wayland/mod.rs index 5cac82db..ace839df 100644 --- a/crates/computer_use/src/linux/wayland/mod.rs +++ b/crates/computer_use/src/linux/wayland/mod.rs @@ -11,11 +11,11 @@ mod screenshot; mod session; use async_trait::async_trait; +use galaxyui_core::r#async::Timer; use keyboard::Keyboard; use mouse::Mouse; use pathfinder_geometry::vector::Vector2I; use session::PortalSession; -use galaxyui_core::r#async::Timer; use crate::{Action, ActionResult, Options, TargetedAction}; diff --git a/crates/computer_use/src/linux/x11/mod.rs b/crates/computer_use/src/linux/x11/mod.rs index 3a97a342..fec45fb6 100644 --- a/crates/computer_use/src/linux/x11/mod.rs +++ b/crates/computer_use/src/linux/x11/mod.rs @@ -6,8 +6,8 @@ mod screenshot; use async_trait::async_trait; use galaxyui::r#async::Timer; -use pathfinder_geometry::vector::Vector2I; use galaxyui_core::r#async::Timer; +use pathfinder_geometry::vector::Vector2I; use x11rb::connection::Connection; use x11rb::protocol::xproto::{self, ConnectionExt as _}; use x11rb::protocol::xtest::ConnectionExt as _; diff --git a/crates/computer_use/src/mac/mod.rs b/crates/computer_use/src/mac/mod.rs index f6b5d2d0..2832ebba 100644 --- a/crates/computer_use/src/mac/mod.rs +++ b/crates/computer_use/src/mac/mod.rs @@ -8,10 +8,10 @@ mod util; mod window; use async_trait::async_trait; +use galaxyui_core::r#async::Timer; use pathfinder_geometry::vector::Vector2I; use post::PostTarget; use util::{display_scale_factor_for_window, main_display_scale_factor}; -use galaxyui_core::r#async::Timer; use crate::{Action, ActionResult, Options, Target, TargetedAction}; diff --git a/crates/computer_use/src/mac/mouse.rs b/crates/computer_use/src/mac/mouse.rs index 860c0ce5..89af8022 100644 --- a/crates/computer_use/src/mac/mouse.rs +++ b/crates/computer_use/src/mac/mouse.rs @@ -1,5 +1,6 @@ use std::time::Duration; +use galaxyui_core::r#async::Timer; use instant::Instant; use objc2::rc::Retained; use objc2_core_foundation::CGPoint; @@ -8,7 +9,6 @@ use objc2_core_graphics::{ CGScrollEventUnit, }; use pathfinder_geometry::vector::Vector2I; -use galaxyui_core::r#async::Timer; use super::post::PostTarget; use super::util::main_display_scale_factor; diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index 48d4df0b..e26159bc 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -49,6 +49,7 @@ pathfinder_color = "0.5.0" unicode-width.workspace = true vec1.workspace = true galaxyui_core.workspace = true +galaxyui.workspace = true galaxy_core.workspace = true galaxy_util.workspace = true rayon.workspace = true diff --git a/crates/editor/benches/buffer_bench.rs b/crates/editor/benches/buffer_bench.rs index f667858d..02e09304 100644 --- a/crates/editor/benches/buffer_bench.rs +++ b/crates/editor/benches/buffer_bench.rs @@ -1,12 +1,12 @@ use std::fs; use criterion::{Criterion, criterion_group, criterion_main}; -use rand::SeedableRng; -use rand::rngs::StdRng; use galaxy_editor::content::buffer::Buffer; use galaxy_editor::content::selection_model::BufferSelectionModel; use galaxy_editor::content::text::IndentBehavior; use galaxyui_core::{App, ModelHandle}; +use rand::SeedableRng; +use rand::rngs::StdRng; const EDIT_SAMPLE_SIZE: usize = 10; const MAX_EDIT_REPLACEMENT_LENGTH: usize = 20; diff --git a/crates/editor/src/content/anchor_tests.rs b/crates/editor/src/content/anchor_tests.rs index 6799fc76..d89e116f 100644 --- a/crates/editor/src/content/anchor_tests.rs +++ b/crates/editor/src/content/anchor_tests.rs @@ -1,8 +1,8 @@ use std::cmp::Ordering; +use galaxyui_core::App; use string_offset::CharOffset; use sum_tree::SumTree; -use galaxyui_core::App; use super::{AnchorSide, Anchors}; use crate::content::anchor::{Anchor, AnchorUpdate}; diff --git a/crates/editor/src/content/buffer.rs b/crates/editor/src/content/buffer.rs index dd2edad6..1a5b3fab 100644 --- a/crates/editor/src/content/buffer.rs +++ b/crates/editor/src/content/buffer.rs @@ -5,6 +5,14 @@ use std::ops::Range; use std::sync::Arc; use enum_iterator::all; +use galaxy_core::platform::SessionPlatform; +use galaxy_core::safe_error; +use galaxy_util::content_version::ContentVersion; +use galaxyui_core::elements::ListIndentLevel; +use galaxyui_core::fonts::Weight; +use galaxyui_core::text::point::Point; +use galaxyui_core::text::{TextBuffer, char_slice}; +use galaxyui_core::{AppContext, Entity, EntityId, ModelContext, ModelHandle}; use itertools::{Either, Itertools}; use line_ending::LineEnding; use markdown_parser::{ @@ -20,14 +28,6 @@ use serde_yaml::Mapping; use string_offset::{ByteOffset, CharOffset}; use sum_tree::{SeekBias, SumTree}; use vec1::{Vec1, vec1}; -use galaxy_core::platform::SessionPlatform; -use galaxy_core::safe_error; -use galaxy_util::content_version::ContentVersion; -use galaxyui_core::elements::ListIndentLevel; -use galaxyui_core::fonts::Weight; -use galaxyui_core::text::point::Point; -use galaxyui_core::text::{TextBuffer, char_slice}; -use galaxyui_core::{AppContext, Entity, EntityId, ModelContext, ModelHandle}; use super::anchor::{Anchor, AnchorSide, Anchors}; use super::cursor::BufferCursor; diff --git a/crates/editor/src/content/buffer_tests.rs b/crates/editor/src/content/buffer_tests.rs index e807a9cb..1f2a0461 100644 --- a/crates/editor/src/content/buffer_tests.rs +++ b/crates/editor/src/content/buffer_tests.rs @@ -2,7 +2,10 @@ use std::ops::Range; use std::sync::Arc; use std::sync::atomic::{AtomicU8, Ordering}; +use galaxy_util::content_version::ContentVersion; use galaxyui::{App, AppContext, ModelContext, ModelHandle, ReadModel}; +use galaxyui_core::elements::ListIndentLevel; +use galaxyui_core::text::point::Point; use line_ending::LineEnding; use markdown_parser::{ FormattedIndentTextInline, FormattedText, FormattedTextFragment, FormattedTextLine, parse_html, @@ -14,10 +17,6 @@ use rand::rngs::StdRng; use serde_yaml::{Mapping, Value}; use string_offset::{ByteOffset, CharOffset}; use vec1::{Vec1, vec1}; -use galaxy_util::content_version::ContentVersion; -use galaxyui_core::elements::ListIndentLevel; -use galaxyui_core::text::point::Point; -use galaxyui_core::{App, AppContext, ModelContext, ModelHandle, ReadModel}; use super::{BufferEvent, EditResult, ToBufferCharOffset}; use crate::content::buffer::{ diff --git a/crates/editor/src/content/core.rs b/crates/editor/src/content/core.rs index d62c8321..60e5f865 100644 --- a/crates/editor/src/content/core.rs +++ b/crates/editor/src/content/core.rs @@ -5,7 +5,6 @@ use galaxyui::elements::ListIndentLevel; use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; use string_offset::CharOffset; use sum_tree::SumTree; -use galaxyui_core::elements::ListIndentLevel; use super::buffer::{Buffer, EditOrigin, EditResult}; use super::cursor::BufferSumTree; diff --git a/crates/editor/src/content/edit.rs b/crates/editor/src/content/edit.rs index d07fc62f..e2a1c3c8 100644 --- a/crates/editor/src/content/edit.rs +++ b/crates/editor/src/content/edit.rs @@ -5,14 +5,6 @@ use std::ops::Range; use std::path::{Path, PathBuf}; use anyhow::{Result, anyhow}; -use itertools::Itertools; -use markdown_parser::{Hyperlink, TableAlignment}; -use num_traits::SaturatingSub; -use rangemap::RangeSet; -use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; -use string_offset::{ByteOffset, CharOffset}; -use urlocator::{UrlLocation, UrlLocator}; -use vec1::Vec1; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::theme::Fill as ThemeFill; use galaxyui_core::assets::asset_cache::{AssetCache, AssetSource, AssetState}; @@ -23,6 +15,14 @@ use galaxyui_core::text::point::Point; use galaxyui_core::text_layout::{StyleAndFont, TextAlignment}; use galaxyui_core::units::{IntoPixels, Pixels}; use galaxyui_core::{AppContext, SingletonEntity}; +use itertools::Itertools; +use markdown_parser::{Hyperlink, TableAlignment}; +use num_traits::SaturatingSub; +use rangemap::RangeSet; +use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; +use string_offset::{ByteOffset, CharOffset}; +use urlocator::{UrlLocation, UrlLocator}; +use vec1::Vec1; use super::buffer::{StyledBufferBlock, StyledBufferRun, StyledTextBlock}; use super::mermaid_diagram::{mermaid_asset_source, mermaid_diagram_layout}; diff --git a/crates/editor/src/content/edit_tests.rs b/crates/editor/src/content/edit_tests.rs index 87ba7742..45ff3613 100644 --- a/crates/editor/src/content/edit_tests.rs +++ b/crates/editor/src/content/edit_tests.rs @@ -1,12 +1,12 @@ use std::path::Path; -use string_offset::CharOffset; use galaxy_core::features::FeatureFlag; use galaxyui_core::assets::asset_cache::{AssetCache, AssetSource, AssetState}; use galaxyui_core::fonts::{Properties, Style, Weight}; use galaxyui_core::image_cache::ImageType; use galaxyui_core::text_layout::{LayoutCache, StyleAndFont, TextStyle}; use galaxyui_core::{App, SingletonEntity}; +use string_offset::CharOffset; use super::{ BlockLocation, LayOutArgs, layout_mermaid_diagram_block, layout_table_block, layout_text_block, diff --git a/crates/editor/src/content/find_tests.rs b/crates/editor/src/content/find_tests.rs index bb9ffedb..4ccde39a 100644 --- a/crates/editor/src/content/find_tests.rs +++ b/crates/editor/src/content/find_tests.rs @@ -8,7 +8,6 @@ use itertools::Itertools; use rangemap::RangeSet; use string_offset::CharOffset; use sum_tree::SumTree; -use galaxyui_core::App; use super::{Engine, Match, SearchConfig}; use crate::content::buffer::Buffer; diff --git a/crates/editor/src/content/hidden_lines_model.rs b/crates/editor/src/content/hidden_lines_model.rs index 796f0196..17027a39 100644 --- a/crates/editor/src/content/hidden_lines_model.rs +++ b/crates/editor/src/content/hidden_lines_model.rs @@ -4,7 +4,6 @@ use std::ops::Range; use galaxyui::{AppContext, Entity, ModelContext, ModelHandle}; use rangemap::RangeSet; use string_offset::CharOffset; -use galaxyui_core::{AppContext, Entity, ModelContext, ModelHandle}; use super::anchor::{Anchor, AnchorSide}; use crate::content::buffer::Buffer; diff --git a/crates/editor/src/content/markdown.rs b/crates/editor/src/content/markdown.rs index b050534d..49c4a5aa 100644 --- a/crates/editor/src/content/markdown.rs +++ b/crates/editor/src/content/markdown.rs @@ -4,6 +4,9 @@ use std::ops::Range; use std::{io, iter}; use anyhow::{Context, Result}; +use galaxyui_core::elements::{ListIndentLevel, ListNumbering}; +use galaxyui_core::text::point::Point; +use galaxyui_core::{AppContext, ModelContext, ModelHandle}; use html5ever::serialize::{Serialize, Serializer, TraversalScope}; use html5ever::{QualName, serialize}; use itertools::Itertools; @@ -14,9 +17,6 @@ use markdown_parser::{ }; use markup5ever::ns; use string_offset::CharOffset; -use galaxyui_core::elements::{ListIndentLevel, ListNumbering}; -use galaxyui_core::text::point::Point; -use galaxyui_core::{AppContext, ModelContext, ModelHandle}; use super::buffer::{ ActionWithSelectionDelta, Buffer, EditOrigin, EditResult, StyledBufferBlock, diff --git a/crates/editor/src/content/markdown_tests.rs b/crates/editor/src/content/markdown_tests.rs index b750e405..6c90e3b2 100644 --- a/crates/editor/src/content/markdown_tests.rs +++ b/crates/editor/src/content/markdown_tests.rs @@ -5,7 +5,6 @@ use markdown_parser::{compute_formatted_text_delta, parse_markdown}; use serde_yaml::Value; use string_offset::CharOffset; use vec1::Vec1; -use galaxyui_core::{App, ReadModel}; use super::MarkdownStyle; use crate::content::buffer::tests::TestEmbeddedItem; diff --git a/crates/editor/src/content/outline_tests.rs b/crates/editor/src/content/outline_tests.rs index 1ce92187..5966635f 100644 --- a/crates/editor/src/content/outline_tests.rs +++ b/crates/editor/src/content/outline_tests.rs @@ -1,6 +1,6 @@ +use galaxyui_core::App; use itertools::Itertools; use string_offset::CharOffset; -use galaxyui_core::App; use crate::content::buffer::Buffer; use crate::content::outline::BlockOutline; diff --git a/crates/editor/src/content/segmentation.rs b/crates/editor/src/content/segmentation.rs index 054cc312..6484ae4f 100644 --- a/crates/editor/src/content/segmentation.rs +++ b/crates/editor/src/content/segmentation.rs @@ -3,11 +3,10 @@ //! [`TextBuffer`] API. use anyhow::anyhow; -use galaxyui::text::{TextBuffer, point::Point, word_boundaries::WordBoundariesPolicy}; +use galaxyui::text::TextBuffer; +use galaxyui::text::point::Point; +use galaxyui::text::word_boundaries::WordBoundariesPolicy; use string_offset::CharOffset; -use galaxyui_core::text::TextBuffer; -use galaxyui_core::text::point::Point; -use galaxyui_core::text::word_boundaries::WordBoundariesPolicy; use super::buffer::{Buffer, ToBufferCharOffset, ToBufferPoint}; use super::cursor::BufferCursor; diff --git a/crates/editor/src/content/segmentation_tests.rs b/crates/editor/src/content/segmentation_tests.rs index 935d0b9a..b7c4c024 100644 --- a/crates/editor/src/content/segmentation_tests.rs +++ b/crates/editor/src/content/segmentation_tests.rs @@ -1,11 +1,11 @@ use galaxy_core::features::FeatureFlag; -use itertools::Itertools; -use markdown_parser::parse_markdown; -use string_offset::CharOffset; use galaxyui_core::App; use galaxyui_core::text::TextBuffer; use galaxyui_core::text::point::Point; use galaxyui_core::text::word_boundaries::WordBoundariesPolicy; +use itertools::Itertools; +use markdown_parser::parse_markdown; +use string_offset::CharOffset; use crate::content::buffer::{Buffer, EditOrigin}; use crate::content::selection_model::BufferSelectionModel; diff --git a/crates/editor/src/content/selection_model.rs b/crates/editor/src/content/selection_model.rs index 3048e1c1..f065e850 100644 --- a/crates/editor/src/content/selection_model.rs +++ b/crates/editor/src/content/selection_model.rs @@ -4,7 +4,6 @@ use galaxyui::{AppContext, Entity, ModelHandle}; use itertools::Itertools; use string_offset::CharOffset; use vec1::{Vec1, vec1}; -use galaxyui_core::{AppContext, Entity, ModelHandle}; use crate::content::anchor::{Anchor, AnchorSide, AnchorUpdate, Anchors}; use crate::content::buffer::{Buffer, SelectionOffsets, ToBufferPoint}; diff --git a/crates/editor/src/content/text.rs b/crates/editor/src/content/text.rs index 03fff5f7..71278c03 100644 --- a/crates/editor/src/content/text.rs +++ b/crates/editor/src/content/text.rs @@ -8,13 +8,11 @@ use std::sync::{Arc, OnceLock}; use arrayvec::ArrayString; use enum_iterator::Sequence; use galaxy_core::features::FeatureFlag; +use galaxyui::AppContext; use galaxyui::elements::ListIndentLevel; +use galaxyui::fonts::{Properties, Style, Weight}; use galaxyui::text::BlockHeaderSize as HeaderSize; use galaxyui::text::point::Point; -use galaxyui::{ - AppContext, - fonts::{Properties, Style, Weight}, -}; use lazy_static::lazy_static; pub use markdown_parser::markdown_parser::TABLE_BLOCK_MARKDOWN_LANG; use markdown_parser::markdown_parser::{ @@ -33,11 +31,6 @@ use rand::Rng; use serde::{Deserialize, Serialize}; use string_offset::{ByteOffset, CharOffset, impl_offset}; use sum_tree::{Cursor, SeekBias, SumTree}; -use galaxyui_core::AppContext; -use galaxyui_core::elements::ListIndentLevel; -use galaxyui_core::fonts::{Properties, Style, Weight}; -use galaxyui_core::text::BlockHeaderSize as HeaderSize; -use galaxyui_core::text::point::Point; use super::buffer::Buffer; use super::core::CursorType; diff --git a/crates/editor/src/content/text_tests.rs b/crates/editor/src/content/text_tests.rs index 137b4403..e88d352d 100644 --- a/crates/editor/src/content/text_tests.rs +++ b/crates/editor/src/content/text_tests.rs @@ -1,6 +1,6 @@ -use markdown_parser::{CodeBlockText, FormattedTable}; use galaxy_core::features::FeatureFlag; use galaxyui_core::fonts::Weight; +use markdown_parser::{CodeBlockText, FormattedTable}; use super::{ BufferBlockItem, BufferTextStyle, CodeBlockType, MarkdownStyle, TextStyles, diff --git a/crates/editor/src/content/validation_tests.rs b/crates/editor/src/content/validation_tests.rs index 1371eb5a..e6e54890 100644 --- a/crates/editor/src/content/validation_tests.rs +++ b/crates/editor/src/content/validation_tests.rs @@ -1,5 +1,5 @@ -use sum_tree::SumTree; use galaxyui_core::elements::ListIndentLevel; +use sum_tree::SumTree; use crate::content::cursor::BufferSumTree; use crate::content::text::{ diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index bab2e0be..f3c06c82 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -5,13 +5,13 @@ use std::any::Any; use std::cell::Ref; use std::ops::Range; +use galaxyui_core::elements::Border; +use galaxyui_core::text_layout::PaintStyleOverride; +use galaxyui_core::{Action, AppContext, Element, TypedActionView, View}; use num_traits::SaturatingSub; use pathfinder_color::ColorU; use rangemap::{RangeMap, RangeSet}; use string_offset::CharOffset; -use galaxyui_core::elements::Border; -use galaxyui_core::text_layout::PaintStyleOverride; -use galaxyui_core::{Action, AppContext, Element, TypedActionView, View}; use crate::content::version::BufferVersion; use crate::render::element::RichTextAction; diff --git a/crates/editor/src/model.rs b/crates/editor/src/model.rs index 6ee55a9d..205782f6 100644 --- a/crates/editor/src/model.rs +++ b/crates/editor/src/model.rs @@ -1,15 +1,12 @@ use std::ops::Range; -use galaxyui::{ - AppContext, Entity, ModelAsRef, ModelContext, ModelHandle, clipboard::ClipboardContent, -}; +use galaxyui::clipboard::ClipboardContent; +use galaxyui::elements::ListIndentLevel; +use galaxyui::{AppContext, Entity, ModelAsRef, ModelContext, ModelHandle}; use itertools::{Either, Itertools}; use line_ending::LineEnding; use string_offset::{ByteOffset, CharOffset}; use vec1::{Vec1, vec1}; -use galaxyui_core::clipboard::ClipboardContent; -use galaxyui_core::elements::ListIndentLevel; -use galaxyui_core::{AppContext, Entity, ModelAsRef, ModelContext, ModelHandle}; use crate::content::anchor::Anchor; use crate::content::buffer::{ diff --git a/crates/editor/src/multiline.rs b/crates/editor/src/multiline.rs index d5ce67cc..9d6ab4f9 100644 --- a/crates/editor/src/multiline.rs +++ b/crates/editor/src/multiline.rs @@ -42,11 +42,10 @@ use std::fmt; use std::marker::PhantomData; use std::ops::Deref; +use galaxy_core::platform::SessionPlatform; use itertools::Itertools as _; use line_ending::LineEnding; -use galaxy_core::platform::SessionPlatform; - /// A line ending format. This is the compile-time equivalent to [`LineEnding`]. pub trait LineFormat { /// The `LineEnding` corresponding to this format. diff --git a/crates/editor/src/render/element/mod.rs b/crates/editor/src/render/element/mod.rs index 694e714d..51670284 100644 --- a/crates/editor/src/render/element/mod.rs +++ b/crates/editor/src/render/element/mod.rs @@ -4,11 +4,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; use float_cmp::ApproxEq; -use instant::Instant; -use parking_lot::Mutex; -use string_offset::CharOffset; -use temporary_block::RenderableTemporaryBlock; -use vim::vim::VimMode; use galaxy_core::ui::theme::Fill as ThemeFill; use galaxyui_core::color::ColorU; use galaxyui_core::elements::new_scrollable::{NewScrollableElement, ScrollableAxis}; @@ -24,14 +19,11 @@ use galaxyui_core::{ AfterLayoutContext, AppContext, Element, Event, EventContext, LayoutContext, ModelHandle, PaintContext, SizeConstraint, WeakViewHandle, }; -use std::{ - fmt, - sync::{ - Arc, - atomic::{AtomicBool, Ordering}, - }, - time::Duration, -}; +use instant::Instant; +use parking_lot::Mutex; +use string_offset::CharOffset; +use temporary_block::RenderableTemporaryBlock; +use vim::vim::VimMode; use self::empty::Empty; use self::header::RenderableHeader; diff --git a/crates/editor/src/render/element/paint.rs b/crates/editor/src/render/element/paint.rs index cbe5aafe..16b63c45 100644 --- a/crates/editor/src/render/element/paint.rs +++ b/crates/editor/src/render/element/paint.rs @@ -2,14 +2,14 @@ use std::ops::Range; -use string_offset::CharOffset; -use vim::vim::VimMode; use galaxy_core::ui::appearance::DEFAULT_UI_FONT_SIZE; use galaxyui_core::PaintContext; use galaxyui_core::elements::{CornerRadius, Point, Radius}; use galaxyui_core::geometry::rect::RectF; use galaxyui_core::geometry::vector::{Vector2F, vec2f}; use galaxyui_core::text_layout::{Line, PaintStyleOverride, TextFrame}; +use string_offset::CharOffset; +use vim::vim::VimMode; use crate::editor::TextDecoration; use crate::render::layout::line_height; diff --git a/crates/editor/src/render/element/table.rs b/crates/editor/src/render/element/table.rs index 31c6de6a..656940f8 100644 --- a/crates/editor/src/render/element/table.rs +++ b/crates/editor/src/render/element/table.rs @@ -1,6 +1,5 @@ use std::ops::Range; -use string_offset::CharOffset; use galaxyui_core::elements::{ Axis, CornerRadius, DEFAULT_SCROLL_WHEEL_PIXELS_PER_LINE, Radius, ScrollData, ScrollbarAppearance, ScrollbarGeometry, ScrollbarWidth, compute_scrollbar_geometry, @@ -11,6 +10,7 @@ use galaxyui_core::geometry::rect::RectF; use galaxyui_core::geometry::vector::{Vector2F, vec2f}; use galaxyui_core::units::{IntoPixels, Pixels}; use galaxyui_core::{AppContext, ClipBounds, Event, EventContext}; +use string_offset::CharOffset; use super::paint::{CursorData, CursorDisplayType}; use super::{RenderContext, RenderableBlock}; diff --git a/crates/editor/src/render/element/table_tests.rs b/crates/editor/src/render/element/table_tests.rs index 4703bca9..e3cc9895 100644 --- a/crates/editor/src/render/element/table_tests.rs +++ b/crates/editor/src/render/element/table_tests.rs @@ -1,14 +1,14 @@ use std::cell::Cell; use std::sync::Arc; -use pathfinder_color::ColorU; -use string_offset::CharOffset; use galaxyui_core::elements::{Axis, scroll_delta_for_pointer_movement}; use galaxyui_core::fonts::FamilyId; use galaxyui_core::geometry::rect::RectF; use galaxyui_core::geometry::vector::vec2f; use galaxyui_core::text_layout::TextFrame; use galaxyui_core::units::{IntoPixels, Pixels}; +use pathfinder_color::ColorU; +use string_offset::CharOffset; use crate::content::text::{FormattedTable, table_cell_offset_maps}; use crate::render::element::table::{ diff --git a/crates/editor/src/render/element/task_list.rs b/crates/editor/src/render/element/task_list.rs index af959710..27d7da5b 100644 --- a/crates/editor/src/render/element/task_list.rs +++ b/crates/editor/src/render/element/task_list.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxyui_core::elements::{ Align, Border, ConstrainedBox, Container, CornerRadius, Hoverable, Icon, ListIndentLevel, MouseStateHandle, Radius, Rect, @@ -6,6 +5,7 @@ use galaxyui_core::elements::{ use galaxyui_core::geometry::vector::vec2f; use galaxyui_core::platform::Cursor; use galaxyui_core::{AppContext, Element, SizeConstraint, WeakViewHandle}; +use pathfinder_color::ColorU; use super::paint::RenderContext; use super::placeholder::{self, BlockPlaceholder}; diff --git a/crates/editor/src/render/layout.rs b/crates/editor/src/render/layout.rs index 863636e0..2444b8fb 100644 --- a/crates/editor/src/render/layout.rs +++ b/crates/editor/src/render/layout.rs @@ -3,8 +3,6 @@ use std::ops::Range; use std::sync::Arc; -#[cfg(test)] -use markdown_parser::FormattedTextInline; use galaxyui_core::color::ColorU; use galaxyui_core::fonts::TextLayoutSystem; #[cfg(test)] @@ -14,6 +12,8 @@ use galaxyui_core::text_layout::{ }; use galaxyui_core::units::{IntoPixels, Pixels}; use galaxyui_core::{AppContext, LayoutContext}; +#[cfg(test)] +use markdown_parser::FormattedTextInline; use super::model::{BlockSpacing, ParagraphStyles, RenderState, RichTextStyles}; use crate::content::text::{BufferBlockStyle, TextStylesWithMetadata}; diff --git a/crates/editor/src/render/mod_tests.rs b/crates/editor/src/render/mod_tests.rs index 685e0201..9d8fdffa 100644 --- a/crates/editor/src/render/mod_tests.rs +++ b/crates/editor/src/render/mod_tests.rs @@ -1,8 +1,8 @@ //! End-to-end editor tests. -use string_offset::CharOffset; use galaxy_core::features::FeatureFlag; use galaxyui_core::{App, ModelHandle, ReadModel}; +use string_offset::CharOffset; use super::model::test_utils::{TEST_STYLES, init_logging}; use super::model::{BlockItem, RenderEvent, RenderState}; diff --git a/crates/editor/src/render/model/location.rs b/crates/editor/src/render/model/location.rs index 481f0e4d..4ed99f4c 100644 --- a/crates/editor/src/render/model/location.rs +++ b/crates/editor/src/render/model/location.rs @@ -4,7 +4,6 @@ use galaxyui::units::{IntoPixels, Pixels}; use num_traits::SaturatingSub; use string_offset::CharOffset; use sum_tree::SeekBias; -use galaxyui_core::units::{IntoPixels, Pixels}; use super::positioned::{Positioned, PositionedCursor}; use super::{ diff --git a/crates/editor/src/render/model/location_tests.rs b/crates/editor/src/render/model/location_tests.rs index 283be7ca..e12c282d 100644 --- a/crates/editor/src/render/model/location_tests.rs +++ b/crates/editor/src/render/model/location_tests.rs @@ -1,13 +1,13 @@ use std::cell::Cell; use std::sync::Arc; -use pathfinder_color::ColorU; -use string_offset::CharOffset; -use sum_tree::SumTree; use galaxyui_core::assets::asset_cache::AssetSource; use galaxyui_core::fonts::FamilyId; use galaxyui_core::text_layout::{CaretPosition, TextFrame}; use galaxyui_core::units::IntoPixels; +use pathfinder_color::ColorU; +use string_offset::CharOffset; +use sum_tree::SumTree; use crate::content::text::{ BufferBlockStyle, CodeBlockType, FormattedTable, table_cell_offset_maps, diff --git a/crates/editor/src/render/model/mod.rs b/crates/editor/src/render/model/mod.rs index d8175b86..8985db05 100644 --- a/crates/editor/src/render/model/mod.rs +++ b/crates/editor/src/render/model/mod.rs @@ -7,18 +7,6 @@ use std::sync::Arc; use std::{fmt, mem}; use float_cmp::ApproxEq; -use itertools::Itertools; -use markdown_parser::TableAlignment; -use num_traits::SaturatingSub; -use ordered_float::OrderedFloat; -use parking_lot::Mutex; -use rangemap::RangeSet; -use serde::{Deserialize, Serialize}; -use serde_yaml::Mapping; -use string_offset::{CharOffset, impl_offset}; -use sum_tree::{SeekBias, SumTree}; -use vec1::Vec1; -use vim::vim::{MotionType, VimMode}; use galaxy_core::channel::ChannelState; use galaxy_core::ui::Icon; use galaxy_core::ui::theme::Fill as ThemeFill; @@ -38,6 +26,18 @@ use galaxyui_core::text_selection_utils::{ }; use galaxyui_core::units::{IntoPixels, Pixels}; use galaxyui_core::{AppContext, Entity, EntityId, ModelContext, ModelHandle}; +use itertools::Itertools; +use markdown_parser::TableAlignment; +use num_traits::SaturatingSub; +use ordered_float::OrderedFloat; +use parking_lot::Mutex; +use rangemap::RangeSet; +use serde::{Deserialize, Serialize}; +use serde_yaml::Mapping; +use string_offset::{CharOffset, impl_offset}; +use sum_tree::{SeekBias, SumTree}; +use vec1::Vec1; +use vim::vim::{MotionType, VimMode}; use self::location::WrapDirection; pub use self::location::{HitTestOptions, Location}; @@ -2241,10 +2241,7 @@ impl RenderState { } else { 0 }; - loop { - let Some(item) = cursor.positioned_item() else { - break; - }; + while let Some(item) = cursor.positioned_item() { if item.start_line != previous_line { index_within_line = 0; } else { @@ -3190,9 +3187,11 @@ impl RenderState { self.reveal_offset_in_table(*character_offset) } AutoScrollMode::ScrollToActiveSelections { .. } => { - self.selections().iter().fold(false, |changed, selection| { - self.reveal_offset_in_table(selection.head) || changed - }) + let mut changed = false; + for selection in self.selections().iter() { + changed = self.reveal_offset_in_table(selection.head) || changed; + } + changed } } } diff --git a/crates/editor/src/render/model/mod_tests.rs b/crates/editor/src/render/model/mod_tests.rs index eb8eb506..d42264e6 100644 --- a/crates/editor/src/render/model/mod_tests.rs +++ b/crates/editor/src/render/model/mod_tests.rs @@ -1,11 +1,6 @@ use std::cell::Cell; use std::sync::Arc; -use markdown_parser::{FormattedTextStyles, Hyperlink}; -use rangemap::RangeSet; -use string_offset::CharOffset; -use sum_tree::SumTree; -use vec1::{Vec1, vec1}; use galaxyui_core::assets::asset_cache::AssetSource; use galaxyui_core::color::ColorU; use galaxyui_core::elements::ListIndentLevel; @@ -14,6 +9,11 @@ use galaxyui_core::geometry::rect::RectF; use galaxyui_core::geometry::vector::vec2f; use galaxyui_core::text_layout::TextFrame; use galaxyui_core::units::{IntoPixels, Pixels}; +use markdown_parser::{FormattedTextStyles, Hyperlink}; +use rangemap::RangeSet; +use string_offset::CharOffset; +use sum_tree::SumTree; +use vec1::{Vec1, vec1}; use super::debug::Describe; use super::test_utils::{layout_paragraph, layout_paragraphs}; @@ -1433,6 +1433,8 @@ fn test_link_at_offset_uses_cached_cell_links() { mod char_cell { + use string_offset::CharOffset; + use crate::render::model::{ ColumnUnit, LineCount, SoftWrapPoint, char_cell_display_width, char_cell_line_row_starts, char_cell_max_line, char_cell_offset_to_softwrap_point, char_cell_softwrap_point_to_offset, diff --git a/crates/editor/src/render/model/positioned.rs b/crates/editor/src/render/model/positioned.rs index 13a0c323..2ca057cd 100644 --- a/crates/editor/src/render/model/positioned.rs +++ b/crates/editor/src/render/model/positioned.rs @@ -3,11 +3,11 @@ use std::sync::Arc; -use string_offset::CharOffset; -use sum_tree::{Cursor, Dimension}; use galaxyui_core::geometry::vector::Vector2F; use galaxyui_core::text_layout::Line; use galaxyui_core::units::{IntoPixels, Pixels}; +use string_offset::CharOffset; +use sum_tree::{Cursor, Dimension}; use super::{ BlockItem, BlockSpacing, HorizontalRuleConfig, ImageBlockConfig, LaidOutEmbeddedItem, diff --git a/crates/editor/src/render/model/test_utils.rs b/crates/editor/src/render/model/test_utils.rs index 147ab4a2..8e87f984 100644 --- a/crates/editor/src/render/model/test_utils.rs +++ b/crates/editor/src/render/model/test_utils.rs @@ -3,15 +3,15 @@ use std::mem; use std::sync::Arc; -use ordered_float::OrderedFloat; -use parking_lot::Once; -use vec1::{Vec1, vec1}; use galaxyui_core::color::ColorU; use galaxyui_core::elements::{Border, Fill, ListIndentLevel}; use galaxyui_core::fonts::{FamilyId, Weight}; use galaxyui_core::geometry::vector::vec2f; use galaxyui_core::text_layout::{CaretPosition, Glyph, Line, Run, TextFrame}; use galaxyui_core::units::{IntoPixels, Pixels}; +use ordered_float::OrderedFloat; +use parking_lot::Once; +use vec1::{Vec1, vec1}; use super::{ BlockItem, BrokenLinkStyle, CheckBoxStyle, DEFAULT_BLOCK_SPACINGS, HorizontalRuleStyle, @@ -310,12 +310,12 @@ pub fn layout(text: &str, styles: &RichTextStyles, max_width: impl IntoPixels) - /// Initialize logging for tests. This should be called at the start of any test that needs logging. pub fn init_logging() { - // If multiple tests run in the same process, we should still only set up logging once. static INIT: Once = Once::new(); INIT.call_once(|| { - env_logger::builder() + let _ = env_logger::builder() .parse_filters("galaxy_editor=trace") .is_test(true) - .init(); + .try_init(); }); } + diff --git a/crates/editor/src/render/model/viewport.rs b/crates/editor/src/render/model/viewport.rs index def7c965..3895902f 100644 --- a/crates/editor/src/render/model/viewport.rs +++ b/crates/editor/src/render/model/viewport.rs @@ -1,10 +1,10 @@ use float_cmp::ApproxEq; -use string_offset::CharOffset; -use sum_tree::{SeekBias, SumTree}; use galaxyui_core::SizeConstraint; use galaxyui_core::geometry::rect::RectF; use galaxyui_core::geometry::vector::{Vector2F, vec2f}; use galaxyui_core::units::{IntoPixels, Pixels}; +use string_offset::CharOffset; +use sum_tree::{SeekBias, SumTree}; use super::positioned::PositionedCursor; use super::{ diff --git a/crates/editor/src/render/model/viewport_tests.rs b/crates/editor/src/render/model/viewport_tests.rs index 157e8d89..fd69dc87 100644 --- a/crates/editor/src/render/model/viewport_tests.rs +++ b/crates/editor/src/render/model/viewport_tests.rs @@ -1,8 +1,8 @@ -use itertools::Itertools; -use sum_tree::SumTree; use galaxyui_core::SizeConstraint; use galaxyui_core::geometry::vector::vec2f; use galaxyui_core::units::{IntoPixels, Pixels}; +use itertools::Itertools; +use sum_tree::SumTree; use super::ViewportState; use crate::render::model::RenderState; diff --git a/crates/editor/src/search.rs b/crates/editor/src/search.rs index f0fcdbd9..4dc9e3c5 100644 --- a/crates/editor/src/search.rs +++ b/crates/editor/src/search.rs @@ -1,13 +1,12 @@ use std::ops::Range; use galaxy_core::ui::theme::Fill; -use galaxyui::{Entity, ModelContext, ModelHandle, r#async::SpawnedFutureHandle}; +use galaxyui::r#async::SpawnedFutureHandle; +use galaxyui::{Entity, ModelContext, ModelHandle}; use itertools::Itertools; use lazy_static::lazy_static; use pathfinder_color::ColorU; use string_offset::CharOffset; -use galaxyui_core::r#async::SpawnedFutureHandle; -use galaxyui_core::{Entity, ModelContext, ModelHandle}; use crate::content::anchor::Anchor; use crate::content::buffer::{Buffer, BufferEvent}; diff --git a/crates/editor/src/selection.rs b/crates/editor/src/selection.rs index 4a409294..d28f9096 100644 --- a/crates/editor/src/selection.rs +++ b/crates/editor/src/selection.rs @@ -1,12 +1,12 @@ use std::ops::Range; -use num_traits::SaturatingSub; -use string_offset::CharOffset; -use vec1::Vec1; use galaxyui_core::text::TextBuffer; use galaxyui_core::text::point::Point; use galaxyui_core::text::word_boundaries::WordBoundariesPolicy; use galaxyui_core::{AppContext, Entity, ModelAsRef, ModelContext, ModelHandle}; +use num_traits::SaturatingSub; +use string_offset::CharOffset; +use vec1::Vec1; use crate::content::buffer::{ AutoScrollBehavior, Buffer, BufferEvent, BufferSelectAction, SelectionOffsets, diff --git a/crates/editor/src/selection_tests.rs b/crates/editor/src/selection_tests.rs index 707853b1..756f228f 100644 --- a/crates/editor/src/selection_tests.rs +++ b/crates/editor/src/selection_tests.rs @@ -1,15 +1,14 @@ use std::sync::Arc; use galaxy_core::features::FeatureFlag; -use galaxyui::{App, ModelAsRef, units::IntoPixels}; +use galaxyui::units::IntoPixels; +use galaxyui::{App, ModelAsRef}; +use galaxyui_core::assets::asset_cache::AssetSource; +use galaxyui_core::text::word_boundaries::WordBoundariesPolicy; use serde_yaml::Value; use string_offset::CharOffset; use sum_tree::SumTree; use vec1::vec1; -use galaxyui_core::assets::asset_cache::AssetSource; -use galaxyui_core::text::word_boundaries::WordBoundariesPolicy; -use galaxyui_core::units::IntoPixels; -use galaxyui_core::{App, ModelAsRef}; use super::{SelectionModel, TextDirection, TextUnit}; use crate::content::buffer::tests::TestEmbeddedItem; diff --git a/crates/galaxy_cli/src/lib.rs b/crates/galaxy_cli/src/lib.rs index 071d819a..a735a01f 100644 --- a/crates/galaxy_cli/src/lib.rs +++ b/crates/galaxy_cli/src/lib.rs @@ -4,10 +4,9 @@ use std::path::Path; use std::{env, fmt}; use clap::{CommandFactory, Parser, Subcommand, ValueEnum}; -use url::Url; - use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; +use url::Url; use crate::agent::OutputFormat; diff --git a/crates/galaxy_cli/src/local_control/commands.rs b/crates/galaxy_cli/src/local_control/commands.rs index fcdd3baf..72731d99 100644 --- a/crates/galaxy_cli/src/local_control/commands.rs +++ b/crates/galaxy_cli/src/local_control/commands.rs @@ -1,4 +1,5 @@ //! Implementations for user-facing `warpctrl` command groups. +use galaxy_core::channel::ChannelState; use local_control::discovery::InstanceRecord; use local_control::protocol::{ Action, ActionKind, ActionNameParams, BindingNameParams, BooleanValueParams, ColorValueParams, @@ -9,7 +10,6 @@ use local_control::protocol::{ }; use local_control::selection::select_instance; use serde::Serialize; -use galaxy_core::channel::ChannelState; use crate::agent::OutputFormat; use crate::local_control::output::{write_json, write_json_line}; diff --git a/crates/galaxy_completer/Cargo.toml b/crates/galaxy_completer/Cargo.toml index 15dff673..26179748 100644 --- a/crates/galaxy_completer/Cargo.toml +++ b/crates/galaxy_completer/Cargo.toml @@ -34,6 +34,7 @@ galaxy_cli.workspace = true galaxy_core.workspace = true galaxy_js = { workspace = true, optional = true } galaxyui_core.workspace = true +galaxyui.workspace = true galaxy_util.workspace = true typed-path.workspace = true diff --git a/crates/galaxy_completer/src/completer/context/mod.rs b/crates/galaxy_completer/src/completer/context/mod.rs index 3b8257ed..bb393c5e 100644 --- a/crates/galaxy_completer/src/completer/context/mod.rs +++ b/crates/galaxy_completer/src/completer/context/mod.rs @@ -15,7 +15,6 @@ use galaxy_util::path::{EscapeChar, ShellFamily}; use galaxyui::platform::OperatingSystem; use smol_str::SmolStr; use typed_path::{TypedPath, TypedPathBuf}; -use galaxyui_core::platform::OperatingSystem; use super::engine::EngineDirEntry; use crate::completer::TopLevelCommandCaseSensitivity; diff --git a/crates/galaxy_completer/src/completer/context/v2.rs b/crates/galaxy_completer/src/completer/context/v2.rs index aafbb8bc..d9ebfac3 100644 --- a/crates/galaxy_completer/src/completer/context/v2.rs +++ b/crates/galaxy_completer/src/completer/context/v2.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; +use galaxy_js::{JsFunctionId, SerializedJsValue, TypedJsFunctionRef}; use serde::de::DeserializeOwned; use serde::Serialize; -use galaxy_js::{JsFunctionId, SerializedJsValue, TypedJsFunctionRef}; #[derive(thiserror::Error, Debug)] pub enum JsExecutionError { diff --git a/crates/galaxy_completer/src/completer/describe.rs b/crates/galaxy_completer/src/completer/describe.rs index 8ac34a4f..352843f7 100644 --- a/crates/galaxy_completer/src/completer/describe.rs +++ b/crates/galaxy_completer/src/completer/describe.rs @@ -1,7 +1,6 @@ use galaxyui::platform::OperatingSystem; use itertools::Itertools; use string_offset::ByteOffset; -use galaxyui_core::platform::OperatingSystem; use super::context::CompletionContext; use super::suggest::{suggestions, CompleterOptions, CompletionsFallbackStrategy, SuggestionType}; diff --git a/crates/galaxy_completer/src/completer/engine/argument/legacy.rs b/crates/galaxy_completer/src/completer/engine/argument/legacy.rs index b54147eb..ab81aa02 100644 --- a/crates/galaxy_completer/src/completer/engine/argument/legacy.rs +++ b/crates/galaxy_completer/src/completer/engine/argument/legacy.rs @@ -250,28 +250,26 @@ async fn suggestions_for_parse_error( ParseErrorReason::ArgumentError { command: _, error: UnexpectedArgument(arg), - } => { - if arg.span.end() == line.len() { - // The unexpected argument could be a prefix for a subcommand. - let prefix = arg.item.as_str(); - let results = (signature.subcommands().iter().filter_map(|subcmd| { - options - .match_strategy - .get_match_type(prefix, subcmd.name()) - .map(|match_type| { - let suggestion = Suggestion::with_same_display_and_replacement( - subcmd.name.clone(), - subcmd.description.as_ref().cloned(), - SuggestionType::Subcommand, - subcmd.priority.into(), - ); - MatchedSuggestion::new(suggestion, match_type) - }) - })) - .sorted_by(MatchedSuggestion::cmp_by_display) - .collect(); - return (results, false); - } + } if arg.span.end() == line.len() => { + // The unexpected argument could be a prefix for a subcommand. + let prefix = arg.item.as_str(); + let results = (signature.subcommands().iter().filter_map(|subcmd| { + options + .match_strategy + .get_match_type(prefix, subcmd.name()) + .map(|match_type| { + let suggestion = Suggestion::with_same_display_and_replacement( + subcmd.name.clone(), + subcmd.description.as_ref().cloned(), + SuggestionType::Subcommand, + subcmd.priority.into(), + ); + MatchedSuggestion::new(suggestion, match_type) + }) + })) + .sorted_by(MatchedSuggestion::cmp_by_display) + .collect(); + return (results, false); } _ => {} } diff --git a/crates/galaxy_completer/src/completer/engine/command.rs b/crates/galaxy_completer/src/completer/engine/command.rs index 8666c25b..8d3715f9 100644 --- a/crates/galaxy_completer/src/completer/engine/command.rs +++ b/crates/galaxy_completer/src/completer/engine/command.rs @@ -55,8 +55,7 @@ pub async fn complete( .into_iter() .chain( sorted_directories_relative_to(parsed_token, matcher, path_completion_context) - .await - .into_iter(), + .await, ) .collect(); } diff --git a/crates/galaxy_completer/src/completer/engine/path.rs b/crates/galaxy_completer/src/completer/engine/path.rs index 280a75d5..1ed3a1c0 100644 --- a/crates/galaxy_completer/src/completer/engine/path.rs +++ b/crates/galaxy_completer/src/completer/engine/path.rs @@ -4,12 +4,12 @@ use std::fs::DirEntry; use std::sync::Arc; use async_trait::async_trait; +use galaxy_util::path::{ShellFamily, HOME_DIR_ENV_VAR_PREFIX}; use itertools::{iproduct, Itertools}; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use typed_path::{TypedPath, TypedPathBuf}; use warp_command_signatures::{IconType, PathSuggestionType}; -use galaxy_util::path::{ShellFamily, HOME_DIR_ENV_VAR_PREFIX}; use crate::completer::context::{PathCompletionContext, PathSeparators}; use crate::completer::matchers::MatchStrategy; diff --git a/crates/galaxy_completer/src/completer/suggest/alias_tests.rs b/crates/galaxy_completer/src/completer/suggest/alias_tests.rs index 0f67028f..a6dcd6c2 100644 --- a/crates/galaxy_completer/src/completer/suggest/alias_tests.rs +++ b/crates/galaxy_completer/src/completer/suggest/alias_tests.rs @@ -203,7 +203,8 @@ pub fn test_expand_command_aliases_should_not_expand_if_no_space_after_alias() { assert!(result.signature_for_completions.is_none()); // The test signature has an alias function which expands subcommand "twelve" to "one", but there's no trailing space so we shouldn't expand. - let result = galaxyui_core::r#async::block_on(expand_command_aliases("test twelve", false, &ctx)); + let result = + galaxyui_core::r#async::block_on(expand_command_aliases("test twelve", false, &ctx)); assert_eq!(result.expanded_command_line, "test twelve"); assert_eq!(result.tokens_from_command, vec!["test", "twelve"]); // "twelve" isn't a valid subcommand, so we should use the "test" signature. @@ -218,8 +219,11 @@ pub fn test_expand_command_aliases_should_not_expand_if_no_space_after_alias() { ); // We have a top-level aliasForTest which expands to test. But the test signature does not expand "twelve" to "one" because there's no trailing space. - let result = - galaxyui_core::r#async::block_on(expand_command_aliases("aliasForTest twelve", false, &ctx)); + let result = galaxyui_core::r#async::block_on(expand_command_aliases( + "aliasForTest twelve", + false, + &ctx, + )); assert_eq!(result.expanded_command_line, "test twelve"); assert_eq!(result.tokens_from_command, vec!["test", "twelve"]); // "twelve" isn't a valid subcommand, so we should use the "test" signature. diff --git a/crates/galaxy_completer/src/completer/suggest/mod.rs b/crates/galaxy_completer/src/completer/suggest/mod.rs index b491f6ac..450c3b59 100644 --- a/crates/galaxy_completer/src/completer/suggest/mod.rs +++ b/crates/galaxy_completer/src/completer/suggest/mod.rs @@ -10,12 +10,12 @@ use std::hash::{Hash, Hasher}; use alias::{expand_command_aliases, AliasExpansionResult}; use async_recursion::async_recursion; +use galaxy_core::ui::theme::AnsiColorIdentifier; use imp::*; use itertools::Itertools; pub use priority::Priority; use smol_str::SmolStr; use warp_command_signatures::IconType; -use galaxy_core::ui::theme::AnsiColorIdentifier; use super::coalesce::coalesce_completion_results; use super::context::CompletionContext; diff --git a/crates/galaxy_completer/src/completer/suggest/priority/priority_tests.rs b/crates/galaxy_completer/src/completer/suggest/priority/priority_tests.rs index 51bdcb92..b168e686 100644 --- a/crates/galaxy_completer/src/completer/suggest/priority/priority_tests.rs +++ b/crates/galaxy_completer/src/completer/suggest/priority/priority_tests.rs @@ -1,3 +1,5 @@ +use warp_command_signatures::{Importance, Order, Priority as OldPriority}; + use super::{Priority, MAX_PRIORITY, MIN_PRIORITY}; #[test] @@ -41,7 +43,6 @@ fn test_priority_comparison() { /// `warp_command_signatures`. #[test] fn test_new_to_old_priority() { - use warp_command_signatures::{Importance, Order, Priority as OldPriority}; assert_eq!( OldPriority::from(Priority::new(MIN_PRIORITY)), OldPriority::Global(Importance::Less(Order(1))), @@ -82,7 +83,6 @@ fn test_new_to_old_priority() { /// `warp_command_signatures` to the new Priority. #[test] fn test_old_to_new_priority() { - assert_eq!( Priority::from(OldPriority::Global(Importance::Less(Order(1)))), Priority::new(MIN_PRIORITY) diff --git a/crates/galaxy_completer/src/parsers/simple/mod.rs b/crates/galaxy_completer/src/parsers/simple/mod.rs index 8f0c8ab2..15ac1890 100644 --- a/crates/galaxy_completer/src/parsers/simple/mod.rs +++ b/crates/galaxy_completer/src/parsers/simple/mod.rs @@ -6,10 +6,10 @@ mod lexer; mod parser; mod token; +use galaxy_util::path::EscapeChar; use lexer::Lexer; use parser::Parser; use string_offset::ByteOffset; -use galaxy_util::path::EscapeChar; use crate::parsers::LiteCommand; diff --git a/crates/galaxy_completer/src/parsers/simple/parser.rs b/crates/galaxy_completer/src/parsers/simple/parser.rs index 26834fad..d47c10e7 100644 --- a/crates/galaxy_completer/src/parsers/simple/parser.rs +++ b/crates/galaxy_completer/src/parsers/simple/parser.rs @@ -378,7 +378,7 @@ fn is_valid_command_separator(token: &Token) -> bool { /// /// This includes all of the separator tokens as well as the grouping tokens fn is_command_terminator(token: &Token) -> bool { - + use Token::*; is_valid_command_separator(token) || matches!(token, OpenParen | CloseParen | OpenCurly | CloseCurly) } diff --git a/crates/galaxy_completer/src/signatures/v2/js.rs b/crates/galaxy_completer/src/signatures/v2/js.rs index 16da2161..bc7a922b 100644 --- a/crates/galaxy_completer/src/signatures/v2/js.rs +++ b/crates/galaxy_completer/src/signatures/v2/js.rs @@ -2,11 +2,11 @@ //! `galaxy_completer::signatures::CommandSignature`s, as well as `IntoWarpJs` implementations for //! Rust structs that may be passed to JS functions defined on the Command Signature (e.g. //! `GeneratorCompletionContext`). -use rquickjs::{FromJs, Function, Object, Value}; use galaxy_js::util::{ get_one_or_more_optional, get_one_or_more_required, get_optional, get_required, }; use galaxy_js::{FromWarpJs, IntoWarpJs, JsFunctionRegistry}; +use rquickjs::{FromJs, Function, Object, Value}; use super::{ Argument, ArgumentValue, Command, CommandSignature, GeneratorCompletionContext, GeneratorFn, diff --git a/crates/galaxy_core/src/execution_mode.rs b/crates/galaxy_core/src/execution_mode.rs index 8de2217b..20c308c5 100644 --- a/crates/galaxy_core/src/execution_mode.rs +++ b/crates/galaxy_core/src/execution_mode.rs @@ -1,6 +1,6 @@ -use galaxyui_core::{Entity, ModelContext, SingletonEntity}; use std::sync::OnceLock; +use galaxyui_core::{Entity, ModelContext, SingletonEntity}; // Global execution mode, for logic that runs outside the UI framework. static GLOBAL_EXECUTION_MODE: OnceLock = OnceLock::new(); diff --git a/crates/galaxy_core/src/lib.rs b/crates/galaxy_core/src/lib.rs index 8f841ffb..22e37bcd 100644 --- a/crates/galaxy_core/src/lib.rs +++ b/crates/galaxy_core/src/lib.rs @@ -27,8 +27,8 @@ pub mod ui; pub mod user_preferences; pub use app_id::AppId; -pub use session_id::SessionId; -pub use warp_util::host_id::HostId; // Re-export galaxyui_core so that it can be referenced safely from the // telemetry macros. pub use galaxyui_core; +pub use session_id::SessionId; +pub use warp_util::host_id::HostId; diff --git a/crates/galaxy_core/src/operating_system_info.rs b/crates/galaxy_core/src/operating_system_info.rs index 198a9fe1..a9b09d18 100644 --- a/crates/galaxy_core/src/operating_system_info.rs +++ b/crates/galaxy_core/src/operating_system_info.rs @@ -3,12 +3,12 @@ use std::fmt::{Display, Formatter}; use std::sync::OnceLock; -use serde::Serialize; -use serde_with::SerializeDisplay; #[cfg(target_family = "wasm")] use galaxyui_core::platform::wasm; #[cfg(target_family = "wasm")] use galaxyui_core::platform::OperatingSystem; +use serde::Serialize; +use serde_with::SerializeDisplay; static OS_INFO: OnceLock> = OnceLock::new(); diff --git a/crates/galaxy_core/src/semantic_selection/mod.rs b/crates/galaxy_core/src/semantic_selection/mod.rs index 7482b252..60548d3d 100644 --- a/crates/galaxy_core/src/semantic_selection/mod.rs +++ b/crates/galaxy_core/src/semantic_selection/mod.rs @@ -2,15 +2,13 @@ use std::collections::HashSet; use std::ops::Range; use galaxyui_core::elements::SmartSelectFn; -use lazy_static::lazy_static; -use regex::Regex; -use settings::ChangeEventReason; -use settings::macros::define_settings_group; -use settings::{Setting, SupportedPlatforms, SyncToCloud}; -use settings_value::SettingsValue; -use string_offset::ByteOffset; use galaxyui_core::text::word_boundaries::WordBoundariesPolicy; use galaxyui_core::text::words::{is_default_word_boundary, DEFAULT_WORD_BOUNDARY_CHARS}; +use lazy_static::lazy_static; +use regex::Regex; +use settings::macros::define_settings_group; +use settings::{Setting, SupportedPlatforms, SyncToCloud}; +use string_offset::ByteOffset; /// Upper limit for how many characters in either direction we'll search for patterns. Need to /// limit this to avoid running regex on absurdly long words diff --git a/crates/galaxy_core/src/sync_queue.rs b/crates/galaxy_core/src/sync_queue.rs index c6c68997..7369e2f8 100644 --- a/crates/galaxy_core/src/sync_queue.rs +++ b/crates/galaxy_core/src/sync_queue.rs @@ -11,9 +11,9 @@ use futures::channel::oneshot::{self, Receiver, Sender}; use futures::future::{AbortHandle, Abortable}; use futures::StreamExt; use galaxyui_core::r#async::executor::Background; -use instant::Instant; use galaxyui_core::r#async::Timer; use galaxyui_core::{Entity, RetryOption, SingletonEntity}; +use instant::Instant; const DEFAULT_BUFFER_SIZE: usize = 1024; const DEFAULT_SYNC_RETRY_STRATEGY: RetryOption = RetryOption::exponential( diff --git a/crates/galaxy_core/src/telemetry.rs b/crates/galaxy_core/src/telemetry.rs index 95f4ee60..21731a3c 100644 --- a/crates/galaxy_core/src/telemetry.rs +++ b/crates/galaxy_core/src/telemetry.rs @@ -1,10 +1,9 @@ use galaxyui_core::{AppContext, Entity, SingletonEntity}; -use serde_json::Value; -use strum::IntoEnumIterator; - #[doc(hidden)] #[cfg(not(target_family = "wasm"))] pub use inventory::submit; +use serde_json::Value; +use strum::IntoEnumIterator; use crate::features::FeatureFlag; @@ -123,3 +122,34 @@ impl Entity for TelemetryContextModel { } impl SingletonEntity for TelemetryContextModel {} + +#[cfg(any(test, feature = "test-util"))] +pub mod testing { + use galaxyui_core::AppContext; + + use crate::telemetry::{TelemetryContextModel, TelemetryContextProvider}; + + pub struct MockTelemetryContextProvider { + anonymous_id: String, + } + + impl MockTelemetryContextProvider { + pub fn register(ctx: &mut AppContext) { + ctx.add_singleton_model(|_ctx| { + let anonymous_id = "mock-anonymous-id".to_string(); + let provider: TelemetryContextModel = Box::new(Self { anonymous_id }); + provider + }); + } + } + + impl TelemetryContextProvider for MockTelemetryContextProvider { + fn user_id(&self, _ctx: &AppContext) -> Option { + None + } + + fn anonymous_id(&self, _ctx: &AppContext) -> String { + self.anonymous_id.clone() + } + } +} diff --git a/crates/galaxy_core/src/ui/color/hex_color.rs b/crates/galaxy_core/src/ui/color/hex_color.rs index 772e4d4d..db7e9ea3 100644 --- a/crates/galaxy_core/src/ui/color/hex_color.rs +++ b/crates/galaxy_core/src/ui/color/hex_color.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use std::fmt; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use galaxyui_core::color::ColorU; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use super::OPAQUE; diff --git a/crates/galaxy_core/src/ui/external_product_icon.rs b/crates/galaxy_core/src/ui/external_product_icon.rs index 4e905075..d24fe8b6 100644 --- a/crates/galaxy_core/src/ui/external_product_icon.rs +++ b/crates/galaxy_core/src/ui/external_product_icon.rs @@ -40,4 +40,8 @@ impl ExternalProductIcon { let path = self.get_path(); WarpUiIcon::new(path, color.into_solid()) } + + pub fn to_warpui_icon(&self, color: Fill) -> WarpUiIcon { + self.to_galaxyui_icon(color) + } } diff --git a/crates/galaxy_core/src/ui/icons.rs b/crates/galaxy_core/src/ui/icons.rs index f8a104a3..8e927ec1 100644 --- a/crates/galaxy_core/src/ui/icons.rs +++ b/crates/galaxy_core/src/ui/icons.rs @@ -678,6 +678,10 @@ impl Icon { WarpUiIcon::new(self.into(), color.into_solid()) } + pub fn to_warpui_icon(self, color: Fill) -> WarpUiIcon { + self.to_galaxyui_icon(color) + } + pub fn icon_for_key(key: &str) -> Option { match key { "⏎" => Some(Self::CornerDownLeft.to_galaxyui_icon(Fill::black())), diff --git a/crates/galaxy_core/src/ui/theme/color.rs b/crates/galaxy_core/src/ui/theme/color.rs index e8f59b8f..b4bf6811 100644 --- a/crates/galaxy_core/src/ui/theme/color.rs +++ b/crates/galaxy_core/src/ui/theme/color.rs @@ -3,15 +3,15 @@ //! These colors can be further understood here: //! https://docs.google.com/document/d/1YMovEoXsPRziPk99a4i9LZNEKGm_rjEyzhcHsFkT3ac/edit. +use galaxyui_core::color::ColorU; use getset::Getters; use serde::{Deserialize, Serialize}; -use galaxyui_core::color::ColorU; use self::internal_colors::{ accent_overlay_2, fg_overlay_1, fg_overlay_2, fg_overlay_3, neutral_1, neutral_2, neutral_3, neutral_4, }; -use super::{AnsiColor, AnsiColorIdentifier, Fill, TerminalColors, GalaxyTheme}; +use super::{AnsiColor, AnsiColorIdentifier, Fill, GalaxyTheme, TerminalColors}; use crate::ui::color::blend::Blend; use crate::ui::color::contrast::{pick_best_foreground_color, MinimumAllowedContrast}; use crate::ui::color::Opacity; diff --git a/crates/galaxy_core/src/ui/theme/mod.rs b/crates/galaxy_core/src/ui/theme/mod.rs index 467ce085..8e298a76 100644 --- a/crates/galaxy_core/src/ui/theme/mod.rs +++ b/crates/galaxy_core/src/ui/theme/mod.rs @@ -676,6 +676,8 @@ pub fn mock_terminal_colors() -> TerminalColors { ) } +pub type WarpTheme = GalaxyTheme; + #[cfg(test)] #[path = "theme_tests.rs"] mod tests; diff --git a/crates/galaxy_features/src/lib.rs b/crates/galaxy_features/src/lib.rs index 51669b46..69315d87 100644 --- a/crates/galaxy_features/src/lib.rs +++ b/crates/galaxy_features/src/lib.rs @@ -905,6 +905,11 @@ pub enum FeatureFlag { /// Enables the `--runner` flag on `run-cloud`, which overrides an agent's /// compute (docker image, instance shape, setup commands) by runner ID. CloudRunners, + + LspCodeActions, + LspCompletion, + LspRename, + LspSignatureHelp, } static FLAG_STATES: [AtomicBool; cardinality::()] = diff --git a/crates/galaxy_files/src/lib.rs b/crates/galaxy_files/src/lib.rs index a15b2919..bb7ee787 100644 --- a/crates/galaxy_files/src/lib.rs +++ b/crates/galaxy_files/src/lib.rs @@ -14,17 +14,17 @@ use std::time::{Duration, SystemTime}; use async_channel::Sender; use futures::io::{AsyncBufReadExt, BufReader}; use futures::StreamExt; -use notify_debouncer_full::notify::{RecursiveMode, WatchFilter}; -use remote_server::manager::RemoteServerManager; -use repo_metadata::repositories::DetectedRepositories; -use repo_metadata::repository::{RepositorySubscriber, SubscriberId}; -use repo_metadata::{CanonicalizedPath, Repository, RepositoryUpdate}; use galaxy_core::HostId; use galaxy_util::content_version::ContentVersion; use galaxy_util::file::{FileId, FileLoadError, FileSaveError}; use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::r#async::SpawnedFutureHandle; use galaxyui_core::{Entity, ModelContext, ModelHandle, SingletonEntity}; +use notify_debouncer_full::notify::{RecursiveMode, WatchFilter}; +use remote_server::manager::RemoteServerManager; +use repo_metadata::repositories::DetectedRepositories; +use repo_metadata::repository::{RepositorySubscriber, SubscriberId}; +use repo_metadata::{CanonicalizedPath, Repository, RepositoryUpdate}; use watcher::{BulkFilesystemWatcher, BulkFilesystemWatcherEvent}; pub mod text_file_reader; diff --git a/crates/galaxy_logging/src/native.rs b/crates/galaxy_logging/src/native.rs index 42cc9c28..135ff393 100644 --- a/crates/galaxy_logging/src/native.rs +++ b/crates/galaxy_logging/src/native.rs @@ -6,9 +6,9 @@ use std::sync::OnceLock; use anyhow::Result; use chrono::Local; +use galaxy_core::channel::ChannelState; use galaxy_core::features::FeatureFlag; use log::LevelFilter; -use galaxy_core::channel::ChannelState; use zip::write::SimpleFileOptions; use zip::{CompressionMethod, ZipWriter}; diff --git a/crates/galaxy_server_client/src/auth/mod.rs b/crates/galaxy_server_client/src/auth/mod.rs index 7289db55..51057fa5 100644 --- a/crates/galaxy_server_client/src/auth/mod.rs +++ b/crates/galaxy_server_client/src/auth/mod.rs @@ -7,36 +7,38 @@ use anyhow::{Context as _, Result, anyhow}; use async_trait::async_trait; use cynic::{MutationBuilder, QueryBuilder}; use firebase::FirebaseError; +use galaxy_core::errors::{AnyhowErrorExt, ErrorExt, register_error}; +use galaxy_graphql::client::Operation; +use galaxy_graphql::mutations::create_anonymous_user::{ + AnonymousUserType, CreateAnonymousUser, CreateAnonymousUserResult, CreateAnonymousUserVariables, +}; +use galaxy_graphql::mutations::expire_api_key::{ + ExpireApiKey, ExpireApiKeyResult, ExpireApiKeyVariables, +}; +use galaxy_graphql::mutations::generate_api_key::{ + GenerateApiKey, GenerateApiKeyInput, GenerateApiKeyResult, GenerateApiKeyVariables, +}; +use galaxy_graphql::mutations::mint_custom_token::{ + MintCustomTokenResult, MintCustomTokenVariables, +}; +use galaxy_graphql::mutations::set_user_is_onboarded::{ + SetUserIsOnboarded, SetUserIsOnboardedResult, SetUserIsOnboardedVariables, +}; +use galaxy_graphql::mutations::update_user_settings::{ + UpdateUserSettings, UpdateUserSettingsInput, UpdateUserSettingsResult, + UpdateUserSettingsVariables, +}; +use galaxy_graphql::queries::api_keys::{ + ApiKeyProperties, ApiKeyPropertiesResult, ApiKeys, ApiKeysVariables, +}; +use galaxy_graphql::queries::get_user::{GetUser, GetUserVariables, UserOutput as GqlUserOutput}; +use galaxy_graphql::queries::get_user_settings::{GetUserSettings, GetUserSettingsVariables}; use instant::Duration; #[cfg(any(test, feature = "test-util"))] use mockall::automock; pub use session::*; use thiserror::Error; pub use user_uid::{TEST_USER_EMAIL, TEST_USER_UID, UserUid}; -use galaxy_core::errors::{AnyhowErrorExt, ErrorExt, register_error}; -use warp_graphql::client::Operation; -use warp_graphql::mutations::create_anonymous_user::{ - AnonymousUserType, CreateAnonymousUser, CreateAnonymousUserResult, CreateAnonymousUserVariables, -}; -use warp_graphql::mutations::expire_api_key::{ - ExpireApiKey, ExpireApiKeyResult, ExpireApiKeyVariables, -}; -use warp_graphql::mutations::generate_api_key::{ - GenerateApiKey, GenerateApiKeyInput, GenerateApiKeyResult, GenerateApiKeyVariables, -}; -use warp_graphql::mutations::mint_custom_token::{MintCustomTokenResult, MintCustomTokenVariables}; -use warp_graphql::mutations::set_user_is_onboarded::{ - SetUserIsOnboarded, SetUserIsOnboardedResult, SetUserIsOnboardedVariables, -}; -use warp_graphql::mutations::update_user_settings::{ - UpdateUserSettings, UpdateUserSettingsInput, UpdateUserSettingsResult, - UpdateUserSettingsVariables, -}; -use warp_graphql::queries::api_keys::{ - ApiKeyProperties, ApiKeyPropertiesResult, ApiKeys, ApiKeysVariables, -}; -use warp_graphql::queries::get_user::{GetUser, GetUserVariables, UserOutput as GqlUserOutput}; -use warp_graphql::queries::get_user_settings::{GetUserSettings, GetUserSettingsVariables}; use warp_server_auth::credentials::{AuthToken, Credentials, FirebaseToken, LoginToken}; pub use warp_server_auth::user_uid; @@ -158,7 +160,7 @@ pub trait AuthClient: Send + Sync { name: String, team_id: Option, agent_uid: Option, - expires_at: Option, + expires_at: Option, ) -> Result; async fn expire_api_key(&self, key_uid: &ApiKeyUid) -> Result; @@ -189,7 +191,7 @@ impl AuthClientImpl { ) -> Result<()> { let operation = UpdateUserSettings::build(UpdateUserSettingsVariables { input, - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let result = send_graphql_request(&self.base_client, operation, None) .await? @@ -204,7 +206,7 @@ impl AuthClientImpl { match result { UpdateUserSettingsResult::UpdateUserSettingsOutput(_) => Ok(()), UpdateUserSettingsResult::UserFacingError(error) => Err(anyhow!( - warp_graphql::client::get_user_facing_error_message(error) + galaxy_graphql::client::get_user_facing_error_message(error) )), UpdateUserSettingsResult::Unknown => Err(anyhow!(unknown_error_message)), } @@ -220,12 +222,12 @@ impl AuthClient for AuthClientImpl { anonymous_user_type: AnonymousUserType, ) -> Result { let operation = CreateAnonymousUser::build(CreateAnonymousUserVariables { - input: warp_graphql::mutations::create_anonymous_user::CreateAnonymousUserInput { + input: galaxy_graphql::mutations::create_anonymous_user::CreateAnonymousUserInput { anonymous_user_type, - expiration_type: warp_graphql::mutations::create_anonymous_user::AnonymousUserExpirationType::NoExpiration, + expiration_type: galaxy_graphql::mutations::create_anonymous_user::AnonymousUserExpirationType::NoExpiration, referral_code, }, - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let response = operation .send_request( @@ -271,9 +273,9 @@ impl AuthClient for AuthClientImpl { } async fn fetch_new_custom_token(&self) -> Result { - let operation = warp_graphql::mutations::mint_custom_token::MintCustomToken::build( + let operation = galaxy_graphql::mutations::mint_custom_token::MintCustomToken::build( MintCustomTokenVariables { - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }, ); let response = send_graphql_request(&self.base_client, operation, None).await?; @@ -288,7 +290,7 @@ impl AuthClient for AuthClientImpl { Ok(MintCustomTokenResult::MintCustomTokenOutput(output)) => Ok(output.custom_token), Ok(MintCustomTokenResult::UserFacingError(error)) => { Err(MintCustomTokenError::UserFacingError( - warp_graphql::client::get_user_facing_error_message(error), + galaxy_graphql::client::get_user_facing_error_message(error), )) } Ok(MintCustomTokenResult::Unknown) | Err(_) => Err(MintCustomTokenError::Unknown), @@ -300,7 +302,7 @@ impl AuthClient for AuthClientImpl { auth_token: Option<&'a str>, ) -> Result { let operation = GetUser::build(GetUserVariables { - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let mut options = self .base_client @@ -315,8 +317,10 @@ impl AuthClient for AuthClientImpl { .data .ok_or_else(|| anyhow!("Expected valid response.data"))?; match response.user { - warp_graphql::queries::get_user::UserResult::UserOutput(user_output) => Ok(user_output), - warp_graphql::queries::get_user::UserResult::Unknown => { + galaxy_graphql::queries::get_user::UserResult::UserOutput(user_output) => { + Ok(user_output) + } + galaxy_graphql::queries::get_user::UserResult::Unknown => { Err(anyhow!("Unable to fetch user")) } } @@ -324,11 +328,11 @@ impl AuthClient for AuthClientImpl { async fn get_user_settings(&self) -> Result> { let operation = GetUserSettings::build(GetUserSettingsVariables { - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let response = send_graphql_request(self.base_client.as_ref(), operation, None).await?; match response.user { - warp_graphql::queries::get_user_settings::UserResult::UserOutput(user_output) => { + galaxy_graphql::queries::get_user_settings::UserResult::UserOutput(user_output) => { Ok(user_output .user .settings @@ -339,7 +343,7 @@ impl AuthClient for AuthClientImpl { is_telemetry_enabled: settings.is_telemetry_enabled, })) } - warp_graphql::queries::get_user_settings::UserResult::Unknown => { + galaxy_graphql::queries::get_user_settings::UserResult::Unknown => { Err(anyhow!("Unable to fetch user settings")) } } @@ -385,7 +389,7 @@ impl AuthClient for AuthClientImpl { async fn set_user_is_onboarded(&self) -> Result { let operation = SetUserIsOnboarded::build(SetUserIsOnboardedVariables { - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let result = send_graphql_request(self.base_client.as_ref(), operation, None) .await? @@ -393,7 +397,7 @@ impl AuthClient for AuthClientImpl { match result { SetUserIsOnboardedResult::SetUserIsOnboardedOutput(_) => Ok(true), SetUserIsOnboardedResult::UserFacingError(error) => Err(anyhow!( - warp_graphql::client::get_user_facing_error_message(error) + galaxy_graphql::client::get_user_facing_error_message(error) )), SetUserIsOnboardedResult::Unknown => Err(anyhow!("failed to set user is onboarded")), } @@ -417,13 +421,13 @@ impl AuthClient for AuthClientImpl { async fn list_api_keys(&self) -> Result> { let operation = ApiKeys::build(ApiKeysVariables { - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let response = send_graphql_request(self.base_client.as_ref(), operation, None).await?; match response.api_keys { ApiKeyPropertiesResult::ApiKeyPropertiesOutput(output) => Ok(output.api_keys), ApiKeyPropertiesResult::UserFacingError(error) => Err(anyhow!( - warp_graphql::client::get_user_facing_error_message(error) + galaxy_graphql::client::get_user_facing_error_message(error) )), ApiKeyPropertiesResult::Unknown => Err(anyhow!("failed to fetch API keys")), } @@ -434,7 +438,7 @@ impl AuthClient for AuthClientImpl { name: String, team_id: Option, agent_uid: Option, - expires_at: Option, + expires_at: Option, ) -> Result { let operation = GenerateApiKey::build(GenerateApiKeyVariables { input: GenerateApiKeyInput { @@ -443,7 +447,7 @@ impl AuthClient for AuthClientImpl { agent_uid, expires_at, }, - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let response = send_graphql_request(self.base_client.as_ref(), operation, None).await?; Ok(response.generate_api_key) @@ -452,7 +456,7 @@ impl AuthClient for AuthClientImpl { async fn expire_api_key(&self, key_uid: &ApiKeyUid) -> Result { let operation = ExpireApiKey::build(ExpireApiKeyVariables { key_uid: key_uid.into(), - request_context: warp_graphql::client::get_request_context(), + request_context: galaxy_graphql::client::get_request_context(), }); let response = send_graphql_request(self.base_client.as_ref(), operation, None).await?; Ok(response.expire_api_key) diff --git a/crates/galaxy_server_client/src/auth/mod_tests.rs b/crates/galaxy_server_client/src/auth/mod_tests.rs index 445e5f19..12d1cbd5 100644 --- a/crates/galaxy_server_client/src/auth/mod_tests.rs +++ b/crates/galaxy_server_client/src/auth/mod_tests.rs @@ -1,4 +1,4 @@ -use warp_graphql::mutations::update_user_settings::UpdateUserSettingsResult; +use galaxy_graphql::mutations::update_user_settings::UpdateUserSettingsResult; use super::AuthClientImpl; diff --git a/crates/galaxy_server_client/src/auth/session.rs b/crates/galaxy_server_client/src/auth/session.rs index f230d082..6e9751c6 100644 --- a/crates/galaxy_server_client/src/auth/session.rs +++ b/crates/galaxy_server_client/src/auth/session.rs @@ -4,16 +4,16 @@ use std::sync::Arc; use anyhow::{Context as _, Result, bail}; use firebase::FetchAccessTokenResponse; +use galaxy_core::channel::ChannelState; +use galaxyui_core::r#async::{BoxFuture, Timer}; use instant::Duration; use oauth2::TokenResponse as _; use url::Url; -use galaxy_core::channel::ChannelState; use warp_server_auth::auth_state::AuthState; use warp_server_auth::credentials::{ AuthToken, Credentials, FirebaseToken, LoginToken, RefreshToken, }; use warp_server_auth::user::FirebaseAuthTokens; -use galaxyui_core::r#async::{BoxFuture, Timer}; use super::UserAuthenticationError; diff --git a/crates/galaxy_server_client/src/base_client.rs b/crates/galaxy_server_client/src/base_client.rs index 1fb6d303..d7326cb6 100644 --- a/crates/galaxy_server_client/src/base_client.rs +++ b/crates/galaxy_server_client/src/base_client.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use anyhow::{Context as _, Result}; use futures::StreamExt as _; +use galaxy_graphql::client::RequestOptions; use instant::Duration; use parking_lot::{Mutex, RwLock}; -use warp_graphql::client::RequestOptions; use warp_server_auth::auth_state::AuthState; use warp_server_auth::credentials::AuthToken; @@ -110,7 +110,7 @@ pub struct BaseClient { auth_state: Arc, event_sender: async_channel::Sender, auth_session: Arc, - ambient_workload_token: Arc>>, + ambient_workload_token: Arc>>, ambient_agent_task_id: Arc>>, agent_source: Option, graphql_routing: GraphqlRoutingConfig, @@ -274,13 +274,13 @@ impl BaseClient { } } } - let workload_token = match warp_isolation_platform::issue_workload_token(Some( + let workload_token = match galaxy_isolation_platform::issue_workload_token(Some( AMBIENT_WORKLOAD_TOKEN_DURATION, )) .await { Ok(token) => token, - Err(warp_isolation_platform::IsolationPlatformError::NoIsolationPlatformDetected) => { + Err(galaxy_isolation_platform::IsolationPlatformError::NoIsolationPlatformDetected) => { return Ok(None); } Err(error) => return Err(error.into()), @@ -369,6 +369,7 @@ impl BaseClient { /// Wraps an eventsource stream so IAP challenges notify the application without changing the /// original stream result or reconnecting it. + #[allow(clippy::result_large_err)] pub fn wrap_eventsource_with_iap_detection( &self, stream: http_client::EventSourceStream, diff --git a/crates/galaxy_server_client/src/cloud_object/mod.rs b/crates/galaxy_server_client/src/cloud_object/mod.rs deleted file mode 100644 index 51b17fb3..00000000 --- a/crates/galaxy_server_client/src/cloud_object/mod.rs +++ /dev/null @@ -1,1079 +0,0 @@ -use std::borrow::Cow; -use std::fmt; -use std::str::FromStr; - -use anyhow::{Result, anyhow}; -use chrono::{DateTime, Utc}; -use derivative::Derivative; -use pathfinder_geometry::vector::vec2f; -use serde::{Deserialize, Serialize}; -use galaxy_core::features::FeatureFlag; -use galaxy_core::ui::Icon; -use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::theme::Fill; -use galaxy_graphql::object_permissions::AccessLevel; -use galaxy_graphql::scalars::time::ServerTimestamp; -use galaxyui_core::Element; -use galaxyui_core::elements::{ - Align, ChildAnchor, ConstrainedBox, Hoverable, MouseStateHandle, OffsetPositioning, - ParentAnchor, ParentElement, ParentOffsetBounds, Stack, -}; -use galaxyui_core::ui_components::components::UiComponent; - -use crate::auth::UserUid; -use crate::drive::sharing::{SharingAccessLevel, Subject, TeamKind, UserKind}; -use crate::ids::{FolderId, ServerId, SyncId}; - -mod creation; -mod generic_cloud_object; -mod generic_string_model; -pub mod models; -mod server_object; -mod update; - -pub use creation::*; -pub use generic_cloud_object::*; -pub use generic_string_model::*; -pub use server_object::*; -pub use update::*; -/// The type of object id each ObjectType corresponds to. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum ObjectIdType { - Notebook, - Workflow, - Folder, - GenericStringObject, -} - -impl ObjectIdType { - /// Returns the prefix for server IDs as we store them in sqlite. The prefix for these - /// objects is in title case unlike how we store the object types, which is why two different - /// APIs are needed. - pub fn sqlite_prefix(&self) -> &'static str { - match self { - ObjectIdType::Notebook => "Notebook", - ObjectIdType::Workflow => "Workflow", - ObjectIdType::Folder => "Folder", - ObjectIdType::GenericStringObject => "GenericStringObject", - } - } -} - -/// A type for communicating the type of cloud object to/from the server, absent of the object itself. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] -pub enum ObjectType { - Notebook, - Workflow, - Folder, - GenericStringObject(GenericStringObjectFormat), -} - -impl ObjectType { - /// Returns the serialized string for the object type, to be used for storing object_type in sqlite. - pub fn sqlite_object_type_as_str(&self) -> Cow<'_, str> { - match self { - ObjectType::Notebook => "NOTEBOOK".into(), - ObjectType::Workflow => "WORKFLOW".into(), - ObjectType::Folder => "FOLDER".into(), - ObjectType::GenericStringObject(format) => format.to_string().into(), - } - } -} - -const NOTEBOOK_OBJECT_STRING: &str = "notebook"; -const WORKFLOW_OBJECT_STRING: &str = "workflow"; -const PROMPT_OBJECT_STRING: &str = "prompt"; -const FOLDER_OBJECT_STRING: &str = "folder"; -const ENV_VAR_COLLECTION_STRING: &str = "env-vars"; - -impl FromStr for ObjectType { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s { - NOTEBOOK_OBJECT_STRING => Ok(Self::Notebook), - WORKFLOW_OBJECT_STRING => Ok(Self::Workflow), - PROMPT_OBJECT_STRING => Ok(Self::Workflow), - FOLDER_OBJECT_STRING => Ok(Self::Folder), - ENV_VAR_COLLECTION_STRING => Ok(Self::GenericStringObject( - GenericStringObjectFormat::Json(JsonObjectType::EnvVarCollection), - )), - _ => Err(anyhow!("Unexpected object type")), - } - } -} - -impl fmt::Display for ObjectType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ObjectType::Notebook => write!(f, "{NOTEBOOK_OBJECT_STRING}"), - ObjectType::Workflow => write!(f, "{WORKFLOW_OBJECT_STRING}"), - ObjectType::Folder => write!(f, "{FOLDER_OBJECT_STRING}"), - ObjectType::GenericStringObject(GenericStringObjectFormat::Json( - JsonObjectType::EnvVarCollection, - )) => write!(f, "{ENV_VAR_COLLECTION_STRING}"), - ObjectType::GenericStringObject(GenericStringObjectFormat::Json( - JsonObjectType::AIFact, - )) => write!(f, "rule"), - ObjectType::GenericStringObject(_) => write!(f, "string_object_placeholder"), // placeholder value - } - } -} - -impl From for ObjectIdType { - fn from(value: ObjectType) -> Self { - match value { - ObjectType::Notebook => ObjectIdType::Notebook, - ObjectType::Workflow => ObjectIdType::Workflow, - ObjectType::Folder => ObjectIdType::Folder, - ObjectType::GenericStringObject(_) => ObjectIdType::GenericStringObject, - } - } -} - -/// The object type prefix for generic string objects. -pub const GENERIC_STRING_OBJECT_PREFIX: &str = "GENERIC_STRING_"; - -/// The object type prefix for json objects. -pub const JSON_OBJECT_PREFIX: &str = "JSON_"; - -/// The data format for the generic string object type. -/// Right now we only support json, but this is left -/// open to support markdown, yaml and other text based types. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] -pub enum GenericStringObjectFormat { - Json(JsonObjectType), -} - -/// Represents a unique key for a generic string object. The server enforces that -/// no two generic string objects have the same key. -#[derive(PartialEq, Eq, Debug, Clone)] -pub struct GenericStringObjectUniqueKey { - /// The unique key. E.g. for cloud prefs this is the storage key of the pref. - pub key: String, - - /// Whether this key is unique for all generic string objects, or unique per user. - pub unique_per: UniquePer, -} - -#[derive(PartialEq, Eq, Debug, Clone)] -pub enum UniquePer { - User, -} - -// Temporarily suppress clippy warnings about the `ToString` impl until we -// move `ObjectType` away from using `std::fmt::Display` for serialization. -#[allow(clippy::to_string_trait_impl)] -impl ToString for GenericStringObjectFormat { - fn to_string(&self) -> String { - match self { - GenericStringObjectFormat::Json(json_object_type) => format!( - "{}{}{}", - GENERIC_STRING_OBJECT_PREFIX, - JSON_OBJECT_PREFIX, - json_object_type.as_str() - ), - } - } -} - -/// An object sub-type for objects that implement the JsonModel trait. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] -pub enum JsonObjectType { - Preference, - EnvVarCollection, - WorkflowEnum, - AIFact, - MCPServer, - AIExecutionProfile, - TemplatableMCPServer, - CloudEnvironment, - ScheduledAmbientAgent, - CloudAgentConfig, -} - -impl JsonObjectType { - pub fn as_str(&self) -> &'static str { - match self { - JsonObjectType::Preference => "PREFERENCE", - JsonObjectType::EnvVarCollection => "ENVVARCOLLECTION", - JsonObjectType::WorkflowEnum => "WORKFLOWENUM", - JsonObjectType::AIFact => "AIFACT", - JsonObjectType::MCPServer => "MCPSERVER", - JsonObjectType::AIExecutionProfile => "AIEXECUTIONPROFILE", - JsonObjectType::TemplatableMCPServer => "TEMPLATABLEMCPSERVER", - JsonObjectType::CloudEnvironment => "CLOUDENVIRONMENT", - JsonObjectType::ScheduledAmbientAgent => "SCHEDULEDAMBIENTAGENT", - JsonObjectType::CloudAgentConfig => "CLOUDAGENTCONFIG", - } - } -} - -impl TryFrom<&str> for JsonObjectType { - type Error = anyhow::Error; - - fn try_from(value: &str) -> std::result::Result { - match value { - "PREFERENCE" => Ok(JsonObjectType::Preference), - "ENVVARCOLLECTION" => Ok(JsonObjectType::EnvVarCollection), - "WORKFLOWENUM" => Ok(JsonObjectType::WorkflowEnum), - "AIFACT" => Ok(JsonObjectType::AIFact), - "MCPSERVER" => Ok(JsonObjectType::MCPServer), - "AIEXECUTIONPROFILE" => Ok(JsonObjectType::AIExecutionProfile), - "TEMPLATABLEMCPSERVER" => Ok(JsonObjectType::TemplatableMCPServer), - "CLOUDENVIRONMENT" => Ok(JsonObjectType::CloudEnvironment), - "SCHEDULEDAMBIENTAGENT" => Ok(JsonObjectType::ScheduledAmbientAgent), - "CLOUDAGENTCONFIG" => Ok(JsonObjectType::CloudAgentConfig), - _ => Err(anyhow!("could not convert unknown json object type")), - } - } -} - -impl TryFrom for ObjectIdType { - type Error = anyhow::Error; - fn try_from(object_type: galaxy_graphql::object::ObjectType) -> Result { - match object_type { - galaxy_graphql::object::ObjectType::AIConversation => Err(anyhow!( - "AIConversation is not a supported object type for this operation" - )), - galaxy_graphql::object::ObjectType::Notebook => Ok(ObjectIdType::Notebook), - galaxy_graphql::object::ObjectType::Workflow => Ok(ObjectIdType::Workflow), - galaxy_graphql::object::ObjectType::Folder => Ok(ObjectIdType::Folder), - galaxy_graphql::object::ObjectType::GenericStringObject => { - Ok(ObjectIdType::GenericStringObject) - } - galaxy_graphql::object::ObjectType::Unknown => { - Err(anyhow!("could not convert unknown cloud object type")) - } - } - } -} - -impl From for galaxy_graphql::object::ObjectType { - fn from(value: ObjectType) -> Self { - match value { - ObjectType::Notebook => galaxy_graphql::object::ObjectType::Notebook, - ObjectType::Workflow => galaxy_graphql::object::ObjectType::Workflow, - ObjectType::Folder => galaxy_graphql::object::ObjectType::Folder, - ObjectType::GenericStringObject(GenericStringObjectFormat::Json( - JsonObjectType::EnvVarCollection, - )) => galaxy_graphql::object::ObjectType::GenericStringObject, - ObjectType::GenericStringObject(gso) => { - todo!("Moving is not implemented for {:?}", gso); - } - } - } -} - -/// The revision timestamp at which an object was edited. This is used by the server -/// to determine if an edit to an object was at the latest revision. Edits at older -/// revisions are rejected by the server. -#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, PartialOrd, Ord)] -pub struct Revision(ServerTimestamp); - -impl Revision { - pub fn from_unix_timestamp_micros(ms_since_epoch: i64) -> Result { - let ts = ServerTimestamp::from_unix_timestamp_micros(ms_since_epoch)?; - Ok(Self(ts)) - } - - pub fn timestamp_micros(&self) -> i64 { - self.0.timestamp_micros() - } - - pub fn utc(&self) -> DateTime { - self.0.utc() - } - - /// Returns the inner `ServerTimestamp`. - pub fn timestamp(&self) -> ServerTimestamp { - self.0 - } - - #[cfg(any(test, feature = "test-util"))] - pub fn now() -> Self { - Self(ServerTimestamp::new(Utc::now())) - } -} - -impl From for ServerTimestamp { - fn from(revision: Revision) -> Self { - revision.0 - } -} - -impl From for Revision { - fn from(time: ServerTimestamp) -> Self { - Revision(time) - } -} - -#[cfg(any(test, feature = "test-util"))] -impl From> for Revision { - fn from(time: DateTime) -> Self { - Self(ServerTimestamp::new(time)) - } -} - -/// The owner for a given object. -#[derive(Copy, Clone, Debug, Eq, Serialize, Deserialize, Derivative)] -#[derivative(PartialEq)] -pub enum Owner { - /// The owner of the object is a user (the object is in their personal drive). - User { user_uid: UserUid }, - /// The owner of the object is a team (the object is in a team drive). - Team { team_uid: ServerId }, -} - -impl Owner { - /// A mock [`Owner`] ID for testing. - #[cfg(any(test, feature = "test-util"))] - pub fn mock_current_user() -> Owner { - use crate::auth::TEST_USER_UID; - - Owner::User { - user_uid: UserUid::new(TEST_USER_UID), - } - } -} - -impl From for Option { - fn from(owner: Owner) -> Option { - match owner { - Owner::User { .. } => None, - Owner::Team { team_uid, .. } => Some(team_uid), - } - } -} - -/// Server representation of an object's container. This corresponds to the `Container` GraphQL -/// type. -/// -/// Containers are similar to, but not quite the same as, the [`CloudObjectLocation`] type. -/// Locations depend on object and user state - an object might currently be in the trash, or -/// it could be in one user's [shared space](Space::Shared) but another's -/// [team space](Space::Team). Containers, on the other hand, represent an object's canonical -/// parent - its one parent folder or drive that permissions are inherited from. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub enum ServerObjectContainer { - Folder { folder_uid: ServerId }, - Drive { owner: Owner }, -} - -/// Server representation of a user object guest, as part of [`ServerObjectGuest`]. -#[derive(Clone, Debug, PartialEq)] -pub enum ServerGuestSubject { - User { firebase_uid: String }, - PendingUser { email: Option }, - Team { team_uid: ServerId }, -} - -/// Server representation of a link-sharing setting. -#[derive(Clone, Debug, PartialEq)] -pub struct ServerLinkSharing { - pub access_level: AccessLevel, - pub source: Option, -} - -/// Server representation of an object guest. This corresponds to the `ObjectGuest` GraphQL type. -#[derive(Clone, Debug, PartialEq)] -pub struct ServerObjectGuest { - pub subject: ServerGuestSubject, - pub access_level: AccessLevel, - /// If this guest is inherited, this is the ancestor that it's inherited from. - pub source: Option, -} - -/// Metadata for a cloud object that was fetched from the server. -#[derive(Clone, Debug)] -pub struct ServerMetadata { - pub uid: ServerId, - pub revision: Revision, - pub metadata_last_updated_ts: ServerTimestamp, - pub trashed_ts: Option, - pub folder_id: Option, - pub is_welcome_object: bool, - pub creator_uid: Option, - pub last_editor_uid: Option, - pub current_editor_uid: Option, -} - -/// Permissions for a cloud object that was fetched from the server. -#[derive(Clone, Debug, PartialEq)] -pub struct ServerPermissions { - /// The GraphQL definition of a `Space` is closer to the client's definition of an `Owner` (due - /// to sharing). This is also going to migrate back to [ServerMetadata] as part of the - /// `Container` migration. - pub space: Owner, - pub guests: Vec, - pub anyone_link_sharing: Option, - pub permissions_last_updated_ts: ServerTimestamp, -} - -impl ServerPermissions { - #[cfg(any(test, feature = "test-util"))] - pub fn mock_personal() -> Self { - Self { - space: Owner::mock_current_user(), - guests: Vec::new(), - anyone_link_sharing: None, - permissions_last_updated_ts: DateTime::::default().into(), - } - } -} - -#[derive(Clone, Debug)] -pub struct NumInFlightRequests(pub usize); - -#[derive(Clone, Debug)] -/// An enum representing what state a local cloud object's content changes can be in, -/// in relation to the server. -pub enum CloudObjectSyncStatus { - /// The object's content hasn't changed from what we believe the server's representation - /// to be. - NoLocalChanges, - /// The object's content has been modified locally, and is currently in the sync queue - /// attempting to sync up with the server. - InFlight(NumInFlightRequests), - /// The object's content has been modified locally but has unresolved conflict with the server - /// revision. - InConflict, - /// The object's content has been modified locally, but persisting the change on the server - /// could not complete for some reason. - Errored, -} - -const SYNC_ICON_DIMENSIONS: f32 = 16.; - -const SYNC_STATUS_TOOLTIP_LOCAL_ONLY: &str = "Saved locally"; -const SYNC_STATUS_TOOLTIP_INFLIGHT: &str = "Saving"; -const SYNC_STATUS_TOOLTIP_ERROR: &str = "Failed to save"; - -#[derive(Debug, Clone, PartialEq)] -pub struct CloudObjectPermissions { - pub owner: Owner, - pub permissions_last_updated_ts: Option, - pub anyone_with_link: Option, - pub guests: Vec, -} - -impl CloudObjectPermissions { - pub fn new_from_server(server_permissions: ServerPermissions) -> Self { - let guests = if FeatureFlag::SharedWithMe.is_enabled() { - server_permissions - .guests - .into_iter() - .map(CloudObjectGuest::from_server) - .collect() - } else { - Vec::new() - }; - - let anyone_with_link = if FeatureFlag::SharedWithMe.is_enabled() { - server_permissions - .anyone_link_sharing - .map(CloudLinkSharing::from_server) - } else { - None - }; - - Self { - owner: server_permissions.space, - permissions_last_updated_ts: Some(server_permissions.permissions_last_updated_ts), - guests, - anyone_with_link, - } - } - - /// Mock permissions for a personal object. - #[cfg(any(test, feature = "test-util"))] - pub fn mock_personal() -> Self { - Self { - owner: Owner::mock_current_user(), - permissions_last_updated_ts: Some(Utc::now().into()), - guests: Vec::new(), - anyone_with_link: None, - } - } - - /// Returns `true` if the given user has direct personal access to this object — - /// either via an explicit user guest ACL entry or via link sharing. - /// Returns `false` if the only access is through a team guest ACL. - pub fn has_direct_user_access(&self, user_uid: UserUid) -> bool { - self.anyone_with_link.is_some() || self.guests.iter().any(|g| g.subject.is_user(user_uid)) - } - - /// Updates self from new permissions information received from the server - pub fn update_from_new_permissions_ts(&mut self, server_permissions: ServerPermissions) { - self.owner = server_permissions.space; - self.permissions_last_updated_ts = Some(server_permissions.permissions_last_updated_ts); - if FeatureFlag::SharedWithMe.is_enabled() { - self.guests = server_permissions - .guests - .into_iter() - .map(CloudObjectGuest::from_server) - .collect(); - self.anyone_with_link = server_permissions - .anyone_link_sharing - .map(CloudLinkSharing::from_server); - } - } -} - -#[derive(Clone, Debug, PartialEq)] -pub struct CloudLinkSharing { - pub access_level: SharingAccessLevel, - // If this sharing setting was inherited, the `source` identifies the container it's inherited - // from. - pub source: Option, -} - -impl CloudLinkSharing { - pub fn from_server(server_link_sharing: ServerLinkSharing) -> Self { - Self { - access_level: server_link_sharing.access_level.into(), - source: server_link_sharing.source, - } - } -} - -#[derive(Clone, Debug, PartialEq)] -pub struct CloudObjectGuest { - pub subject: Subject, - pub access_level: SharingAccessLevel, - /// If this guest was added to a container object, the `source` identifies that object. - pub source: Option, -} - -impl CloudObjectGuest { - pub fn from_server(server_guest: ServerObjectGuest) -> Self { - let subject = match server_guest.subject { - ServerGuestSubject::User { firebase_uid } => { - Subject::User(UserKind::Account(UserUid::new(&firebase_uid))) - } - ServerGuestSubject::PendingUser { email } => Subject::PendingUser { email }, - ServerGuestSubject::Team { team_uid } => Subject::Team(TeamKind::Team { team_uid }), - }; - - Self { - subject, - access_level: server_guest.access_level.into(), - source: server_guest.source, - } - } -} - -#[derive(Clone, Debug)] -pub struct CloudObjectMetadata { - pub revision: Option, - pub metadata_last_updated_ts: Option, - pub current_editor_uid: Option, - pub pending_changes_statuses: CloudObjectStatuses, - pub trashed_ts: Option, - pub folder_id: Option, - /// Welcome objects are created on the server when a user first receives - /// access to Warp Drive as part of onboarding. - pub is_welcome_object: bool, - pub last_editor_uid: Option, - pub creator_uid: Option, - /// The "last used" timestamp for this environment. - /// - /// This is populated via `GetCloudEnvironments` from - /// `CloudEnvironment.lastTaskCreated.createdAt`. - /// Only applicable for CloudEnvironment objects. - pub last_task_run_ts: Option, -} - -impl CloudObjectMetadata { - pub fn new_from_server(server_metadata: ServerMetadata) -> Self { - Self { - revision: Some(server_metadata.revision), - current_editor_uid: server_metadata.current_editor_uid, - metadata_last_updated_ts: Some(server_metadata.metadata_last_updated_ts), - pending_changes_statuses: CloudObjectStatuses { - content_sync_status: CloudObjectSyncStatus::NoLocalChanges, - has_pending_metadata_change: false, - has_pending_permissions_change: false, - pending_untrash: false, - pending_delete: false, - }, - trashed_ts: server_metadata.trashed_ts, - folder_id: server_metadata.folder_id.map(|id| id.into()), - is_welcome_object: server_metadata.is_welcome_object, - creator_uid: server_metadata.creator_uid, - last_editor_uid: server_metadata.last_editor_uid, - // last_task_run_ts is populated separately via GetCloudEnvironments query - last_task_run_ts: None, - } - } - - /// Creates a new set of metadata with reasonable defaults for a test: - /// * Content and metadata timestamps set to now - /// * No editor information - /// * No parent folder - /// * Not trashed - #[cfg(any(test, feature = "test-util"))] - pub fn mock() -> Self { - Self { - revision: Some(Revision::now()), - current_editor_uid: None, - metadata_last_updated_ts: Some(Utc::now().into()), - pending_changes_statuses: CloudObjectStatuses::mock(), - trashed_ts: None, - folder_id: None, - is_welcome_object: false, - last_editor_uid: None, - creator_uid: None, - last_task_run_ts: None, - } - } - - pub fn has_pending_content_changes(&self) -> bool { - !matches!( - self.pending_changes_statuses.content_sync_status, - CloudObjectSyncStatus::NoLocalChanges | CloudObjectSyncStatus::InConflict - ) - } - - pub fn is_errored(&self) -> bool { - matches!( - self.pending_changes_statuses.content_sync_status, - CloudObjectSyncStatus::Errored - ) - } - - /// True iff there are unsynced online-only changes for the object. - pub fn has_pending_online_only_change(&self) -> bool { - self.pending_changes_statuses.has_pending_permissions_change - || self.pending_changes_statuses.has_pending_metadata_change - || self.pending_changes_statuses.pending_untrash - || self.pending_changes_statuses.pending_delete - } - - pub fn set_current_editor(&mut self, editor_uid: Option) { - self.current_editor_uid = editor_uid; - } - - /// Updates revision and last_editor_uid from server metadata. - /// - /// This unconditionally updates the revision and last_editor_uid, even if - /// there are conflicts, so callers should check for conflicts before calling - /// this. - pub fn update_revision_from_server(&mut self, server_metadata: &ServerMetadata) { - self.revision = Some(server_metadata.revision.clone()); - self.last_editor_uid = server_metadata.last_editor_uid.clone(); - } - - /// Updates self from a new metadata received from the server - pub fn update_from_new_metadata_ts(&mut self, server_metadata: ServerMetadata) { - // Overwriting the metadata from an MetadataUpdated RTC message shouldn't overwrite - // the versioning of the object's data: the revision timestamp, has_pending_changes, conflict_status - // (if the object data is not being updated, the data versioning should stay the same. - self.current_editor_uid = server_metadata.current_editor_uid; - self.trashed_ts = server_metadata.trashed_ts; - self.folder_id = server_metadata.folder_id.map(|folder_id| folder_id.into()); - self.creator_uid = server_metadata.creator_uid; - self.metadata_last_updated_ts = Some(server_metadata.metadata_last_updated_ts); - } -} - -/// A struct holding the different statuses of pending changes that a cloud object might have. -/// Note that content is handled differently than permissions/metadata: -/// * Content changes go through the sync queue, and thus can exist in more states -/// * Metadata/permissions changes are synchronous operations, and thus are only either -/// in flight or synced -#[derive(Clone, Debug)] -pub struct CloudObjectStatuses { - pub content_sync_status: CloudObjectSyncStatus, - /// True iff there are unsynced permission changes for the object. - /// We intentionally don't persist this value in sqlite. And if true, - /// we don't upsert any in-memory permission changes to sqlite. - pub has_pending_permissions_change: bool, - /// True iff there are unsynced metadata changes for the object. - /// We intentionally don't persist this value in sqlite. And if true, - /// we don't upsert trashed and folder changes to sqlite. - pub has_pending_metadata_change: bool, - - /// True iff there is an unsynced untrash operation on the object. - pub pending_untrash: bool, - - /// True iff there is an unsynced delete operation on the object. - pub pending_delete: bool, -} - -impl CloudObjectStatuses { - /// Empty statuses with no in-flight changes, for use in tests. - #[cfg(any(test, feature = "test-util"))] - pub fn mock() -> Self { - Self { - content_sync_status: CloudObjectSyncStatus::NoLocalChanges, - has_pending_permissions_change: false, - has_pending_metadata_change: false, - pending_untrash: false, - pending_delete: false, - } - } - - pub fn render_icon( - &self, - sync_queue_is_dequeueing: bool, - hover_state: MouseStateHandle, - appearance: &Appearance, - ) -> Option> { - let theme = appearance.theme(); - let has_in_flight_requests = match &self.content_sync_status { - CloudObjectSyncStatus::InFlight(reqs) => reqs.0 > 0, - _ => false, - }; - - let should_show_local_only_indicator = has_in_flight_requests && !sync_queue_is_dequeueing; - let should_show_syncing_indicator = has_in_flight_requests - || self.has_pending_metadata_change - || self.has_pending_permissions_change - || self.pending_untrash; - let should_show_error_indicator = matches!( - self.content_sync_status, - CloudObjectSyncStatus::Errored | CloudObjectSyncStatus::InConflict - ); - - let icon_and_tooltip_text = if should_show_local_only_indicator { - Some(( - Icon::Laptop.to_galaxyui_icon(theme.main_text_color(theme.surface_1())), - SYNC_STATUS_TOOLTIP_LOCAL_ONLY, - )) - } else if should_show_syncing_indicator { - Some(( - Icon::Refresh.to_galaxyui_icon(theme.sub_text_color(theme.surface_2())), - SYNC_STATUS_TOOLTIP_INFLIGHT, - )) - } else if should_show_error_indicator { - Some(( - Icon::AlertTriangle.to_galaxyui_icon(Fill::Solid(theme.ui_error_color())), - SYNC_STATUS_TOOLTIP_ERROR, - )) - } else { - None - }; - - if let Some((icon, tooltip_text)) = icon_and_tooltip_text { - return Some( - Align::new( - Hoverable::new(hover_state, move |hover_state| { - let mut stack = Stack::new().with_child( - ConstrainedBox::new(icon.finish()) - .with_height(SYNC_ICON_DIMENSIONS) - .with_width(SYNC_ICON_DIMENSIONS) - .finish(), - ); - - if hover_state.is_hovered() { - let tooltip = appearance - .ui_builder() - .tool_tip(tooltip_text.to_string()) - .build() - .finish(); - - stack.add_positioned_overlay_child( - tooltip, - OffsetPositioning::offset_from_parent( - vec2f(0., -24.), - ParentOffsetBounds::Unbounded, - ParentAnchor::Center, - ChildAnchor::Center, - ), - ); - } - - stack.finish() - }) - .finish(), - ) - .finish(), - ); - } - - None - } -} - -// Used for event tracking purposes, matches -// up with GraphQL enum of the same name. -#[derive(Copy, Default, Clone, Debug, Eq, PartialEq)] -pub enum CloudObjectEventEntrypoint { - TeamSettings, - ResourceCenter, - UniversalSearch, - ManagementUI, - Blocklist, - ImportModal, - Onboarding, - #[default] - Unknown, -} - -// A newtype for a serialized model that wraps a plain string. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct SerializedModel(String); - -impl SerializedModel { - pub fn new(s: String) -> Self { - Self(s) - } - - pub fn model_as_str(&self) -> &str { - &self.0 - } - - pub fn take(self) -> String { - self.0 - } -} - -impl From for SerializedModel { - fn from(s: String) -> Self { - Self(s) - } -} - -#[derive(Clone, Debug, PartialEq)] -pub struct RevisionAndLastEditor { - pub revision: Revision, - pub last_editor_uid: Option, -} - -// GraphQL conversion impls. - -impl From - for galaxy_graphql::generic_string_object::GenericStringObjectFormat -{ - fn from(format: GenericStringObjectFormat) -> Self { - use galaxy_graphql::generic_string_object::GenericStringObjectFormat as GraphQLFormat; - match format { - GenericStringObjectFormat::Json(JsonObjectType::Preference) => { - GraphQLFormat::JsonPreference - } - GenericStringObjectFormat::Json(JsonObjectType::EnvVarCollection) => { - GraphQLFormat::JsonEnvVarCollection - } - GenericStringObjectFormat::Json(JsonObjectType::WorkflowEnum) => { - GraphQLFormat::JsonWorkflowEnum - } - GenericStringObjectFormat::Json(JsonObjectType::AIFact) => GraphQLFormat::JsonAIFact, - GenericStringObjectFormat::Json(JsonObjectType::MCPServer) => { - GraphQLFormat::JsonMCPServer - } - GenericStringObjectFormat::Json(JsonObjectType::AIExecutionProfile) => { - GraphQLFormat::JsonAIExecutionProfile - } - GenericStringObjectFormat::Json(JsonObjectType::TemplatableMCPServer) => { - GraphQLFormat::JsonTemplatableMCPServer - } - GenericStringObjectFormat::Json(JsonObjectType::CloudEnvironment) => { - GraphQLFormat::JsonCloudEnvironment - } - GenericStringObjectFormat::Json(JsonObjectType::ScheduledAmbientAgent) => { - GraphQLFormat::JsonScheduledAmbientAgent - } - GenericStringObjectFormat::Json(JsonObjectType::CloudAgentConfig) => { - unreachable!("JsonCloudAgentConfig is no longer present in GraphQL schema") - } - } - } -} - -impl From for galaxy_graphql::object::CloudObjectEventEntrypoint { - fn from(entrypoint: CloudObjectEventEntrypoint) -> Self { - use galaxy_graphql::object::CloudObjectEventEntrypoint as GraphQLEntrypoint; - match entrypoint { - CloudObjectEventEntrypoint::TeamSettings => GraphQLEntrypoint::TeamSettings, - CloudObjectEventEntrypoint::ResourceCenter => GraphQLEntrypoint::ResourceCenter, - CloudObjectEventEntrypoint::UniversalSearch => GraphQLEntrypoint::UniversalSearch, - CloudObjectEventEntrypoint::ManagementUI => GraphQLEntrypoint::DriveIndex, - CloudObjectEventEntrypoint::Blocklist => GraphQLEntrypoint::Blocklist, - CloudObjectEventEntrypoint::ImportModal => GraphQLEntrypoint::ImportModal, - CloudObjectEventEntrypoint::Onboarding => GraphQLEntrypoint::Onboarding, - CloudObjectEventEntrypoint::Unknown => GraphQLEntrypoint::Unknown, - } - } -} - -impl From - for galaxy_graphql::generic_string_object::GenericStringObjectUniqueKey -{ - fn from(key: GenericStringObjectUniqueKey) -> Self { - use galaxy_graphql::generic_string_object::GenericStringObjectUniqueKey as GraphQLKey; - GraphQLKey { - key: key.key, - unique_per: key.unique_per.into(), - } - } -} - -impl From for galaxy_graphql::generic_string_object::UniquePer { - fn from(unique_per: UniquePer) -> Self { - use galaxy_graphql::generic_string_object::UniquePer as GraphQLUniquePer; - match unique_per { - UniquePer::User => GraphQLUniquePer::User, - } - } -} - -impl TryFrom for ServerMetadata { - type Error = anyhow::Error; - - fn try_from(value: galaxy_graphql::object::ObjectMetadata) -> Result { - let folder_id: Option = match value.parent { - galaxy_graphql::object::Container::FolderContainer(folder_container) => { - Some(folder_container.folder_uid.into_inner().into()) - } - _ => None, - }; - let metadata = ServerMetadata { - uid: ServerId::from_string_lossy(value.uid.inner()), - revision: value.revision_ts.into(), - metadata_last_updated_ts: value.metadata_last_updated_ts, - trashed_ts: value.trashed_ts, - folder_id, - is_welcome_object: value.is_welcome_object, - creator_uid: value.creator_uid.map(|uid| uid.into_inner()), - last_editor_uid: value.last_editor_uid.map(|uid| uid.into_inner()), - current_editor_uid: value.current_editor_uid.map(|uid| uid.into_inner()), - }; - Ok(metadata) - } -} - -impl TryFrom for ServerPermissions { - type Error = anyhow::Error; - - fn try_from( - value: galaxy_graphql::object_permissions::ObjectPermissions, - ) -> Result { - let server_object_guests: Result, _> = value - .guests - .into_iter() - .map(|guest| guest.try_into()) - .collect(); - let object_permissions = ServerPermissions { - space: value.space.try_into()?, - guests: server_object_guests?, - anyone_link_sharing: match value.anyone_link_sharing { - Some(sharing) => Some(sharing.try_into()?), - None => None, - }, - permissions_last_updated_ts: value.last_updated_ts, - }; - Ok(object_permissions) - } -} - -impl TryFrom for ServerObjectGuest { - type Error = anyhow::Error; - - fn try_from( - value: galaxy_graphql::object_permissions::ObjectGuest, - ) -> Result { - let object_guest = ServerObjectGuest { - subject: value.subject.try_into()?, - access_level: value.access_level, - source: match value.source { - Some(container) => Some(container.try_into()?), - None => None, - }, - }; - Ok(object_guest) - } -} - -impl TryFrom for ServerGuestSubject { - type Error = anyhow::Error; - - fn try_from( - value: galaxy_graphql::object_permissions::GuestSubject, - ) -> Result { - match value { - galaxy_graphql::object_permissions::GuestSubject::UserGuest(user_guest) => { - let guest_subject = ServerGuestSubject::User { - firebase_uid: user_guest.firebase_uid.into_inner(), - }; - Ok(guest_subject) - } - galaxy_graphql::object_permissions::GuestSubject::PendingUserGuest(guest) => { - Ok(ServerGuestSubject::PendingUser { email: guest.email }) - } - galaxy_graphql::object_permissions::GuestSubject::TeamGuest(team_guest) => { - Ok(ServerGuestSubject::Team { - team_uid: ServerId::from_string_lossy(team_guest.uid.inner()), - }) - } - galaxy_graphql::object_permissions::GuestSubject::Unknown => { - anyhow::bail!("Unknown GuestSubject type") - } - } - } -} - -impl TryFrom for ServerLinkSharing { - type Error = anyhow::Error; - - fn try_from( - value: galaxy_graphql::object_permissions::LinkSharing, - ) -> Result { - Ok(ServerLinkSharing { - access_level: value.access_level, - source: value.source.map(TryInto::try_into).transpose()?, - }) - } -} - -impl TryFrom for ServerObjectContainer { - type Error = anyhow::Error; - - fn try_from(value: galaxy_graphql::object::Container) -> Result { - match value { - galaxy_graphql::object::Container::FolderContainer(folder) => { - Ok(ServerObjectContainer::Folder { - folder_uid: ServerId::from_string_lossy(folder.folder_uid.inner()), - }) - } - galaxy_graphql::object::Container::Space(space) => Ok(ServerObjectContainer::Drive { - owner: space.try_into()?, - }), - galaxy_graphql::object::Container::Unknown => { - anyhow::bail!("Unknown Container type") - } - } - } -} - -impl TryFrom for Owner { - type Error = anyhow::Error; - - fn try_from(value: galaxy_graphql::object::Space) -> Result { - let owner = match value.type_ { - galaxy_graphql::object::SpaceType::Team => Owner::Team { - team_uid: ServerId::from_string_lossy(value.uid.inner()), - }, - galaxy_graphql::object::SpaceType::User => Owner::User { - user_uid: UserUid::new(value.uid.inner()), - }, - }; - Ok(owner) - } -} - -impl From for galaxy_graphql::object_permissions::Owner { - fn from(owner: Owner) -> Self { - use galaxy_graphql::object_permissions::{Owner as GraphQLOwner, OwnerType}; - match owner { - Owner::User { user_uid } => GraphQLOwner { - type_: OwnerType::User, - uid: Some(cynic::Id::new(user_uid.to_string())), - }, - Owner::Team { team_uid, .. } => GraphQLOwner { - type_: OwnerType::Team, - uid: Some(cynic::Id::new(team_uid)), - }, - } - } -} diff --git a/crates/galaxy_server_client/src/drive.rs b/crates/galaxy_server_client/src/drive.rs deleted file mode 100644 index af90f02a..00000000 --- a/crates/galaxy_server_client/src/drive.rs +++ /dev/null @@ -1 +0,0 @@ -pub use cloud_objects::drive::*; diff --git a/crates/galaxy_server_client/src/drive/mod.rs b/crates/galaxy_server_client/src/drive/mod.rs index 1e6f80f8..9afe53c4 100644 --- a/crates/galaxy_server_client/src/drive/mod.rs +++ b/crates/galaxy_server_client/src/drive/mod.rs @@ -1 +1,2 @@ pub mod sharing; +pub use cloud_objects::drive::*; diff --git a/crates/galaxy_server_client/src/drive/sharing.rs b/crates/galaxy_server_client/src/drive/sharing.rs index c18b4799..07121f49 100644 --- a/crates/galaxy_server_client/src/drive/sharing.rs +++ b/crates/galaxy_server_client/src/drive/sharing.rs @@ -1,11 +1,11 @@ use std::str::FromStr; +use cloud_objects::cloud_object::Owner; use galaxy_graphql::object_permissions::AccessLevel; use serde::{Deserialize, Serialize}; use session_sharing_protocol::common::{ProfileData as SessionSharingProfileData, Role}; use crate::auth::UserUid; -use crate::cloud_object::Owner; use crate::ids::ServerId; #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] diff --git a/crates/galaxy_server_client/src/graphql_helpers.rs b/crates/galaxy_server_client/src/graphql_helpers.rs index a55a1d28..461fc890 100644 --- a/crates/galaxy_server_client/src/graphql_helpers.rs +++ b/crates/galaxy_server_client/src/graphql_helpers.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; use anyhow::{Result, anyhow}; +use galaxy_graphql::client::{GraphQLError, Operation}; +use galaxyui_core::r#async::BoxFuture; use http::StatusCode; use instant::Duration; -use warp_graphql::client::{GraphQLError, Operation}; -use galaxyui_core::r#async::BoxFuture; use crate::auth::AuthEvent; use crate::base_client::BaseClient; diff --git a/crates/galaxy_server_client/src/graphql_helpers_tests.rs b/crates/galaxy_server_client/src/graphql_helpers_tests.rs index 1607ff6e..4a2500c7 100644 --- a/crates/galaxy_server_client/src/graphql_helpers_tests.rs +++ b/crates/galaxy_server_client/src/graphql_helpers_tests.rs @@ -6,8 +6,8 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use cynic::{GraphQlError, GraphQlResponse}; use futures::executor::block_on; +use galaxy_graphql::client::{GraphQLError, RequestOptions}; use http::StatusCode; -use warp_graphql::client::{GraphQLError, RequestOptions}; use warp_server_auth::auth_state::AuthState; use super::send_graphql_request; @@ -124,7 +124,7 @@ impl FakeGraphqlOperation { } } -impl warp_graphql::client::Operation<()> for FakeGraphqlOperation { +impl galaxy_graphql::client::Operation<()> for FakeGraphqlOperation { fn operation_name(&self) -> Option> { Some(Cow::Borrowed("FakeGraphqlOperation")) } diff --git a/crates/galaxy_server_client/src/iap.rs b/crates/galaxy_server_client/src/iap.rs index adb27d1c..82f730de 100644 --- a/crates/galaxy_server_client/src/iap.rs +++ b/crates/galaxy_server_client/src/iap.rs @@ -4,10 +4,10 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use anyhow::Result; use base64::Engine; use blocking::unblock; -use instant::Instant; use galaxy_core::channel::IapConfig; use galaxyui_core::r#async::{BoxFuture, FutureExt as _, Timer}; use galaxyui_core::{AppContext, Entity, ModelContext, SingletonEntity}; +use instant::Instant; #[cfg(not(target_family = "wasm"))] use websocket::connect_error_http_response; diff --git a/crates/galaxy_server_client/src/iap_tests.rs b/crates/galaxy_server_client/src/iap_tests.rs index dfebc201..87fa360c 100644 --- a/crates/galaxy_server_client/src/iap_tests.rs +++ b/crates/galaxy_server_client/src/iap_tests.rs @@ -1,8 +1,8 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use base64::Engine; -use instant::Instant; use galaxy_core::channel::IapConfig; +use instant::Instant; use super::*; diff --git a/crates/galaxy_server_client/src/persistence/mod.rs b/crates/galaxy_server_client/src/persistence/mod.rs index 441cec56..b808f453 100644 --- a/crates/galaxy_server_client/src/persistence/mod.rs +++ b/crates/galaxy_server_client/src/persistence/mod.rs @@ -7,7 +7,7 @@ use diesel::result::Error; pub use cloud_objects::{decode_guests, decode_link_sharing, encode_guests, encode_link_sharing}; -use crate::cloud_object::{ +use cloud_objects::cloud_object::{ CloudObjectMetadata, CloudObjectPermissions, ObjectIdType, ObjectType, Owner, }; use crate::ids::SyncId; diff --git a/crates/galaxy_server_client/src/public_api.rs b/crates/galaxy_server_client/src/public_api.rs index 7925f7c4..00f943c0 100644 --- a/crates/galaxy_server_client/src/public_api.rs +++ b/crates/galaxy_server_client/src/public_api.rs @@ -1,7 +1,7 @@ use anyhow::{Context as _, Result}; -use serde::de::DeserializeOwned; use galaxy_core::channel::ChannelState; use galaxy_core::errors::{ErrorExt, register_error}; +use serde::de::DeserializeOwned; use crate::base_client::{AmbientHeaderPolicy, BaseClient}; diff --git a/crates/galaxy_terminal/src/model/escape_sequences.rs b/crates/galaxy_terminal/src/model/escape_sequences.rs index c197f548..2ead6608 100644 --- a/crates/galaxy_terminal/src/model/escape_sequences.rs +++ b/crates/galaxy_terminal/src/model/escape_sequences.rs @@ -1,10 +1,8 @@ use std::collections::HashMap; -use galaxyui::keymap::Keystroke; -use galaxyui::platform::OperatingSystem; -use lazy_static::lazy_static; use galaxyui_core::keymap::Keystroke; use galaxyui_core::platform::OperatingSystem; +use lazy_static::lazy_static; use super::mouse::{MouseAction, MouseButton, MouseState}; use super::TermMode; diff --git a/crates/galaxy_terminal/src/model/grid/flat_storage/index_tests.rs b/crates/galaxy_terminal/src/model/grid/flat_storage/index_tests.rs index 8032c2b5..9ff2429b 100644 --- a/crates/galaxy_terminal/src/model/grid/flat_storage/index_tests.rs +++ b/crates/galaxy_terminal/src/model/grid/flat_storage/index_tests.rs @@ -291,6 +291,10 @@ fn test_cell_type() { } mod offset_point_conversion { + use string_offset::ByteOffset; + + use crate::model::grid::FlatStorage; + use crate::model::Point; #[test] fn test_normal_cell() { diff --git a/crates/galaxy_terminal/src/model/indexing.rs b/crates/galaxy_terminal/src/model/indexing.rs index 32199eb4..5d9a1759 100644 --- a/crates/galaxy_terminal/src/model/indexing.rs +++ b/crates/galaxy_terminal/src/model/indexing.rs @@ -4,9 +4,8 @@ use std::cmp::Ordering; use std::fmt; use std::ops::{Add, AddAssign, Range, Sub, SubAssign}; -use galaxyui::units::Lines; -use serde::{Deserialize, Serialize}; use galaxyui_core::units::Lines; +use serde::{Deserialize, Serialize}; use super::grid::Dimensions; diff --git a/crates/galaxy_util/src/path.rs b/crates/galaxy_util/src/path.rs index f50991c7..2a6ca559 100644 --- a/crates/galaxy_util/src/path.rs +++ b/crates/galaxy_util/src/path.rs @@ -571,7 +571,6 @@ pub fn to_relative_path(is_wsl: bool, absolute_path: &Path, cwd: &Path) -> Optio // On Windows, check if paths are on different drives #[cfg(windows)] { - let abs_drive = absolute_path.components().next().and_then(|c| match c { Component::Prefix(prefix) => Some(prefix.kind()), _ => None, diff --git a/crates/galaxy_util/src/path_tests.rs b/crates/galaxy_util/src/path_tests.rs index 0151c348..e042a3b1 100644 --- a/crates/galaxy_util/src/path_tests.rs +++ b/crates/galaxy_util/src/path_tests.rs @@ -205,7 +205,6 @@ fn test_to_relative_path() { #[test] fn test_normalize_relative_path_for_glob() { - assert_eq!( normalize_relative_path_for_glob(Path::new("app/src/main.rs")), "app/src/main.rs" diff --git a/crates/galaxyui/examples/animated_images/root_view.rs b/crates/galaxyui/examples/animated_images/root_view.rs index d3bd6610..ea3442c6 100644 --- a/crates/galaxyui/examples/animated_images/root_view.rs +++ b/crates/galaxyui/examples/animated_images/root_view.rs @@ -1,9 +1,9 @@ -use instant::Instant; use galaxyui::assets::asset_cache::AssetSource; use galaxyui::elements::{ CacheOption, ConstrainedBox, CrossAxisAlignment, Flex, Image, ParentElement, Shrinkable, Stack, }; use galaxyui::{AppContext, Element, Entity, TypedActionView, View}; +use instant::Instant; pub struct RootView { animation_start_time: Instant, diff --git a/crates/galaxyui/examples/autotracking/root_view.rs b/crates/galaxyui/examples/autotracking/root_view.rs index dcb7c20a..f82312ff 100644 --- a/crates/galaxyui/examples/autotracking/root_view.rs +++ b/crates/galaxyui/examples/autotracking/root_view.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{ Align, Border, ChildView, Container, CornerRadius, DispatchEventResult, EventHandler, Flex, ParentElement, Radius, Rect, Stack, Text, @@ -8,6 +7,7 @@ use galaxyui::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, Tracked, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; pub fn init(ctx: &mut AppContext) { ctx.add_singleton_model(|_| Settings { diff --git a/crates/galaxyui/examples/blur/root_view.rs b/crates/galaxyui/examples/blur/root_view.rs index 270752bc..94c8362b 100644 --- a/crates/galaxyui/examples/blur/root_view.rs +++ b/crates/galaxyui/examples/blur/root_view.rs @@ -1,7 +1,6 @@ -use galaxyui::{elements::Rect, AppContext, Element, Entity, TypedActionView, View}; -use pathfinder_color::ColorU; use galaxyui::elements::Rect; use galaxyui::{AppContext, Element, Entity, TypedActionView, View}; +use pathfinder_color::ColorU; pub struct BlurredView {} diff --git a/crates/galaxyui/examples/draggable/root_view.rs b/crates/galaxyui/examples/draggable/root_view.rs index 1e1f5034..98f81e27 100644 --- a/crates/galaxyui/examples/draggable/root_view.rs +++ b/crates/galaxyui/examples/draggable/root_view.rs @@ -1,13 +1,13 @@ use std::any::Any; -use pathfinder_color::ColorU; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxyui::elements::{ AcceptedByDropTarget, Align, ConstrainedBox, Container, DragAxis, Draggable, DraggableState, DropTarget, DropTargetData, ParentElement, Rect, Stack, }; use galaxyui::{AppContext, Element, Entity, TypedActionView, View}; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; #[derive(Default)] pub struct RootView { diff --git a/crates/galaxyui/examples/example-black-background-box/root_view.rs b/crates/galaxyui/examples/example-black-background-box/root_view.rs index 4fc7d87a..c3c52e61 100644 --- a/crates/galaxyui/examples/example-black-background-box/root_view.rs +++ b/crates/galaxyui/examples/example-black-background-box/root_view.rs @@ -1,7 +1,6 @@ -use galaxyui::{elements::Rect, AppContext, Element, Entity, TypedActionView, View}; -use pathfinder_color::ColorU; use galaxyui::elements::Rect; use galaxyui::{AppContext, Element, Entity, TypedActionView, View}; +use pathfinder_color::ColorU; pub struct RootView {} diff --git a/crates/galaxyui/examples/formatted-text/root_view.rs b/crates/galaxyui/examples/formatted-text/root_view.rs index dbaf808d..d409174a 100644 --- a/crates/galaxyui/examples/formatted-text/root_view.rs +++ b/crates/galaxyui/examples/formatted-text/root_view.rs @@ -1,6 +1,5 @@ //! A UI sample demonstrating how the SelectableArea element can be used. -use markdown_parser::{parse_markdown, FormattedTextFragment, FormattedTextLine}; use galaxyui::color::ColorU; use galaxyui::elements::{ Align, ChildView, ConstrainedBox, Flex, FormattedTextElement, HeadingFontSizeMultipliers, @@ -12,6 +11,7 @@ use galaxyui::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use markdown_parser::{parse_markdown, FormattedTextFragment, FormattedTextLine}; pub struct RootView { sub_view: ViewHandle, diff --git a/crates/galaxyui/examples/frame-capture-test/root_view.rs b/crates/galaxyui/examples/frame-capture-test/root_view.rs index f96365da..6a91691c 100644 --- a/crates/galaxyui/examples/frame-capture-test/root_view.rs +++ b/crates/galaxyui/examples/frame-capture-test/root_view.rs @@ -1,8 +1,6 @@ use std::sync::{Arc, Mutex}; use std::time::{SystemTime, UNIX_EPOCH}; -use image::ImageEncoder; -use pathfinder_color::ColorU; use galaxyui::elements::{ Align, ConstrainedBox, Container, DispatchEventResult, EventHandler, Padding, ParentElement, Rect, Stack, Text, @@ -12,6 +10,8 @@ use galaxyui::platform::CapturedFrame; use galaxyui::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use image::ImageEncoder; +use pathfinder_color::ColorU; #[derive(Clone, Debug)] pub enum RootViewAction { diff --git a/crates/galaxyui/examples/image/root_view.rs b/crates/galaxyui/examples/image/root_view.rs index c64464db..b219a0cc 100644 --- a/crates/galaxyui/examples/image/root_view.rs +++ b/crates/galaxyui/examples/image/root_view.rs @@ -1,9 +1,9 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{ CacheOption, ConstrainedBox, Flex, Icon, Image, MainAxisAlignment, MainAxisSize, ParentElement, Rect, Stack, }; use galaxyui::{AppContext, Element, Entity, TypedActionView, View}; +use pathfinder_color::ColorU; pub struct RootView {} diff --git a/crates/galaxyui/examples/manual-scrolling/root_view.rs b/crates/galaxyui/examples/manual-scrolling/root_view.rs index 3975c59f..75353857 100644 --- a/crates/galaxyui/examples/manual-scrolling/root_view.rs +++ b/crates/galaxyui/examples/manual-scrolling/root_view.rs @@ -1,12 +1,3 @@ -use galaxyui::elements::new_scrollable::AxisConfiguration; -use galaxyui::elements::new_scrollable::ClippedAxisConfiguration; -use galaxyui::elements::new_scrollable::DualAxisConfig; -use galaxyui::elements::new_scrollable::NewScrollableElement; -use galaxyui::elements::new_scrollable::ScrollableAppearance; -use galaxyui::elements::new_scrollable::ScrollableAxis; -use galaxyui::elements::Axis; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxyui::color::ColorU; use galaxyui::elements::new_scrollable::{ AxisConfiguration, ClippedAxisConfiguration, DualAxisConfig, NewScrollableElement, @@ -19,6 +10,8 @@ use galaxyui::elements::{ use galaxyui::keymap::FixedBinding; use galaxyui::units::Pixels; use galaxyui::{AppContext, Element, Entity, TypedActionView, View, ViewContext, ViewHandle}; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::{vec2f, Vector2F}; pub fn init(ctx: &mut AppContext) { use galaxyui::keymap::macros::*; diff --git a/crates/galaxyui/examples/resizable/main.rs b/crates/galaxyui/examples/resizable/main.rs index f4920520..5abf709b 100644 --- a/crates/galaxyui/examples/resizable/main.rs +++ b/crates/galaxyui/examples/resizable/main.rs @@ -1,5 +1,6 @@ -use anyhow::{anyhow, Result}; use std::borrow::Cow; + +use anyhow::{anyhow, Result}; pub mod root_view; extern crate galaxyui; diff --git a/crates/galaxyui/examples/scrolling/main.rs b/crates/galaxyui/examples/scrolling/main.rs index f4920520..5abf709b 100644 --- a/crates/galaxyui/examples/scrolling/main.rs +++ b/crates/galaxyui/examples/scrolling/main.rs @@ -1,5 +1,6 @@ -use anyhow::{anyhow, Result}; use std::borrow::Cow; + +use anyhow::{anyhow, Result}; pub mod root_view; extern crate galaxyui; diff --git a/crates/galaxyui/examples/shadows/root_view.rs b/crates/galaxyui/examples/shadows/root_view.rs index 0c2132e3..b1a3ebce 100644 --- a/crates/galaxyui/examples/shadows/root_view.rs +++ b/crates/galaxyui/examples/shadows/root_view.rs @@ -1,10 +1,10 @@ -use pathfinder_geometry::vector::vec2f; use galaxyui::color::ColorU; use galaxyui::elements::{ Align, ConstrainedBox, Container, CornerRadius, DropShadow, Flex, ParentElement, Radius, Rect, Shrinkable, }; use galaxyui::{AppContext, Element, Entity, TypedActionView, View}; +use pathfinder_geometry::vector::vec2f; pub struct RootView; diff --git a/crates/galaxyui/examples/slider/main.rs b/crates/galaxyui/examples/slider/main.rs index f4920520..5abf709b 100644 --- a/crates/galaxyui/examples/slider/main.rs +++ b/crates/galaxyui/examples/slider/main.rs @@ -1,5 +1,6 @@ -use anyhow::{anyhow, Result}; use std::borrow::Cow; + +use anyhow::{anyhow, Result}; pub mod root_view; extern crate galaxyui; diff --git a/crates/galaxyui/examples/slider/root_view.rs b/crates/galaxyui/examples/slider/root_view.rs index 50662a49..da196d57 100644 --- a/crates/galaxyui/examples/slider/root_view.rs +++ b/crates/galaxyui/examples/slider/root_view.rs @@ -1,9 +1,9 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{Align, Container}; use galaxyui::presenter::ChildView; use galaxyui::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui::ui_components::slider::{Slider, SliderStateHandle}; use galaxyui::{AppContext, Element, Entity, TypedActionView, View, ViewContext, ViewHandle}; +use pathfinder_color::ColorU; /// Renders a center-aligned slider component against a black background. When the slider is /// dragged, the updated value is printed to stdout. diff --git a/crates/galaxyui/examples/table-sample/main.rs b/crates/galaxyui/examples/table-sample/main.rs index 75add097..aa0dbdac 100644 --- a/crates/galaxyui/examples/table-sample/main.rs +++ b/crates/galaxyui/examples/table-sample/main.rs @@ -5,10 +5,9 @@ use pathfinder_geometry::vector::vec2f; pub mod root_view; extern crate galaxyui; -use galaxyui::{platform, platform::WindowBounds, AssetProvider}; -use rust_embed::RustEmbed; use galaxyui::platform::WindowBounds; use galaxyui::{platform, AssetProvider}; +use rust_embed::RustEmbed; #[derive(Clone, Copy, RustEmbed)] #[folder = "examples/assets"] diff --git a/crates/galaxyui/examples/table-sample/root_view.rs b/crates/galaxyui/examples/table-sample/root_view.rs index 45394e23..73cfa63c 100644 --- a/crates/galaxyui/examples/table-sample/root_view.rs +++ b/crates/galaxyui/examples/table-sample/root_view.rs @@ -1,6 +1,5 @@ use std::sync::{Arc, Mutex}; -use image::ImageEncoder; use galaxyui::color::ColorU; use galaxyui::elements::{ ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container, Empty, Fill, Flex, @@ -16,6 +15,7 @@ use galaxyui::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, WindowId, }; +use image::ImageEncoder; use crate::CaptureConfig; diff --git a/crates/galaxyui/examples/typed_actions/root_view.rs b/crates/galaxyui/examples/typed_actions/root_view.rs index 1fcc4c7d..13762fd4 100644 --- a/crates/galaxyui/examples/typed_actions/root_view.rs +++ b/crates/galaxyui/examples/typed_actions/root_view.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxyui::elements::{Align, ConstrainedBox, ParentElement, Rect, Stack, Text}; use galaxyui::fonts::FamilyId; use galaxyui::keymap::FixedBinding; @@ -7,6 +6,7 @@ use galaxyui::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; // We could initiate global action and bindings here. pub fn init(ctx: &mut AppContext) { diff --git a/crates/galaxyui/src/fonts/mod.rs b/crates/galaxyui/src/fonts/mod.rs index 7930fe59..b963ed90 100644 --- a/crates/galaxyui/src/fonts/mod.rs +++ b/crates/galaxyui/src/fonts/mod.rs @@ -6,8 +6,8 @@ pub mod font_kit; #[path = "text_layout_tests.rs"] mod text_layout_tests; +pub use galaxyui_core::fonts::*; #[cfg(all(test, target_os = "macos"))] pub(crate) use text_layout_tests::collect_line_caret_position_starts; #[cfg(test)] pub(crate) use text_layout_tests::{collect_glyph_indices, init_fonts}; -pub use galaxyui_core::fonts::*; diff --git a/crates/galaxyui/src/platform/mac/app.rs b/crates/galaxyui/src/platform/mac/app.rs index b78350df..fd3648d6 100644 --- a/crates/galaxyui/src/platform/mac/app.rs +++ b/crates/galaxyui/src/platform/mac/app.rs @@ -5,11 +5,6 @@ use std::path::PathBuf; use cocoa::base::id; use futures_util::future::LocalBoxFuture; -use objc::runtime::{Object, Sel, BOOL, NO, YES}; -use objc2::rc::{autoreleasepool, Retained}; -use objc2::{msg_send, AnyThread, MainThreadMarker}; -use objc2_app_kit::{NSAlert, NSApplication, NSImage, NSRunningApplication}; -use objc2_foundation::{NSArray, NSData, NSString, NSUInteger, NSURL}; use galaxyui_core::assets::AssetProvider; use galaxyui_core::integration::TestDriver; use galaxyui_core::keymap::{Keystroke, Trigger}; @@ -20,6 +15,11 @@ use galaxyui_core::platform::app::{ use galaxyui_core::platform::menu::{Menu, MenuBar}; use galaxyui_core::platform::{self, FilePickerCallback, SaveFilePickerCallback}; use galaxyui_core::{AppContext, Event}; +use objc::runtime::{Object, Sel, BOOL, NO, YES}; +use objc2::rc::{autoreleasepool, Retained}; +use objc2::{msg_send, AnyThread, MainThreadMarker}; +use objc2_app_kit::{NSAlert, NSApplication, NSImage, NSRunningApplication}; +use objc2_foundation::{NSArray, NSData, NSString, NSUInteger, NSURL}; use super::keycode::{Keycode, CMD_KEY, CONTROL_KEY, OPTION_KEY, SHIFT_KEY}; use super::menus::{make_dock_menu, make_main_menu}; diff --git a/crates/galaxyui/src/platform/mac/clipboard.rs b/crates/galaxyui/src/platform/mac/clipboard.rs index b3cb3648..8bdda82e 100644 --- a/crates/galaxyui/src/platform/mac/clipboard.rs +++ b/crates/galaxyui/src/platform/mac/clipboard.rs @@ -4,10 +4,10 @@ use std::slice; use anyhow::Result; use cocoa::base::id; +use galaxyui_core::clipboard::{ClipboardContent, ImageData}; use objc2::rc::Retained; use objc2_app_kit::{NSPasteboard, NSPasteboardTypeHTML, NSPasteboardTypeString}; use objc2_foundation::{ns_string, NSArray, NSData, NSString}; -use galaxyui_core::clipboard::{ClipboardContent, ImageData}; extern "C" { fn getFilePathsFromPasteboard() -> id; diff --git a/crates/galaxyui/src/platform/mac/delegate.rs b/crates/galaxyui/src/platform/mac/delegate.rs index 5c1f90c9..4b210936 100644 --- a/crates/galaxyui/src/platform/mac/delegate.rs +++ b/crates/galaxyui/src/platform/mac/delegate.rs @@ -4,10 +4,6 @@ use std::sync::Arc; use anyhow::Result; use cocoa::base::{id, nil, BOOL, NO, YES}; -use objc2::{msg_send, MainThreadMarker}; -use objc2_app_kit::{NSApplication, NSCursor, NSRequestUserAttentionType}; -use objc2_av_foundation::{AVAuthorizationStatus, AVCaptureDevice, AVMediaTypeAudio}; -use objc2_foundation::NSUInteger; use galaxyui_core::accessibility::AccessibilityContent; use galaxyui_core::clipboard::InMemoryClipboard; use galaxyui_core::keymap::Keystroke; @@ -20,6 +16,10 @@ use galaxyui_core::platform::{ SendNotificationErrorCallback, TerminationMode, }; use galaxyui_core::{platform, ApplicationBundleInfo, WindowId}; +use objc2::{msg_send, MainThreadMarker}; +use objc2_app_kit::{NSApplication, NSCursor, NSRequestUserAttentionType}; +use objc2_av_foundation::{AVAuthorizationStatus, AVCaptureDevice, AVMediaTypeAudio}; +use objc2_foundation::NSUInteger; use super::app::create_native_platform_modal; use super::keycode::{modifier_code, Keycode}; diff --git a/crates/galaxyui/src/platform/mac/event.rs b/crates/galaxyui/src/platform/mac/event.rs index 31bdc5e7..112eef20 100644 --- a/crates/galaxyui/src/platform/mac/event.rs +++ b/crates/galaxyui/src/platform/mac/event.rs @@ -1,13 +1,13 @@ use std::ffi::CStr; use cocoa::base::id; -use objc2_app_kit::{NSEvent, NSEventModifierFlags, NSEventType}; -use objc2_foundation::NSUInteger; -use pathfinder_geometry::vector::vec2f; use galaxyui_core::event::{KeyEventDetails, ModifiersState}; use galaxyui_core::keymap::Keystroke; use galaxyui_core::platform::keyboard::{KeyCode, PhysicalKey}; use galaxyui_core::Event; +use objc2_app_kit::{NSEvent, NSEventModifierFlags, NSEventType}; +use objc2_foundation::NSUInteger; +use pathfinder_geometry::vector::vec2f; use super::keycode::{scancode_to_physicalkey, Keycode}; use super::utils::unicode_char_to_key; diff --git a/crates/galaxyui/src/platform/mac/fonts.rs b/crates/galaxyui/src/platform/mac/fonts.rs index 670b6faf..50438720 100644 --- a/crates/galaxyui/src/platform/mac/fonts.rs +++ b/crates/galaxyui/src/platform/mac/fonts.rs @@ -24,9 +24,9 @@ use font_kit::font::Font; use font_kit::loaders::core_text::NativeFont; use futures::future::BoxFuture; use futures::FutureExt as _; +use galaxyui_core::fonts::canvas::RasterFormat; use galaxyui_core::fonts::{ - canvas::RasterFormat, FamilyId, FontId, FontInfo, GlyphId, Metrics, Properties, - RasterizedGlyph, SubpixelAlignment, + FamilyId, FontId, FontInfo, GlyphId, Metrics, Properties, RasterizedGlyph, SubpixelAlignment, }; use galaxyui_core::platform::{self, FontDB as _, LineStyle, TextLayoutSystem}; use galaxyui_core::rendering; diff --git a/crates/galaxyui/src/platform/mac/keycode.rs b/crates/galaxyui/src/platform/mac/keycode.rs index fb3128cf..307f2410 100644 --- a/crates/galaxyui/src/platform/mac/keycode.rs +++ b/crates/galaxyui/src/platform/mac/keycode.rs @@ -2,10 +2,10 @@ use std::slice; use cocoa::base::{id, BOOL}; use cocoa::foundation::NSUInteger; -use objc2::rc::Retained; -use objc2_foundation::{NSArray, NSNumber, NSString}; use galaxyui_core::keymap::Keystroke; use galaxyui_core::platform::keyboard::{KeyCode, NativeKeyCode, PhysicalKey}; +use objc2::rc::Retained; +use objc2_foundation::{NSArray, NSNumber, NSString}; // Modifier key mask values for the Carbon API. pub const CMD_KEY: u16 = 256; diff --git a/crates/galaxyui/src/platform/mac/menus.rs b/crates/galaxyui/src/platform/mac/menus.rs index d3d70041..2c7a1b57 100644 --- a/crates/galaxyui/src/platform/mac/menus.rs +++ b/crates/galaxyui/src/platform/mac/menus.rs @@ -5,6 +5,12 @@ use std::ffi::c_void; use std::rc::Rc; use cocoa::base::{id, nil}; +use galaxyui_core::actions::StandardAction; +use galaxyui_core::keymap::Keystroke; +use galaxyui_core::platform::menu::{ + ItemTriggeredCallback, Menu, MenuBar, MenuItem, MenuItemProperties, MenuItemPropertyChanges, + UpdateMenuItemCallback, +}; use lazy_static::lazy_static; use objc2::rc::{autoreleasepool, Retained}; use objc2::runtime::Sel; @@ -20,12 +26,6 @@ use objc2_app_kit::{ NSUpArrowFunctionKey, }; use objc2_foundation::{ns_string, NSInteger, NSString}; -use galaxyui_core::actions::StandardAction; -use galaxyui_core::keymap::Keystroke; -use galaxyui_core::platform::menu::{ - ItemTriggeredCallback, Menu, MenuBar, MenuItem, MenuItemProperties, MenuItemPropertyChanges, - UpdateMenuItemCallback, -}; use super::app::callback_dispatcher; diff --git a/crates/galaxyui/src/platform/mac/notification.rs b/crates/galaxyui/src/platform/mac/notification.rs index 0f67709d..c4a66854 100644 --- a/crates/galaxyui/src/platform/mac/notification.rs +++ b/crates/galaxyui/src/platform/mac/notification.rs @@ -1,10 +1,10 @@ use anyhow::{anyhow, Result}; use chrono::DateTime; use cocoa::base::id; -use objc2_foundation::NSUInteger; use galaxyui_core::notification::{ NotificationResponse, NotificationSendError, RequestPermissionsOutcome, }; +use objc2_foundation::NSUInteger; use super::utils::nsstring_as_str; diff --git a/crates/galaxyui/src/platform/mac/rendering/metal/renderer.rs b/crates/galaxyui/src/platform/mac/rendering/metal/renderer.rs index 61a8abdb..00268b58 100644 --- a/crates/galaxyui/src/platform/mac/rendering/metal/renderer.rs +++ b/crates/galaxyui/src/platform/mac/rendering/metal/renderer.rs @@ -7,6 +7,11 @@ use std::ptr::NonNull; use std::sync::Once; use dispatch2::DispatchData; +use galaxyui_core::fonts::{self, canvas, RasterizedGlyph, SubpixelAlignment}; +use galaxyui_core::platform::CapturedFrame; +use galaxyui_core::rendering::texture_cache::TextureCache; +use galaxyui_core::rendering::{self}; +use galaxyui_core::scene::{CornerRadius, GlyphFade, GlyphKey, Icon, Image, Layer, Scene}; use objc2::rc::Retained; use objc2::runtime::ProtocolObject; use objc2_foundation::NSString; @@ -22,11 +27,6 @@ use objc2_quartz_core::CAMetalDrawable; use pathfinder_color::{ColorF, ColorU}; use pathfinder_geometry::rect::{RectF, RectI}; use pathfinder_geometry::vector::{vec2f, Vector2F}; -use galaxyui_core::fonts::{self, canvas, RasterizedGlyph, SubpixelAlignment}; -use galaxyui_core::platform::CapturedFrame; -use galaxyui_core::rendering::texture_cache::TextureCache; -use galaxyui_core::rendering::{self}; -use galaxyui_core::scene::{CornerRadius, GlyphFade, GlyphKey, Icon, Image, Layer, Scene}; use super::frame_capture::capture_frame; use crate::platform::mac::rendering::renderer::Device; diff --git a/crates/galaxyui/src/platform/mac/rendering/metal/renderer_manager.rs b/crates/galaxyui/src/platform/mac/rendering/metal/renderer_manager.rs index 5c8d69e5..76cec678 100644 --- a/crates/galaxyui/src/platform/mac/rendering/metal/renderer_manager.rs +++ b/crates/galaxyui/src/platform/mac/rendering/metal/renderer_manager.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; +use galaxyui_core::rendering; use objc2::runtime::ProtocolObject; use objc2_metal::{MTLDevice, MTLPixelFormat}; -use galaxyui_core::rendering; use crate::platform::mac::rendering::metal::renderer::Renderer; diff --git a/crates/galaxyui/src/platform/mac/rendering/renderer.rs b/crates/galaxyui/src/platform/mac/rendering/renderer.rs index 2403cf96..31a64dab 100644 --- a/crates/galaxyui/src/platform/mac/rendering/renderer.rs +++ b/crates/galaxyui/src/platform/mac/rendering/renderer.rs @@ -1,11 +1,11 @@ -use objc2::rc::Retained; -use objc2::runtime::ProtocolObject; -use objc2_app_kit::{NSView, NSWindow}; -use objc2_metal::MTLDevice; use galaxyui_core::rendering::{ GPUBackend, GPUDeviceInfo, GPUDeviceType, GPUPowerPreference, OnGPUDeviceSelected, }; use galaxyui_core::{fonts, Scene}; +use objc2::rc::Retained; +use objc2::runtime::ProtocolObject; +use objc2_app_kit::{NSView, NSWindow}; +use objc2_metal::MTLDevice; use crate::platform::mac::rendering::is_integrated_gpu; use crate::platform::mac::window::WindowState; diff --git a/crates/galaxyui/src/platform/mac/text_layout.rs b/crates/galaxyui/src/platform/mac/text_layout.rs index 2e79e2c5..e94b19de 100644 --- a/crates/galaxyui/src/platform/mac/text_layout.rs +++ b/crates/galaxyui/src/platform/mac/text_layout.rs @@ -27,17 +27,16 @@ use core_text::run::{CTRun, CTRunRef}; use core_text::string_attributes::{ kCTFontAttributeName, kCTKernAttributeName, kCTParagraphStyleAttributeName, }; -use itertools::Itertools; -use ordered_float::OrderedFloat; -use pathfinder_geometry::vector::vec2f; -use vec1::Vec1; - use galaxyui_core::fonts::GlyphId; -use galaxyui_core::platform::{CapturedFrame, LineStyle}; +use galaxyui_core::platform::LineStyle; use galaxyui_core::text_layout::{ CaretPosition, ClipConfig, Glyph, Line, Run, StyleAndFont, TextAlignment, TextBorder, TextFrame, TextStyle, }; +use itertools::Itertools; +use ordered_float::OrderedFloat; +use pathfinder_geometry::vector::vec2f; +use vec1::Vec1; use super::fonts::FontDB; use super::utils::{cg_color_to_color_u, color_u_to_cg_color}; diff --git a/crates/galaxyui/src/platform/mac/window.rs b/crates/galaxyui/src/platform/mac/window.rs index 81f51fb9..94f643d0 100644 --- a/crates/galaxyui/src/platform/mac/window.rs +++ b/crates/galaxyui/src/platform/mac/window.rs @@ -9,6 +9,18 @@ use std::time::Duration; use anyhow::{anyhow, Result}; use cocoa::base::id; +use galaxyui_core::accessibility::AccessibilityContent; +use galaxyui_core::actions::StandardAction; +use galaxyui_core::event::ModifiersState; +use galaxyui_core::platform::{ + self, file_picker, FilePickerCallback, FilePickerConfiguration, FullscreenState, + GraphicsBackend, TerminationMode, WindowBounds, WindowFocusBehavior, WindowOptions, + WindowStyle, +}; +use galaxyui_core::r#async::{executor, Timer}; +use galaxyui_core::rendering::GPUPowerPreference; +use galaxyui_core::windowing::WindowCallbacks; +use galaxyui_core::{DisplayId, DisplayIdx, Event, OptionalPlatformWindow, Scene, WindowId}; use instant::Instant; use num_traits::FromPrimitive; use objc::runtime::Object; @@ -23,18 +35,6 @@ use objc2_metal::{MTLCopyAllDevices, MTLCreateSystemDefaultDevice, MTLDevice}; use objc2_quartz_core::CAMetalLayer; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::{vec2f, Vector2F}; -use galaxyui_core::accessibility::AccessibilityContent; -use galaxyui_core::actions::StandardAction; -use galaxyui_core::event::ModifiersState; -use galaxyui_core::platform::{ - self, file_picker, FilePickerCallback, FilePickerConfiguration, FullscreenState, - GraphicsBackend, TerminationMode, WindowBounds, WindowFocusBehavior, WindowOptions, - WindowStyle, -}; -use galaxyui_core::r#async::{executor, Timer}; -use galaxyui_core::rendering::GPUPowerPreference; -use galaxyui_core::windowing::WindowCallbacks; -use galaxyui_core::{DisplayId, DisplayIdx, Event, OptionalPlatformWindow, Scene, WindowId}; use super::delegate::DispatchDelegate; use super::rendering::{self, is_integrated_gpu, Device, RendererManager}; diff --git a/crates/galaxyui/src/platform/wasm/mod.rs b/crates/galaxyui/src/platform/wasm/mod.rs index 810290bd..5361b9df 100644 --- a/crates/galaxyui/src/platform/wasm/mod.rs +++ b/crates/galaxyui/src/platform/wasm/mod.rs @@ -2,12 +2,12 @@ pub(crate) mod hidden_input; pub(crate) mod mobile_detection; pub(crate) mod soft_keyboard; +// Re-export the functions from the core crate. +pub use galaxyui_core::platform::wasm::*; use gloo::events::{EventListener, EventListenerOptions}; pub use hidden_input::{HiddenInput, HiddenInputEvent, InputCallback}; pub use mobile_detection::{is_mobile_device, is_mobile_user_agent}; pub use soft_keyboard::{SoftKeyboardInput, SoftKeyboardManager, SoftKeyboardState}; -// Re-export the functions from the core crate. -pub use galaxyui_core::platform::wasm::*; use wasm_bindgen::{JsCast, UnwrapThrowExt}; use super::KEYS_TO_IGNORE; diff --git a/crates/galaxyui/src/rendering/mod.rs b/crates/galaxyui/src/rendering/mod.rs index 43f0f190..f262e1dc 100644 --- a/crates/galaxyui/src/rendering/mod.rs +++ b/crates/galaxyui/src/rendering/mod.rs @@ -3,9 +3,9 @@ pub(crate) mod glyph_cache; #[cfg(wgpu)] pub mod wgpu; -pub(crate) use glyph_cache::{GlyphCache, GlyphRasterBoundsFn, RasterizeGlyphFn}; pub use galaxyui_core::rendering::*; use galaxyui_core::scene::Dash; +pub(crate) use glyph_cache::{GlyphCache, GlyphRasterBoundsFn, RasterizeGlyphFn}; /// Cache for the result of calling [`is_low_power_gpu_available`], as the /// check can be expensive. diff --git a/crates/galaxyui/src/rendering/wgpu/renderer/glyph.rs b/crates/galaxyui/src/rendering/wgpu/renderer/glyph.rs index 586dde3f..8738d928 100644 --- a/crates/galaxyui/src/rendering/wgpu/renderer/glyph.rs +++ b/crates/galaxyui/src/rendering/wgpu/renderer/glyph.rs @@ -295,6 +295,7 @@ impl Pipeline { mod shaders { use pathfinder_color::ColorU; + use pathfinder_geometry::rect::RectF; use crate::rendering::wgpu::shader_types::{ColorF, Vector4F}; diff --git a/crates/galaxyui/src/rendering/wgpu/shader_types.rs b/crates/galaxyui/src/rendering/wgpu/shader_types.rs index 700a6f55..76e9499c 100644 --- a/crates/galaxyui/src/rendering/wgpu/shader_types.rs +++ b/crates/galaxyui/src/rendering/wgpu/shader_types.rs @@ -1,3 +1,5 @@ +use std::mem; + use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectF; @@ -95,8 +97,6 @@ impl Vertex { const ATTRIBS: [wgpu::VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Float32x2]; pub(super) fn desc() -> wgpu::VertexBufferLayout<'static> { - use std::mem; - wgpu::VertexBufferLayout { array_stride: mem::size_of::() as wgpu::BufferAddress, step_mode: wgpu::VertexStepMode::Vertex, @@ -200,7 +200,6 @@ impl RectData { } pub(super) fn desc() -> wgpu::VertexBufferLayout<'static> { - wgpu::VertexBufferLayout { array_stride: mem::size_of::() as wgpu::BufferAddress, step_mode: wgpu::VertexStepMode::Instance, diff --git a/crates/galaxyui/src/windowing/winit/fonts.rs b/crates/galaxyui/src/windowing/winit/fonts.rs index a5ca215b..849285c0 100644 --- a/crates/galaxyui/src/windowing/winit/fonts.rs +++ b/crates/galaxyui/src/windowing/winit/fonts.rs @@ -24,6 +24,7 @@ use cosmic_text::{ use dashmap::mapref::entry::Entry; use dashmap::DashMap; use fontdb::Source; +use galaxyui_core::fonts::{Style, Weight}; use itertools::Itertools; use parking_lot::RwLock; use pathfinder_geometry::rect::{RectF, RectI}; @@ -31,7 +32,6 @@ use pathfinder_geometry::vector::{vec2f, vec2i, Vector2F, Vector2I}; use resvg::usvg::fontdb; use resvg::usvg::fontdb::Query; use vec1::Vec1; -use galaxyui_core::fonts::{Style, Weight}; #[cfg(target_os = "windows")] use windows::loader; diff --git a/crates/galaxyui_core/src/accessibility.rs b/crates/galaxyui_core/src/accessibility.rs index 6b2c716a..19aad9c0 100644 --- a/crates/galaxyui_core/src/accessibility.rs +++ b/crates/galaxyui_core/src/accessibility.rs @@ -274,3 +274,5 @@ impl From> for ActionAccessibilityContent { } } } + +pub type WarpA11yRole = GalaxyA11yRole; diff --git a/crates/galaxyui_core/src/elements/clipped.rs b/crates/galaxyui_core/src/elements/clipped.rs index 24056f78..ef325b94 100644 --- a/crates/galaxyui_core/src/elements/clipped.rs +++ b/crates/galaxyui_core/src/elements/clipped.rs @@ -97,5 +97,5 @@ impl Element for Clipped { } #[cfg(test)] -#[path = "clipped_tests.rs"] +#[path = "clipped_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/clipped_scrollable.rs b/crates/galaxyui_core/src/elements/clipped_scrollable.rs index 766c84b4..945b8df3 100644 --- a/crates/galaxyui_core/src/elements/clipped_scrollable.rs +++ b/crates/galaxyui_core/src/elements/clipped_scrollable.rs @@ -467,5 +467,5 @@ impl ScrollableElement for ClippedScrollable { } #[cfg(test)] -#[path = "clipped_scrollable_tests.rs"] +#[path = "clipped_scrollable_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/container.rs b/crates/galaxyui_core/src/elements/container.rs index 7f234fc1..592c66d5 100644 --- a/crates/galaxyui_core/src/elements/container.rs +++ b/crates/galaxyui_core/src/elements/container.rs @@ -445,5 +445,5 @@ impl SelectableElement for Container { } #[cfg(test)] -#[path = "container_tests.rs"] +#[path = "container_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/event_handler.rs b/crates/galaxyui_core/src/elements/event_handler.rs index ccbca694..a1ec5d52 100644 --- a/crates/galaxyui_core/src/elements/event_handler.rs +++ b/crates/galaxyui_core/src/elements/event_handler.rs @@ -367,5 +367,5 @@ impl Element for EventHandler { } #[cfg(test)] -#[path = "event_handler_tests.rs"] +#[path = "event_handler_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/flex/mod.rs b/crates/galaxyui_core/src/elements/flex/mod.rs index 7f6dd706..797cdf93 100644 --- a/crates/galaxyui_core/src/elements/flex/mod.rs +++ b/crates/galaxyui_core/src/elements/flex/mod.rs @@ -996,5 +996,5 @@ impl SelectableElement for Expanded { } #[cfg(test)] -#[path = "mod_tests.rs"] +#[path = "mod_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/flex/wrap.rs b/crates/galaxyui_core/src/elements/flex/wrap.rs index 6ed95a21..048479f0 100644 --- a/crates/galaxyui_core/src/elements/flex/wrap.rs +++ b/crates/galaxyui_core/src/elements/flex/wrap.rs @@ -605,5 +605,5 @@ impl RunBuilder { } #[cfg(test)] -#[path = "wrap_tests.rs"] +#[path = "wrap_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/formatted_text_element_tests.rs b/crates/galaxyui_core/src/elements/formatted_text_element_tests.rs index 857865bb..eea1bd68 100644 --- a/crates/galaxyui_core/src/elements/formatted_text_element_tests.rs +++ b/crates/galaxyui_core/src/elements/formatted_text_element_tests.rs @@ -1,24 +1,24 @@ -use super::{ - FormattedTextElement, FrameMouseHandlers, HeadingFontSizeMultipliers, HighlightedHyperlink, - HyperlinkSupport, LaidOutTextFrame, SecretRange, -}; -use crate::text::BlockHeaderSize; -use crate::{ - elements::{Point, SelectableElement, ZIndex}, - fonts::FamilyId, - text_layout::TextFrame, -}; -use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; -use pathfinder_color::ColorU; -use pathfinder_geometry::{rect::RectF, vector::vec2f}; use std::borrow::Cow; use std::cell::RefCell; use std::ops::Range; use std::rc::Rc; use std::sync::{Arc, Mutex}; + +use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; +use pathfinder_color::ColorU; +use pathfinder_geometry::rect::RectF; +use pathfinder_geometry::vector::vec2f; use string_offset::ByteOffset; -use super::apply_secret_replacements; +use super::{ + apply_secret_replacements, FormattedTextElement, FrameMouseHandlers, + HeadingFontSizeMultipliers, HighlightedHyperlink, HyperlinkSupport, LaidOutTextFrame, + SecretRange, +}; +use crate::elements::{Point, SelectableElement, ZIndex}; +use crate::fonts::FamilyId; +use crate::text::BlockHeaderSize; +use crate::text_layout::TextFrame; #[test] fn test_default_heading_font_size_multipliers() { diff --git a/crates/galaxyui_core/src/elements/hoverable.rs b/crates/galaxyui_core/src/elements/hoverable.rs index bccc7cf0..40362406 100644 --- a/crates/galaxyui_core/src/elements/hoverable.rs +++ b/crates/galaxyui_core/src/elements/hoverable.rs @@ -710,27 +710,24 @@ impl Element for Hoverable { // The double-clicked handler takes precendence. However, we should still fall back to the single-click handler // on a double-click if there's no double-click handler set. - if matches!(click_count, Some(2)) && self.double_click_handler.is_some() { - let handler = self - .double_click_handler - .as_mut() - .expect("handler should exist"); - handler(ctx, app, *position); - ctx.notify(); - return true; - } else if click_count.is_some() && self.click_handler.is_some() { - let handler = self.click_handler.as_mut().expect("handler should exist"); - handler(ctx, app, *position); - ctx.notify(); - return true; - } else if click_count.is_some() && self.click_with_modifiers_handler.is_some() { - let handler = self - .click_with_modifiers_handler - .as_mut() - .expect("handler should exist"); - handler(ctx, app, *position, *modifiers); - ctx.notify(); - return true; + if matches!(click_count, Some(2)) { + if let Some(handler) = self.double_click_handler.as_mut() { + handler(ctx, app, *position); + ctx.notify(); + return true; + } + } + if click_count.is_some() { + if let Some(handler) = self.click_handler.as_mut() { + handler(ctx, app, *position); + ctx.notify(); + return true; + } + if let Some(handler) = self.click_with_modifiers_handler.as_mut() { + handler(ctx, app, *position, *modifiers); + ctx.notify(); + return true; + } } } Event::MouseMoved { @@ -742,10 +739,8 @@ impl Element for Hoverable { return true; } } - Event::LeftMouseDragged { .. } => { - if self.suppress_drag && self.state().is_clicked() { - return true; - } + Event::LeftMouseDragged { .. } if self.suppress_drag && self.state().is_clicked() => { + return true; } _ => {} } @@ -828,5 +823,5 @@ impl SelectableElement for Hoverable { } #[cfg(test)] -#[path = "hoverable_tests.rs"] +#[path = "hoverable_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/live.rs b/crates/galaxyui_core/src/elements/live.rs new file mode 100644 index 00000000..15a1edfe --- /dev/null +++ b/crates/galaxyui_core/src/elements/live.rs @@ -0,0 +1,82 @@ +use std::time::Duration; + +use pathfinder_geometry::vector::Vector2F; + +use super::{ + AfterLayoutContext, AppContext, Element, EventContext, LayoutContext, PaintContext, Point, + SizeConstraint, +}; +use crate::event::DispatchedEvent; + +/// A wrapper element that triggers periodic repaints at a fixed interval. +/// +/// Wrap any child element in `LiveElement` to ensure the view repaints on a +/// timer, which is useful for content that changes over time (e.g. an elapsed +/// duration counter). The repaint cycle is self-sustaining: each `paint` call +/// schedules the next repaint. +pub struct LiveElement { + child: Box, + repaint_interval: Duration, + size: Option, + origin: Option, +} + +impl LiveElement { + pub fn new(child: Box, repaint_interval: Duration) -> Self { + Self { + child, + repaint_interval, + size: None, + origin: None, + } + } +} + +impl Element for LiveElement { + fn layout( + &mut self, + constraint: SizeConstraint, + ctx: &mut LayoutContext, + app: &AppContext, + ) -> Vector2F { + let size = self.child.layout(constraint, ctx, app); + self.size = Some(size); + size + } + + fn after_layout(&mut self, ctx: &mut AfterLayoutContext, app: &AppContext) { + self.child.after_layout(ctx, app); + } + + fn paint(&mut self, origin: Vector2F, ctx: &mut PaintContext, app: &AppContext) { + self.child.paint(origin, ctx, app); + self.origin = Some(Point::from_vec2f(origin, ctx.scene.z_index())); + ctx.repaint_after(self.repaint_interval); + } + + fn size(&self) -> Option { + self.size + } + + fn origin(&self) -> Option { + self.origin + } + + fn dispatch_event( + &mut self, + event: &DispatchedEvent, + ctx: &mut EventContext, + app: &AppContext, + ) -> bool { + self.child.dispatch_event(event, ctx, app) + } + + fn as_selectable_element(&self) -> Option<&dyn super::SelectableElement> { + self.child.as_selectable_element() + } + + #[cfg(any(test, feature = "test-util"))] + fn debug_text_content(&self) -> Option { + self.child.debug_text_content() + } +} diff --git a/crates/galaxyui_core/src/elements/mod.rs b/crates/galaxyui_core/src/elements/mod.rs index 92aea39e..39047e85 100644 --- a/crates/galaxyui_core/src/elements/mod.rs +++ b/crates/galaxyui_core/src/elements/mod.rs @@ -9,8 +9,6 @@ mod debug; mod dismiss; mod drag; -#[cfg(feature = "tui")] -pub mod tui; pub mod drag_resize; mod empty; mod event_handler; @@ -20,6 +18,7 @@ mod hoverable; mod icon; mod image; mod list; +mod live; mod min_size; pub mod new_scrollable; mod percentage; @@ -33,6 +32,8 @@ mod size_constraint_switch; mod stack; pub mod table; mod text; +#[cfg(feature = "tui")] +pub mod tui; mod uniform_list; mod viewported_list; @@ -61,6 +62,7 @@ pub use hoverable::*; pub use icon::*; pub use image::*; pub use list::*; +pub use live::*; pub use min_size::*; pub use new_scrollable::NewScrollable; use pathfinder_color::ColorU; diff --git a/crates/galaxyui_core/src/elements/new_scrollable/mod.rs b/crates/galaxyui_core/src/elements/new_scrollable/mod.rs index c3ed5041..c4971ad2 100644 --- a/crates/galaxyui_core/src/elements/new_scrollable/mod.rs +++ b/crates/galaxyui_core/src/elements/new_scrollable/mod.rs @@ -1586,5 +1586,5 @@ impl ClippedScrollStateHandle { } #[cfg(test)] -#[path = "scrollable_tests.rs"] +#[path = "scrollable_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/new_scrollable/util.rs b/crates/galaxyui_core/src/elements/new_scrollable/util.rs index 23e9072f..57845304 100644 --- a/crates/galaxyui_core/src/elements/new_scrollable/util.rs +++ b/crates/galaxyui_core/src/elements/new_scrollable/util.rs @@ -157,5 +157,5 @@ pub(crate) fn scroll_delta_for_axis( } #[cfg(test)] -#[path = "util_tests.rs"] +#[path = "util_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/new_scrollable/util_test.rs b/crates/galaxyui_core/src/elements/new_scrollable/util_test.rs new file mode 100644 index 00000000..9adb6bdf --- /dev/null +++ b/crates/galaxyui_core/src/elements/new_scrollable/util_test.rs @@ -0,0 +1,154 @@ +use super::*; + +#[test] +fn test_scroll_delta_for_axis_fully_into_view() { + let mode = ScrollToPositionMode::FullyIntoView; + assert_eq!( + scroll_delta_for_axis( + Axis::Horizontal, + RectF::new(vec2f(100., 0.), vec2f(250., 250.)), + RectF::new(vec2f(400., 50.), vec2f(50., 50.)), + mode, + ), + 100. + ); + assert_eq!( + scroll_delta_for_axis( + Axis::Horizontal, + RectF::new(vec2f(200., 0.), vec2f(250., 250.)), + RectF::new(vec2f(100., 50.), vec2f(50., 50.)), + mode, + ), + -100. + ); + assert_eq!( + scroll_delta_for_axis( + Axis::Horizontal, + RectF::new(vec2f(100., 0.), vec2f(250., 250.)), + RectF::new(vec2f(325., 50.), vec2f(50., 50.)), + mode, + ), + 25. + ); + assert_eq!( + scroll_delta_for_axis( + Axis::Horizontal, + RectF::new(vec2f(100., 0.), vec2f(250., 250.)), + RectF::new(vec2f(150., 50.), vec2f(50., 50.)), + mode, + ), + 0. + ); + assert_eq!( + scroll_delta_for_axis( + Axis::Horizontal, + RectF::new(vec2f(100., 0.), vec2f(250., 250.)), + RectF::new(vec2f(50., 50.), vec2f(350., 50.)), + mode, + ), + 0. + ); +} + +#[test] +fn test_scroll_delta_for_axis_top_into_view() { + let mode = ScrollToPositionMode::TopIntoView; + + // --- Element LARGER than the viewport --- + + // Element taller than viewport, below viewport: align top with + // viewport top. + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 100.), vec2f(250., 250.)), + RectF::new(vec2f(50., 400.), vec2f(50., 300.)), + mode, + ), + 300. + ); + + // Element taller than viewport, above viewport: align top with + // viewport top. + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 200.), vec2f(250., 250.)), + RectF::new(vec2f(50., 100.), vec2f(50., 300.)), + mode, + ), + -100. + ); + + // Element taller than viewport, top at viewport top: align top + // (delta = 0). + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 100.), vec2f(250., 250.)), + RectF::new(vec2f(50., 100.), vec2f(50., 300.)), + mode, + ), + 0. + ); + + // Element taller than viewport, top visible but bottom extends + // past: align top with viewport top (shows max content from top). + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 100.), vec2f(250., 250.)), + RectF::new(vec2f(50., 200.), vec2f(50., 300.)), + mode, + ), + 100. + ); + + // Element taller than viewport, spans entire viewport (top above, + // bottom below): align top with viewport top. + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 100.), vec2f(250., 250.)), + RectF::new(vec2f(50., 50.), vec2f(50., 400.)), + mode, + ), + -50. + ); + + // --- Element FITS in the viewport (delegates to FullyIntoView) --- + + // Small element below viewport: scroll down (bottom to viewport + // bottom). + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 100.), vec2f(250., 250.)), + RectF::new(vec2f(50., 400.), vec2f(50., 50.)), + mode, + ), + 100. + ); + + // Small element above viewport: scroll up (top to viewport top). + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 200.), vec2f(250., 250.)), + RectF::new(vec2f(50., 100.), vec2f(50., 50.)), + mode, + ), + -100. + ); + + // Small element fully visible: no scroll. + assert_eq!( + scroll_delta_for_axis( + Axis::Vertical, + RectF::new(vec2f(0., 100.), vec2f(250., 250.)), + RectF::new(vec2f(50., 150.), vec2f(50., 50.)), + mode, + ), + 0. + ); +} diff --git a/crates/galaxyui_core/src/elements/scrollable.rs b/crates/galaxyui_core/src/elements/scrollable.rs index 487eef8b..009f77b0 100644 --- a/crates/galaxyui_core/src/elements/scrollable.rs +++ b/crates/galaxyui_core/src/elements/scrollable.rs @@ -683,5 +683,5 @@ impl Element for Scrollable { } #[cfg(test)] -#[path = "scrollable_tests.rs"] +#[path = "scrollable_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/size_constraint_switch.rs b/crates/galaxyui_core/src/elements/size_constraint_switch.rs index cebdb097..f6a92408 100644 --- a/crates/galaxyui_core/src/elements/size_constraint_switch.rs +++ b/crates/galaxyui_core/src/elements/size_constraint_switch.rs @@ -149,5 +149,5 @@ impl Element for SizeConstraintSwitch { } #[cfg(test)] -#[path = "size_constraint_switch_tests.rs"] +#[path = "size_constraint_switch_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/stack/mod.rs b/crates/galaxyui_core/src/elements/stack/mod.rs index b4e67795..77e3cc60 100644 --- a/crates/galaxyui_core/src/elements/stack/mod.rs +++ b/crates/galaxyui_core/src/elements/stack/mod.rs @@ -441,5 +441,5 @@ impl Extend> for Stack { } #[cfg(test)] -#[path = "mod_tests.rs"] +#[path = "mod_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/stack/offset_positioning.rs b/crates/galaxyui_core/src/elements/stack/offset_positioning.rs index 25d5109d..9058d34c 100644 --- a/crates/galaxyui_core/src/elements/stack/offset_positioning.rs +++ b/crates/galaxyui_core/src/elements/stack/offset_positioning.rs @@ -887,5 +887,5 @@ impl Default for PositioningAxis { } #[cfg(test)] -#[path = "offset_positioning_tests.rs"] +#[path = "offset_positioning_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/text.rs b/crates/galaxyui_core/src/elements/text.rs index 971902e9..7c593ae0 100644 --- a/crates/galaxyui_core/src/elements/text.rs +++ b/crates/galaxyui_core/src/elements/text.rs @@ -1436,5 +1436,5 @@ impl PartialClickableElement for Text { } #[cfg(test)] -#[path = "text_tests.rs"] +#[path = "text_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/elements/uniform_list.rs b/crates/galaxyui_core/src/elements/uniform_list.rs index 6564d68f..e2191b80 100644 --- a/crates/galaxyui_core/src/elements/uniform_list.rs +++ b/crates/galaxyui_core/src/elements/uniform_list.rs @@ -326,5 +326,5 @@ where } #[cfg(test)] -#[path = "uniform_list_tests.rs"] +#[path = "uniform_list_test.rs"] mod tests; diff --git a/crates/galaxyui_core/src/keymap_tests.rs b/crates/galaxyui_core/src/keymap_tests.rs index b541558c..832190e5 100644 --- a/crates/galaxyui_core/src/keymap_tests.rs +++ b/crates/galaxyui_core/src/keymap_tests.rs @@ -437,6 +437,7 @@ fn test_binding_description_eq_ignores_dynamic_override() { mod settings_value_tests { use settings_value::SettingsValue; + use crate::keymap::Keystroke; #[test] fn test_keystroke_to_file_value_is_normalized_string() { diff --git a/crates/galaxyui_core/src/platform/mod.rs b/crates/galaxyui_core/src/platform/mod.rs index 0601aa1c..51a959b6 100644 --- a/crates/galaxyui_core/src/platform/mod.rs +++ b/crates/galaxyui_core/src/platform/mod.rs @@ -14,8 +14,6 @@ use std::path::Path; use std::rc::Rc; use std::sync::Arc; -use galaxy_util::path::ShellFamily; - use anyhow::Result; pub use app::AppCallbacks; use async_task::Runnable; @@ -24,6 +22,7 @@ pub use file_picker::{ FilePickerCallback, FilePickerConfiguration, FileType, SaveFilePickerCallback, SaveFilePickerConfiguration, }; +use galaxy_util::path::ShellFamily; use lazy_static::lazy_static; use pathfinder_geometry::rect::{RectF, RectI}; use pathfinder_geometry::vector::{Vector2F, Vector2I}; diff --git a/crates/galaxyui_extras/src/user_preferences/toml_backed_tests.rs b/crates/galaxyui_extras/src/user_preferences/toml_backed_tests.rs index 7e1c1e2d..ff522258 100644 --- a/crates/galaxyui_extras/src/user_preferences/toml_backed_tests.rs +++ b/crates/galaxyui_extras/src/user_preferences/toml_backed_tests.rs @@ -1,5 +1,6 @@ use toml_edit::Item; +use super::super::UserPreferences; use super::*; #[test] @@ -220,7 +221,6 @@ fn test_write_and_read_with_hierarchy() { #[test] fn test_write_and_read_struct_value() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("test_settings.toml"); let (prefs, _) = TomlBackedUserPreferences::new(file_path.clone()); @@ -256,7 +256,6 @@ fn test_write_and_read_struct_value() { #[test] fn test_new_with_invalid_toml_returns_error_and_recovers_on_reload() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("broken_settings.toml"); @@ -296,7 +295,6 @@ fn test_new_with_invalid_toml_returns_error_and_recovers_on_reload() { #[test] fn test_writes_inhibited_when_file_initially_broken() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("broken_settings.toml"); @@ -335,7 +333,6 @@ fn test_writes_inhibited_when_file_initially_broken() { #[test] fn test_string_value_for_numeric_setting_reads_as_json_string() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("test_settings.toml"); @@ -366,7 +363,6 @@ fn test_string_value_for_numeric_setting_reads_as_json_string() { #[test] fn test_remove_with_hierarchy() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("test_settings.toml"); let (prefs, _) = TomlBackedUserPreferences::new(file_path); @@ -392,7 +388,6 @@ fn test_remove_with_hierarchy() { #[test] fn test_per_key_write_inhibition_preserves_value_in_file() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("settings.toml"); @@ -435,7 +430,6 @@ fn test_per_key_write_inhibition_preserves_value_in_file() { #[test] fn test_per_key_write_inhibition_blocks_remove() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("settings.toml"); std::fs::write(&file_path, "[font]\nfont_size = \"abc\"\n").unwrap(); @@ -457,7 +451,6 @@ fn test_per_key_write_inhibition_blocks_remove() { #[test] fn test_reload_clears_per_key_inhibitions() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("settings.toml"); std::fs::write(&file_path, "[font]\nfont_size = \"abc\"\n").unwrap(); @@ -483,7 +476,6 @@ fn test_reload_clears_per_key_inhibitions() { #[test] fn test_clear_all_write_inhibitions() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("settings.toml"); std::fs::write(&file_path, "[font]\nfont_size = \"abc\"\nfont_name = 123\n").unwrap(); @@ -583,7 +575,6 @@ fn write_and_read_file( value_json: &str, max_table_depth: Option, ) -> String { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("settings.toml"); let (prefs, _) = TomlBackedUserPreferences::new(file_path.clone()); diff --git a/crates/graphql/src/api/queries/get_conversation_usage.rs b/crates/graphql/src/api/queries/get_conversation_usage.rs index 95b48d90..c5c0278c 100644 --- a/crates/graphql/src/api/queries/get_conversation_usage.rs +++ b/crates/graphql/src/api/queries/get_conversation_usage.rs @@ -195,6 +195,10 @@ impl From<&ConversationUsageMetadata> for persistence::model::ConversationUsageM token_usage: convert_token_usage(&gql.warp_token_usage, &gql.byok_token_usage), tool_usage_metadata: (&gql.tool_usage_metadata).into(), context_window_segments: gql.context_window_segments.iter().map(Into::into).collect(), + total_cache_read_tokens: 0, + total_cache_write_tokens: 0, + total_cache_miss_tokens: 0, + total_cost_cents: 0.0, } } } diff --git a/crates/graphql/src/client.rs b/crates/graphql/src/client.rs index 01333f58..dd05cbe0 100644 --- a/crates/graphql/src/client.rs +++ b/crates/graphql/src/client.rs @@ -1,14 +1,13 @@ use std::borrow::Cow; use cynic::{GraphQlResponse, QueryFragment, QueryVariables}; -use galaxy_core::{channel::ChannelState, operating_system_info::OperatingSystemInfo}; +use galaxy_core::channel::ChannelState; +use galaxy_core::operating_system_info::OperatingSystemInfo; use http::StatusCode; use instant::Duration; use reqwest::header::CONTENT_TYPE; use serde::de::DeserializeOwned; use serde::Serialize; -use galaxy_core::channel::ChannelState; -use galaxy_core::operating_system_info::OperatingSystemInfo; use crate::error::{UserFacingError, UserFacingErrorInterface}; use crate::request_context::{ClientContext, OsContext, RequestContext}; diff --git a/crates/http_server/src/lib.rs b/crates/http_server/src/lib.rs index ba6b06df..be05910a 100644 --- a/crates/http_server/src/lib.rs +++ b/crates/http_server/src/lib.rs @@ -1,8 +1,8 @@ use std::net::SocketAddr; +use galaxy_core::channel::{Channel, ChannelState}; use galaxyui_core::{Entity, ModelContext, SingletonEntity}; use tower_http::trace::TraceLayer; -use galaxy_core::channel::{Channel, ChannelState}; // Spells "Warp" - should hopefully not conflict with other ports. // Does not conflict with known ports on https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers diff --git a/crates/input_classifier/src/bin/evaluate.rs b/crates/input_classifier/src/bin/evaluate.rs index 110288c9..0b004541 100644 --- a/crates/input_classifier/src/bin/evaluate.rs +++ b/crates/input_classifier/src/bin/evaluate.rs @@ -66,10 +66,10 @@ fn get_binary_confidence_color(is_correct: bool, is_low_confidence: bool) -> Str "\x1b[31m".to_string() // Red for incorrect } } +use galaxy_completer::ParsedTokensSnapshot; +use galaxy_completer::util::parse_current_commands_and_tokens; #[cfg(feature = "onnx")] use input_classifier::{OnnxClassifier, OnnxModel}; -use warp_completer::ParsedTokensSnapshot; -use warp_completer::util::parse_current_commands_and_tokens; #[cfg(feature = "onnx")] fn default_onnx_model() -> Option { cfg_if::cfg_if! { diff --git a/crates/input_classifier/src/heuristic_classifier/mod.rs b/crates/input_classifier/src/heuristic_classifier/mod.rs index 2b3b1285..68c56b69 100644 --- a/crates/input_classifier/src/heuristic_classifier/mod.rs +++ b/crates/input_classifier/src/heuristic_classifier/mod.rs @@ -64,8 +64,7 @@ impl InputClassifier for HeuristicClassifier { ); } - let result = self - .classify_input(input, context) + self.classify_input(input, context) .await .map(|result| InputClassificationResult::new(result.to_input_type(), result.source)) .unwrap_or(InputClassificationResult::new( @@ -115,15 +114,7 @@ async fn natural_language_detection_heuristic( include_last_token: bool, ) -> ClassificationResult { let source = InputClassifierDecisionSource::InputClassifierFallbackHeuristic; - let word_tokens_count = word_tokens.len(); - - let min_token_length = if matches!(current_input_type, InputType::AI) { - MINIMUM_COMMAND_DETECTION_TOKEN_LENGTH - } else { - MINIMUM_NATURAL_LANGUAGE_DETECTION_TOKEN_LENGTH - }; - - if min_token_length > word_tokens_count as u8 { + if input.buffer_text.len() < MINIMUM_CLASSIFICATION_CHAR_LENGTH { return ClassificationResult::pure_shell(source); } diff --git a/crates/input_classifier/src/heuristic_classifier/mod_tests.rs b/crates/input_classifier/src/heuristic_classifier/mod_tests.rs index 27ca46f5..44631a16 100644 --- a/crates/input_classifier/src/heuristic_classifier/mod_tests.rs +++ b/crates/input_classifier/src/heuristic_classifier/mod_tests.rs @@ -105,6 +105,12 @@ fn test_input_detection() { detected_input_type(&classifier, token, &context).await, InputType::AI ); + // Test case for "Can you review this code base" + let token = mock_parsed_input_token("Can you review this code base".to_string()).await; + assert_eq!( + detected_input_type(&classifier, token, &context).await, + InputType::AI + ); // Short queries with contractions should be parsed as AI input. let mut token = mock_parsed_input_token("What's the reason".to_string()).await; token.parsed_tokens[0].token_description = None; diff --git a/crates/input_classifier/src/test_utils.rs b/crates/input_classifier/src/test_utils.rs index c9c8d62e..5ce7c479 100644 --- a/crates/input_classifier/src/test_utils.rs +++ b/crates/input_classifier/src/test_utils.rs @@ -1,9 +1,9 @@ use std::collections::HashSet; use std::sync::Arc; -use smol_str::SmolStr; use galaxy_completer::completer::{GeneratorContext, PathCompletionContext}; use galaxy_completer::signatures::CommandRegistry; +use smol_str::SmolStr; /// An implementation of `CompletionContext` for testing purposes. pub struct CompletionContext { diff --git a/crates/input_classifier/src/util.rs b/crates/input_classifier/src/util.rs index 566aad75..458d3512 100644 --- a/crates/input_classifier/src/util.rs +++ b/crates/input_classifier/src/util.rs @@ -59,14 +59,14 @@ pub fn is_prefix_of_natural_language_word(input: &str) -> bool { /// nld_heuristic_v2: rm check_if_token_has_shell_syntax and pin threshold to be 1 for all input pub async fn is_likely_shell_command( input: &ParsedTokensSnapshot, - _word_tokens_count: usize, + word_tokens_count: usize, ) -> bool { const YIELD_BATCH_SIZE: usize = 5; let use_nld_heuristic_v2 = cfg!(feature = "nld_heuristic_v2"); let mut likely_command_token_count = 0; let total_token_count = input.parsed_tokens.len(); - let mut is_first_token_command = false; + let is_first_token_command = is_installed_binary(input); log::debug!( "is_likely_shell_command start: use_nld_heuristic_v2={use_nld_heuristic_v2}, total_token_count={total_token_count}, word_tokens_count={word_tokens_count}" ); diff --git a/crates/integration/Cargo.toml b/crates/integration/Cargo.toml index 7692a215..332b46ab 100644 --- a/crates/integration/Cargo.toml +++ b/crates/integration/Cargo.toml @@ -38,7 +38,7 @@ strum.workspace = true strum_macros.workspace = true sum_tree.workspace = true version-compare.workspace = true -galaxy = { workspace = true, features = ["integration_tests"] } +warp = { workspace = true, features = ["integration_tests"] } galaxy_cli = { workspace = true, features = ["integration_tests"] } galaxy_core.workspace = true warp-command-signatures.workspace = true @@ -65,5 +65,5 @@ nix = { workspace = true, features = ["user", "signal"] } [features] run_on_linux = [] -drag_tabs_to_windows = ["galaxy/drag_tabs_to_windows"] +drag_tabs_to_windows = ["warp/drag_tabs_to_windows"] default = ["run_on_linux"] diff --git a/crates/integration/src/bin/integration.rs b/crates/integration/src/bin/integration.rs index e40dc736..c2a2a78d 100644 --- a/crates/integration/src/bin/integration.rs +++ b/crates/integration/src/bin/integration.rs @@ -69,7 +69,7 @@ pub fn main() -> Result<()> { // GUI application), do so. This must occur before init_logging, as the // terminal server sets up its own logger, and attempting to set a second // logger leads to a panic. - galaxy::terminal::local_tty::server::run_terminal_server(args); + warp::terminal::local_tty::server::run_terminal_server(args); return Ok(()); } // This is a catch-all to handle the plugin host, which the integration test crate doesn't have a feature flag for. @@ -107,7 +107,7 @@ pub fn main() -> Result<()> { } #[cfg_attr(not(unix), allow(unreachable_code))] - galaxy::run_integration_test(driver) + warp::run_integration_test(driver) } /// Type of a function that produces an integration test builder. diff --git a/crates/integration/src/builder.rs b/crates/integration/src/builder.rs index 66d520b5..4ab48f70 100644 --- a/crates/integration/src/builder.rs +++ b/crates/integration/src/builder.rs @@ -180,7 +180,7 @@ impl Builder { // Set the DISABLE_SAVE_ENV_VAR to make sure we don't write any keybinding changes to the // filesystem - utils.set_env(galaxy::keyboard::DISABLE_SAVE_ENV_VAR, Some("true")); + utils.set_env(warp::keyboard::DISABLE_SAVE_ENV_VAR, Some("true")); // On Ubuntu (and possibly other Linux distros), a message is // printed out during shell initialization telling the user how to @@ -200,7 +200,7 @@ impl Builder { // As part of initializing the test driver, $HOME gets set to a unique // temporary directory. We can now construct a file containing any // initial user preferences that are needed for the test. - let file_path = galaxy::settings::user_preferences_file_path(); + let file_path = warp::settings::user_preferences_file_path(); // Use println because logging may not have been initialized yet. println!("Initializing preferences file at {file_path:?}"); let prefs = match FileBackedUserPreferences::new(file_path.clone()) { diff --git a/crates/integration/src/lib.rs b/crates/integration/src/lib.rs index 7a97346d..6b2b4c4b 100644 --- a/crates/integration/src/lib.rs +++ b/crates/integration/src/lib.rs @@ -6,5 +6,5 @@ pub mod user_defaults; pub mod util; pub use builder::Builder; -pub use warp::integration_testing::view_getters; pub use galaxyui_core::integration::TestStep; +pub use warp::integration_testing::view_getters; diff --git a/crates/integration/src/test.rs b/crates/integration/src/test.rs index b937ada8..0fd68718 100644 --- a/crates/integration/src/test.rs +++ b/crates/integration/src/test.rs @@ -53,6 +53,16 @@ pub use code_review::*; pub use ctrl_d::*; pub use file_tree::*; use float_cmp::assert_approx_eq; +use galaxyui_core::event::KeyState; +use galaxyui_core::integration::{AssertionOutcome, StepData, TestStep}; +use galaxyui_core::keymap::{Keystroke, PerPlatformKeystroke, Trigger}; +use galaxyui_core::platform::keyboard::KeyCode; +use galaxyui_core::platform::{OperatingSystem, TerminationMode}; +use galaxyui_core::units::Lines; +use galaxyui_core::windowing::WindowManager; +use galaxyui_core::{ + async_assert, async_assert_eq, AssetProvider, Event, SingletonEntity, UpdateView, ViewHandle, +}; pub use goto_line::*; pub use history::*; pub use input::*; @@ -180,16 +190,6 @@ use warp::workspace::{ Workspace, WorkspaceAction, NEW_SESSION_MENU_BUTTON_POSITION_ID, NEW_TAB_BUTTON_POSITION_ID, }; use warp::{cmd_or_ctrl_shift, AgentModeEntrypoint}; -use galaxyui_core::event::KeyState; -use galaxyui_core::integration::{AssertionOutcome, StepData, TestStep}; -use galaxyui_core::keymap::{Keystroke, PerPlatformKeystroke, Trigger}; -use galaxyui_core::platform::keyboard::KeyCode; -use galaxyui_core::platform::{OperatingSystem, TerminationMode}; -use galaxyui_core::units::Lines; -use galaxyui_core::windowing::WindowManager; -use galaxyui_core::{ - async_assert, async_assert_eq, AssetProvider, Event, SingletonEntity, UpdateView, ViewHandle, -}; pub use websockets::*; pub use workflows::*; pub use workspace::*; @@ -3826,9 +3826,7 @@ pub fn test_open_new_tab_with_specific_shell_from_new_session_menu() -> Builder let mut builder = new_builder() .set_should_run_test(|| cfg!(windows)) .with_step(wait_until_bootstrapped_single_pane_for_tab(0)); - let mut tab_index = 1; - - for (shell, test_command) in test_cases { + for (tab_index, (shell, test_command)) in (1..).zip(test_cases) { let expected = regex::Regex::new(format!("{}$", shell.name()).as_str()).expect("regex should compile"); builder = builder @@ -3847,7 +3845,6 @@ pub fn test_open_new_tab_with_specific_shell_from_new_session_menu() -> Builder ExpectedExitStatus::Success, expected, )); - tab_index += 1; } builder } @@ -6792,7 +6789,7 @@ pub fn test_agent_mode_pane_minimum_size() -> Builder { f32, pane_width - AGENT_MODE_PANE_DEFAULT_MINIMUM_WIDTH, 0., - epsilon = 4. + epsilon = 8. ); AssertionOutcome::Success diff --git a/crates/integration/src/test/agent_mode.rs b/crates/integration/src/test/agent_mode.rs index 3e34aa01..8b2b0072 100644 --- a/crates/integration/src/test/agent_mode.rs +++ b/crates/integration/src/test/agent_mode.rs @@ -5,6 +5,9 @@ use std::collections::HashMap; use std::path::PathBuf; use std::time::Duration; +use galaxyui_core::integration::TestStep; +use galaxyui_core::text::SelectionType; +use galaxyui_core::{async_assert, Event, SingletonEntity}; use lazy_static::lazy_static; use pathfinder_geometry::vector::{vec2f, Vector2F}; use settings::ToggleableSetting; @@ -19,9 +22,6 @@ use warp::integration_testing::terminal::{ use warp::integration_testing::view_getters::single_terminal_view_for_tab; use warp::settings::SelectionSettings; use warp_multi_agent_api as api; -use galaxyui_core::integration::TestStep; -use galaxyui_core::text::SelectionType; -use galaxyui_core::{async_assert, Event, SingletonEntity}; use super::new_builder; use crate::util::skip_if_powershell_core_2303; diff --git a/crates/integration/src/test/ai_assistant.rs b/crates/integration/src/test/ai_assistant.rs index 4e03d81a..3b13019c 100644 --- a/crates/integration/src/test/ai_assistant.rs +++ b/crates/integration/src/test/ai_assistant.rs @@ -1,3 +1,4 @@ +use galaxyui_core::async_assert; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::util::ExpectedExitStatus; use warp::integration_testing::terminal::{ @@ -5,7 +6,6 @@ use warp::integration_testing::terminal::{ wait_until_bootstrapped_single_pane_for_tab, }; use warp::integration_testing::view_getters::ai_assistant_panel_view; -use galaxyui_core::async_assert; use super::new_builder; use crate::Builder; diff --git a/crates/integration/src/test/block_filtering.rs b/crates/integration/src/test/block_filtering.rs index 3027e3af..1109800e 100644 --- a/crates/integration/src/test/block_filtering.rs +++ b/crates/integration/src/test/block_filtering.rs @@ -1,3 +1,4 @@ +use galaxyui_core::{async_assert, async_assert_eq}; use warp::cmd_or_ctrl_shift; use warp::integration_testing::terminal::util::current_shell_starter_and_version; use warp::integration_testing::terminal::{ @@ -10,7 +11,6 @@ use warp::terminal::model::index::Point; use warp::terminal::model::terminal_model::{BlockIndex, WithinBlock, WithinModel}; use warp::terminal::shell::ShellType; use warp::terminal::GridType; -use galaxyui_core::{async_assert, async_assert_eq}; use super::new_builder; use crate::test::integration_testing::block_filtering::{ diff --git a/crates/integration/src/test/bootstrapping.rs b/crates/integration/src/test/bootstrapping.rs index 677ae44e..650df993 100644 --- a/crates/integration/src/test/bootstrapping.rs +++ b/crates/integration/src/test/bootstrapping.rs @@ -1,5 +1,8 @@ //! Integration tests for bootstrapping logic. +use galaxyui_core::clipboard::ClipboardContent; +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert, async_assert_eq, ViewHandle}; use settings::Setting as _; use version_compare::Cmp; use warp::cmd_or_ctrl_shift; @@ -22,9 +25,6 @@ use warp::integration_testing::view_getters::{ use warp::terminal::session_settings::HonorPS1; use warp::terminal::shell::{self, ShellType}; use warp::workspace::Workspace; -use galaxyui_core::clipboard::ClipboardContent; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert, async_assert_eq, ViewHandle}; use super::{new_builder, Builder}; use crate::util::{write_all_rc_files_for_test, write_rc_files_for_test, ShellRcType}; diff --git a/crates/integration/src/test/code_review.rs b/crates/integration/src/test/code_review.rs index ad9eb606..38404778 100644 --- a/crates/integration/src/test/code_review.rs +++ b/crates/integration/src/test/code_review.rs @@ -3,6 +3,8 @@ use std::path::{Path, PathBuf}; use std::time::Duration; use command::blocking::Command; +use galaxyui_core::integration::{AssertionCallback, TestStep}; +use galaxyui_core::{async_assert, App, WindowId}; use warp::features::FeatureFlag; use warp::integration_testing::code_review::{ assert_code_review_anchor, assert_code_review_line_text, assert_code_review_loaded, @@ -13,8 +15,6 @@ use warp::integration_testing::code_review::{ use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for_tab; use warp::integration_testing::view_getters::{single_terminal_view_for_tab, workspace_view}; use warp::workspace::WorkspaceAction; -use galaxyui_core::integration::{AssertionCallback, TestStep}; -use galaxyui_core::{async_assert, App, WindowId}; use super::new_builder; use crate::util::write_all_rc_files_for_test; diff --git a/crates/integration/src/test/ctrl_d.rs b/crates/integration/src/test/ctrl_d.rs index aa65d2b6..f3857734 100644 --- a/crates/integration/src/test/ctrl_d.rs +++ b/crates/integration/src/test/ctrl_d.rs @@ -1,5 +1,6 @@ //! Integration tests for CTRL-D / EOT behaviour. +use galaxyui_core::integration::TestStep; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::util::current_shell_starter_and_version; use warp::integration_testing::terminal::{ @@ -13,7 +14,6 @@ use warp::terminal::model::bootstrap::BootstrapStage; use warp::terminal::shell::ShellType; use warp::terminal::TerminalView; use warp::workspace::Workspace; -use galaxyui_core::integration::TestStep; use super::{new_builder, Builder}; use crate::util::write_all_rc_files_for_test; diff --git a/crates/integration/src/test/file_tree.rs b/crates/integration/src/test/file_tree.rs index 4bfe7c23..2f91dab2 100644 --- a/crates/integration/src/test/file_tree.rs +++ b/crates/integration/src/test/file_tree.rs @@ -1,11 +1,11 @@ +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert, async_assert_eq, App}; use regex::Regex; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::tab::assert_pane_title; use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for_tab; use warp::integration_testing::view_getters::{pane_group_view, workspace_view}; use warp::workspace::WorkspaceAction; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert, async_assert_eq, App}; use super::{new_builder, Builder}; use crate::util::write_all_rc_files_for_test; diff --git a/crates/integration/src/test/goto_line.rs b/crates/integration/src/test/goto_line.rs index bc61b8e6..b727b99c 100644 --- a/crates/integration/src/test/goto_line.rs +++ b/crates/integration/src/test/goto_line.rs @@ -1,3 +1,4 @@ +use galaxyui_core::{async_assert_eq, App}; use regex::Regex; use warp::integration_testing::goto_line::{ assert_code_editor_line_numbers, assert_cursor_at_line, assert_cursor_at_line_and_column, @@ -10,7 +11,6 @@ use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for use warp::integration_testing::view_getters::{pane_group_view, workspace_view}; use warp::settings::CodeEditorLineNumberMode; use warp::workspace::WorkspaceAction; -use galaxyui_core::{async_assert_eq, App}; use super::{new_builder, Builder}; use crate::util::write_all_rc_files_for_test; diff --git a/crates/integration/src/test/history.rs b/crates/integration/src/test/history.rs index 49d8ac8f..8807e9c5 100644 --- a/crates/integration/src/test/history.rs +++ b/crates/integration/src/test/history.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use galaxyui_core::{async_assert, ViewHandle}; use settings::Setting as _; use warp::integration_testing::command_search::{ assert_command_search_has_results, assert_command_search_is_open, @@ -17,7 +18,6 @@ use warp::sqlite_testing::set_user_and_hostname_for_commands; use warp::terminal::input::Input; use warp::terminal::model::session::get_local_hostname; use warp::terminal::shell::ShellType; -use galaxyui_core::{async_assert, ViewHandle}; use super::{new_builder, TEST_ONLY_ASSETS}; use crate::util::{get_local_user, write_histfiles_for_test}; diff --git a/crates/integration/src/test/input.rs b/crates/integration/src/test/input.rs index 35f9bb2a..72cdd982 100644 --- a/crates/integration/src/test/input.rs +++ b/crates/integration/src/test/input.rs @@ -1,5 +1,7 @@ use std::time::Duration; +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert_eq, Event}; use warp::features::FeatureFlag; use warp::integration_testing::clipboard::write_to_clipboard; use warp::integration_testing::input::{ @@ -18,8 +20,6 @@ use warp::integration_testing::view_getters::{ single_input_view_for_tab, single_terminal_view_for_tab, }; use warp::terminal::shell::ShellType; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert_eq, Event}; use super::new_builder; use crate::Builder; diff --git a/crates/integration/src/test/keyboard_protocol.rs b/crates/integration/src/test/keyboard_protocol.rs index 969b7eb2..f9d57dfa 100644 --- a/crates/integration/src/test/keyboard_protocol.rs +++ b/crates/integration/src/test/keyboard_protocol.rs @@ -1,5 +1,10 @@ use std::time::Duration; +use galaxyui_core::event::{KeyEventDetails, KeyState}; +use galaxyui_core::integration::TestStep; +use galaxyui_core::keymap::Keystroke; +use galaxyui_core::platform::keyboard::KeyCode; +use galaxyui_core::{async_assert, Event}; use warp::features::FeatureFlag; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::{ @@ -7,11 +12,6 @@ use warp::integration_testing::terminal::{ wait_until_bootstrapped_single_pane_for_tab, }; use warp::integration_testing::view_getters::single_terminal_view_for_tab; -use galaxyui_core::event::{KeyEventDetails, KeyState}; -use galaxyui_core::integration::TestStep; -use galaxyui_core::keymap::Keystroke; -use galaxyui_core::platform::keyboard::KeyCode; -use galaxyui_core::{async_assert, Event}; use super::new_builder; use crate::Builder; @@ -48,8 +48,10 @@ fn wait_for_protocol_enabled() -> TestStep { fn assert_output_contains( expected: &'static str, description: &'static str, -) -> impl FnMut(&mut galaxyui_core::App, galaxyui_core::WindowId) -> galaxyui_core::integration::AssertionOutcome -{ +) -> impl FnMut( + &mut galaxyui_core::App, + galaxyui_core::WindowId, +) -> galaxyui_core::integration::AssertionOutcome { move |app, window_id| { let terminal_view = single_terminal_view_for_tab(app, window_id, 0); terminal_view.read(app, |view, _ctx| { diff --git a/crates/integration/src/test/launch_configs.rs b/crates/integration/src/test/launch_configs.rs index 52fc20c5..a4402099 100644 --- a/crates/integration/src/test/launch_configs.rs +++ b/crates/integration/src/test/launch_configs.rs @@ -1,6 +1,8 @@ use std::path::PathBuf; use std::time::Duration; +use galaxyui_core::integration::{AssertionOutcome, TestStep}; +use galaxyui_core::{async_assert, ModelHandle}; use warp::features::FeatureFlag; use warp::integration_testing::pane_group::assert_focused_pane_index; use warp::integration_testing::settings::set_window_custom_size; @@ -16,8 +18,6 @@ use warp::search::command_palette::launch_config; use warp::search::data_source::Query; use warp::search::SyncDataSource; use warp::workspace::NEW_TAB_BUTTON_POSITION_ID; -use galaxyui_core::integration::{AssertionOutcome, TestStep}; -use galaxyui_core::{async_assert, ModelHandle}; use super::{assert_approx_eq, new_builder, TEST_ONLY_ASSETS}; use crate::Builder; @@ -98,9 +98,9 @@ pub fn test_with_launch_config() -> Builder { move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: - galaxy::launch_configs::launch_config::make_mock_single_window_launch_config(), + warp::launch_configs::launch_config::make_mock_single_window_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: false, }, @@ -158,10 +158,10 @@ pub fn test_open_launch_config_from_add_tab_menu_legacy() -> Builder { } pub fn test_launch_config_single_child_branch() -> Builder { - use galaxy::launch_configs::launch_config::{ + use galaxyui_core::actions::StandardAction; + use warp::launch_configs::launch_config::{ LaunchConfig, PaneMode, PaneTemplateType, SplitDirection, TabTemplate, WindowTemplate, }; - use galaxyui_core::actions::StandardAction; /// Create a launch config that has a branch with a single child fn create_launch_config() -> LaunchConfig { @@ -195,7 +195,7 @@ pub fn test_launch_config_single_child_branch() -> Builder { .with_action(move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: create_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: false, @@ -227,9 +227,9 @@ pub fn test_open_launch_config_with_custom_size() -> Builder { move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: - galaxy::launch_configs::launch_config::make_mock_single_window_launch_config(), + warp::launch_configs::launch_config::make_mock_single_window_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: false, }, @@ -267,9 +267,9 @@ pub fn test_open_launch_config_in_active_window() -> Builder { move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: - galaxy::launch_configs::launch_config::make_mock_single_window_launch_config(), + warp::launch_configs::launch_config::make_mock_single_window_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: true, }, @@ -288,7 +288,7 @@ pub fn test_open_launch_config_in_active_window() -> Builder { } pub fn test_with_launch_config_with_active_tab_index() -> Builder { - use galaxy::launch_configs::launch_config::{ + use warp::launch_configs::launch_config::{ LaunchConfig, PaneMode, PaneTemplateType, SplitDirection, TabTemplate, WindowTemplate, }; @@ -330,7 +330,7 @@ pub fn test_with_launch_config_with_active_tab_index() -> Builder { move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: create_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: false, @@ -347,7 +347,7 @@ pub fn test_with_launch_config_with_active_tab_index() -> Builder { } pub fn test_with_launch_config_with_active_pane() -> Builder { - use galaxy::launch_configs::launch_config::{ + use warp::launch_configs::launch_config::{ LaunchConfig, PaneMode, PaneTemplateType, SplitDirection, TabTemplate, WindowTemplate, }; @@ -407,7 +407,7 @@ pub fn test_with_launch_config_with_active_pane() -> Builder { move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: create_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: false, @@ -425,7 +425,7 @@ pub fn test_with_launch_config_with_active_pane() -> Builder { } pub fn test_with_launch_config_with_no_active_pane() -> Builder { - use galaxy::launch_configs::launch_config::{ + use warp::launch_configs::launch_config::{ LaunchConfig, PaneMode, PaneTemplateType, SplitDirection, TabTemplate, WindowTemplate, }; @@ -485,7 +485,7 @@ pub fn test_with_launch_config_with_no_active_pane() -> Builder { move |app, _, _| { app.dispatch_global_action( "root_view:open_launch_config", - galaxy::root_view::OpenLaunchConfigArg { + warp::root_view::OpenLaunchConfigArg { launch_config: create_launch_config(), ui_location: get_launch_config_ui_location(), open_in_active_window: false, diff --git a/crates/integration/src/test/notebooks.rs b/crates/integration/src/test/notebooks.rs index 03b6c254..dcc50b1c 100644 --- a/crates/integration/src/test/notebooks.rs +++ b/crates/integration/src/test/notebooks.rs @@ -1,3 +1,4 @@ +use galaxyui_core::integration::TestStep; use warp::cmd_or_ctrl_shift; use warp::features::FeatureFlag; use warp::integration_testing::command_palette::open_command_palette_and_run_action; @@ -15,7 +16,6 @@ use warp::integration_testing::terminal::{ }; use warp::integration_testing::view_getters::terminal_view; use warp::integration_testing::window::{add_and_save_window, close_window, save_active_window_id}; -use galaxyui_core::integration::TestStep; use super::{new_builder, Builder}; diff --git a/crates/integration/src/test/pane_restoration.rs b/crates/integration/src/test/pane_restoration.rs index ecbf71ed..09860abc 100644 --- a/crates/integration/src/test/pane_restoration.rs +++ b/crates/integration/src/test/pane_restoration.rs @@ -201,7 +201,7 @@ pub fn test_undo_close_grace_period_cleanup() -> Builder { .with_step( new_step_with_default_assertions("Check pane count before undo close") .add_assertion(move |app, window_id| { - let workspace_view = galaxy::integration_testing::view_getters::workspace_view(app, window_id); + let workspace_view = warp::integration_testing::view_getters::workspace_view(app, window_id); let initial_pane_count = workspace_view.read(app, |workspace, ctx| { let pane_group_view = workspace.get_pane_group_view(0).expect("should have tab 0"); pane_group_view.read(ctx, |pane_group, _| pane_group.pane_count()) @@ -213,7 +213,7 @@ pub fn test_undo_close_grace_period_cleanup() -> Builder { .add_assertion(assert_focused_pane_index(0, 0)) // Should still be focused on original pane .add_assertion(move |app, window_id| { // Assert we still only have one pane (no restoration occurred) - let workspace_view = galaxy::integration_testing::view_getters::workspace_view(app, window_id); + let workspace_view = warp::integration_testing::view_getters::workspace_view(app, window_id); workspace_view.read(app, |workspace, ctx| { let pane_group_view = workspace.get_pane_group_view(0).expect("should have tab 0"); let pane_count = pane_group_view.read(ctx, |pane_group, _| pane_group.pane_count()); @@ -272,7 +272,7 @@ pub fn test_closed_panes_cleared_on_rearrangement() -> Builder { )) .with_step( // Close the middle pane by using a direct operation targeting pane index 1 - galaxy::integration_testing::pane_group::close_pane_by_index( + warp::integration_testing::pane_group::close_pane_by_index( 0, // tab index 1, // pane index - the middle pane ), @@ -280,7 +280,7 @@ pub fn test_closed_panes_cleared_on_rearrangement() -> Builder { .with_step( new_step_with_default_assertions("Verify we have 2 visible panes after closing one") .add_assertion(move |app, window_id| { - let workspace_view = galaxy::integration_testing::view_getters::workspace_view(app, window_id); + let workspace_view = warp::integration_testing::view_getters::workspace_view(app, window_id); workspace_view.read(app, |workspace, ctx| { let pane_group_view = workspace.get_pane_group_view(0).expect("should have tab 0"); let (visible_pane_count, total_pane_count) = pane_group_view.read(ctx, |pane_group, _| { @@ -296,11 +296,11 @@ pub fn test_closed_panes_cleared_on_rearrangement() -> Builder { ) .with_step( // Trigger pane rearrangement by moving panes - galaxy::integration_testing::pane_group::move_pane_by_indices( + warp::integration_testing::pane_group::move_pane_by_indices( 0, 0, 1, - galaxy::pane_group::tree::Direction::Right, + warp::pane_group::tree::Direction::Right, ), ) .with_step( @@ -310,7 +310,7 @@ pub fn test_closed_panes_cleared_on_rearrangement() -> Builder { .with_step( new_step_with_default_assertions("Verify pane was NOT restored - still have same visible panes") .add_assertion(move |app, window_id| { - let workspace_view = galaxy::integration_testing::view_getters::workspace_view(app, window_id); + let workspace_view = warp::integration_testing::view_getters::workspace_view(app, window_id); workspace_view.read(app, |workspace, ctx| { let pane_group_view = workspace.get_pane_group_view(0).expect("should have tab 0"); let visible_pane_count = pane_group_view.read(ctx, |pane_group, _| pane_group.visible_pane_count()); @@ -326,7 +326,7 @@ pub fn test_closed_panes_cleared_on_rearrangement() -> Builder { ) .with_step( trigger_undo_close().add_assertion(move |app, window_id| { - let workspace_view = galaxy::integration_testing::view_getters::workspace_view(app, window_id); + let workspace_view = warp::integration_testing::view_getters::workspace_view(app, window_id); workspace_view.read(app, |workspace, ctx| { let pane_group_view = workspace.get_pane_group_view(0).expect("should have tab 0"); let visible_pane_count = pane_group_view.read(ctx, |pane_group, _| pane_group.visible_pane_count()); @@ -342,7 +342,7 @@ pub fn test_closed_panes_cleared_on_rearrangement() -> Builder { .with_step( new_step_with_default_assertions("Verify remaining pane has expected state") .add_assertion(move |app, window_id| { - let workspace_view = galaxy::integration_testing::view_getters::workspace_view(app, window_id); + let workspace_view = warp::integration_testing::view_getters::workspace_view(app, window_id); let visible_pane_count = workspace_view.read(app, |workspace, ctx| { let pane_group_view = workspace.get_pane_group_view(0).expect("should have tab 0"); pane_group_view.read(ctx, |pane_group, _| pane_group.visible_pane_count()) @@ -448,7 +448,7 @@ pub fn test_tab_closes_when_last_visible_pane_closed() -> Builder { .set_pause_on_failure(std::time::Duration::from_secs(30)) .add_assertion(move |app, window_id| { let workspace_view = - galaxy::integration_testing::view_getters::workspace_view(app, window_id); + warp::integration_testing::view_getters::workspace_view(app, window_id); workspace_view.read(app, |workspace, _ctx| { let focused_tab_idx = workspace.active_tab_index(); diff --git a/crates/integration/src/test/preview_config_migration.rs b/crates/integration/src/test/preview_config_migration.rs index 3851a725..29addd40 100644 --- a/crates/integration/src/test/preview_config_migration.rs +++ b/crates/integration/src/test/preview_config_migration.rs @@ -36,7 +36,7 @@ pub fn test_preview_config_dir_migration() -> Builder { // integration channel is Integration, not Preview, so the public // entry point would no-op. let new_dir = home.join(".warp-preview"); - galaxy::integration_testing::preview_config_migration::run_config_dir_symlink_migration( + warp::integration_testing::preview_config_migration::run_config_dir_symlink_migration( &old_dir, &new_dir, ); }) diff --git a/crates/integration/src/test/remote_server.rs b/crates/integration/src/test/remote_server.rs index 70b8dd50..e4ba30f5 100644 --- a/crates/integration/src/test/remote_server.rs +++ b/crates/integration/src/test/remote_server.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::time::Duration; +use galaxyui_core::integration::TestStep; use settings::Setting as _; use warp::features::FeatureFlag; use warp::integration_testing::remote_server::{ @@ -24,7 +25,6 @@ use warp::integration_testing::terminal::{ }; use warp::terminal::shell::ShellType; use warp::terminal::warpify::settings::{SshExtensionInstallMode, SshExtensionInstallModeSetting}; -use galaxyui_core::integration::TestStep; use super::{new_builder, Builder}; diff --git a/crates/integration/src/test/secrets.rs b/crates/integration/src/test/secrets.rs index 1c07fdba..a150b706 100644 --- a/crates/integration/src/test/secrets.rs +++ b/crates/integration/src/test/secrets.rs @@ -1,3 +1,5 @@ +use galaxyui_core::async_assert; +use galaxyui_core::integration::TestStep; use warp::integration_testing::clipboard::assert_clipboard_contains_string; use warp::integration_testing::secret_redaction::{ assert_secret_tooltip_open, assert_secrets_redacted_for_ai, @@ -14,8 +16,6 @@ use warp::integration_testing::view_getters::single_terminal_view; use warp::settings_view::{PrivacyPageAction, SettingsAction}; use warp::terminal::model::index::Point; use warp::terminal::model::terminal_model::WithinModel; -use galaxyui_core::async_assert; -use galaxyui_core::integration::TestStep; use super::{new_builder, Builder}; use crate::util::skip_if_powershell_core_2303; diff --git a/crates/integration/src/test/session_restoration.rs b/crates/integration/src/test/session_restoration.rs index 3ae4fc66..b80324f9 100644 --- a/crates/integration/src/test/session_restoration.rs +++ b/crates/integration/src/test/session_restoration.rs @@ -1,3 +1,5 @@ +use galaxyui_core::integration::{AssertionOutcome, TestStep}; +use galaxyui_core::{async_assert_eq, SingletonEntity, ViewHandle}; use settings::{RespectUserSyncSetting, SyncToCloud}; use warp::features::FeatureFlag; use warp::integration_testing::notebook::{ @@ -19,8 +21,6 @@ use warp::terminal::model::terminal_model::BlockIndex; use warp::terminal::shell::ShellType; use warp::terminal::{History, ShellHost, TerminalView}; use warp::workspace::Workspace; -use galaxyui_core::integration::{AssertionOutcome, TestStep}; -use galaxyui_core::{async_assert_eq, SingletonEntity, ViewHandle}; use super::{new_builder, Builder, TEST_ONLY_ASSETS}; use crate::util::{get_local_user, tab_title_in_home_dir}; diff --git a/crates/integration/src/test/settings_file_errors.rs b/crates/integration/src/test/settings_file_errors.rs index 96c59cb2..5a05f32e 100644 --- a/crates/integration/src/test/settings_file_errors.rs +++ b/crates/integration/src/test/settings_file_errors.rs @@ -7,18 +7,18 @@ use std::time::Duration; +use galaxyui_core::async_assert; +use galaxyui_core::integration::TestStep; use warp::features::FeatureFlag; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for_tab; use warp::integration_testing::view_getters::workspace_view; -use galaxyui_core::async_assert; -use galaxyui_core::integration::TestStep; use super::{new_builder, Builder}; /// Helper: returns the path to the TOML settings file. fn toml_file_path() -> std::path::PathBuf { - galaxy::settings::user_preferences_toml_file_path() + warp::settings::user_preferences_toml_file_path() } // --------------------------------------------------------------------------- diff --git a/crates/integration/src/test/settings_file_hot_reload.rs b/crates/integration/src/test/settings_file_hot_reload.rs index 6e9b04a7..c71acad2 100644 --- a/crates/integration/src/test/settings_file_hot_reload.rs +++ b/crates/integration/src/test/settings_file_hot_reload.rs @@ -6,19 +6,19 @@ use std::time::Duration; +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert_eq, SingletonEntity}; use settings::Setting as _; use warp::features::FeatureFlag; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for_tab; use warp::settings::FontSettings; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert_eq, SingletonEntity}; use super::{new_builder, Builder}; /// Helper: returns the path to the TOML settings file. fn toml_file_path() -> std::path::PathBuf { - galaxy::settings::user_preferences_toml_file_path() + warp::settings::user_preferences_toml_file_path() } /// Verifies the full settings hot-reload pipeline end-to-end: the filesystem diff --git a/crates/integration/src/test/settings_file_migration.rs b/crates/integration/src/test/settings_file_migration.rs index afc07181..33a0db53 100644 --- a/crates/integration/src/test/settings_file_migration.rs +++ b/crates/integration/src/test/settings_file_migration.rs @@ -3,12 +3,12 @@ use std::collections::HashMap; +use galaxyui_core::integration::AssertionOutcome; +use galaxyui_core::{async_assert, async_assert_eq, SingletonEntity}; use settings::Setting as _; use warp::features::FeatureFlag; use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for_tab; use warp::settings::{BlockVisibilitySettings, ScrollSettings}; -use galaxyui_core::integration::AssertionOutcome; -use galaxyui_core::{async_assert, async_assert_eq, SingletonEntity}; use super::{new_builder, Builder}; @@ -65,7 +65,7 @@ pub fn test_settings_file_migration_from_native_store() -> Builder { .add_named_assertion( "TOML settings file should contain the migrated settings", move |_app, _window_id| { - let toml_path = galaxy::settings::user_preferences_toml_file_path(); + let toml_path = warp::settings::user_preferences_toml_file_path(); let contents = match std::fs::read_to_string(&toml_path) { Ok(c) => c, Err(err) => { diff --git a/crates/integration/src/test/settings_private.rs b/crates/integration/src/test/settings_private.rs index 07cf7c52..77e5eeb5 100644 --- a/crates/integration/src/test/settings_private.rs +++ b/crates/integration/src/test/settings_private.rs @@ -5,27 +5,27 @@ use std::collections::HashMap; +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert, async_assert_eq, SingletonEntity}; use settings::Setting as _; use warp::features::FeatureFlag; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::wait_until_bootstrapped_single_pane_for_tab; use warp::settings::{CodeSettings, DebugSettings, FontSettings}; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert, async_assert_eq, SingletonEntity}; use super::{new_builder, Builder}; /// Helper: read the TOML settings file from disk and return its contents. /// Returns an empty string if the file does not exist. fn read_toml_file() -> String { - let path = galaxy::settings::user_preferences_toml_file_path(); + let path = warp::settings::user_preferences_toml_file_path(); std::fs::read_to_string(path).unwrap_or_default() } /// Helper: read the JSON user preferences file from disk and return its contents. /// Returns an empty string if the file does not exist. fn read_json_prefs_file() -> String { - let path = galaxy::settings::user_preferences_file_path(); + let path = warp::settings::user_preferences_file_path(); std::fs::read_to_string(path).unwrap_or_default() } diff --git a/crates/integration/src/test/ssh.rs b/crates/integration/src/test/ssh.rs index 4f02a033..98a78e8e 100644 --- a/crates/integration/src/test/ssh.rs +++ b/crates/integration/src/test/ssh.rs @@ -1,5 +1,7 @@ use std::collections::HashMap; +use galaxyui_core::integration::{AssertionCallback, AssertionOutcome, TestStep}; +use galaxyui_core::{async_assert, async_assert_eq}; use regex::Regex; use settings::Setting as _; use warp::integration_testing::step::new_step_with_default_assertions; @@ -19,8 +21,6 @@ use warp::integration_testing::view_getters::{single_terminal_view, single_termi use warp::terminal::model::bootstrap::BootstrapStage; use warp::terminal::session_settings::{StartupShell, StartupShellOverride}; use warp::terminal::shell::ShellType; -use galaxyui_core::integration::{AssertionCallback, AssertionOutcome, TestStep}; -use galaxyui_core::{async_assert, async_assert_eq}; use super::new_builder; use crate::Builder; diff --git a/crates/integration/src/test/subshell.rs b/crates/integration/src/test/subshell.rs index 2d1b738c..80b23070 100644 --- a/crates/integration/src/test/subshell.rs +++ b/crates/integration/src/test/subshell.rs @@ -1,5 +1,9 @@ use std::collections::HashMap; +use galaxyui_core::integration::{AssertionOutcome, TestStep}; +use galaxyui_core::windowing::state::ApplicationStage; +use galaxyui_core::windowing::WindowManager; +use galaxyui_core::{async_assert, UpdateModel}; use settings::Setting as _; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::subshell::util::ssh_command; @@ -14,10 +18,6 @@ use warp::integration_testing::view_getters::single_input_view_for_tab; use warp::root_view::SubshellCommandArg; use warp::terminal::shell::ShellType; use warp::terminal::warpify::settings::AddedSubshellCommands; -use galaxyui_core::integration::{AssertionOutcome, TestStep}; -use galaxyui_core::windowing::state::ApplicationStage; -use galaxyui_core::windowing::WindowManager; -use galaxyui_core::{async_assert, UpdateModel}; use super::{new_builder, Builder}; use crate::util::skip_if_powershell_core_2303; diff --git a/crates/integration/src/test/sync_inputs.rs b/crates/integration/src/test/sync_inputs.rs index f96d6c08..0824a7c8 100644 --- a/crates/integration/src/test/sync_inputs.rs +++ b/crates/integration/src/test/sync_inputs.rs @@ -1,3 +1,5 @@ +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert, async_assert_eq}; use warp::cmd_or_ctrl_shift; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::util::ExpectedExitStatus; @@ -8,8 +10,6 @@ use warp::integration_testing::terminal::{ }; use warp::integration_testing::view_getters::{terminal_view, workspace_view}; use warp::workspace::WorkspaceAction; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert, async_assert_eq}; use super::{new_builder, Builder}; use crate::util::{get_input_buffer, skip_if_powershell_core_2303}; diff --git a/crates/integration/src/test/typeahead.rs b/crates/integration/src/test/typeahead.rs index 63488894..63315796 100644 --- a/crates/integration/src/test/typeahead.rs +++ b/crates/integration/src/test/typeahead.rs @@ -1,3 +1,5 @@ +use galaxyui_core::integration::{AssertionCallback, AssertionOutcome, TestStep}; +use galaxyui_core::{async_assert, async_assert_eq}; use warp::integration_testing::agent_mode::AgentViewState; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::util::current_shell_starter_and_version; @@ -9,8 +11,6 @@ use warp::integration_testing::terminal::{ use warp::integration_testing::view_getters::single_terminal_view_for_tab; use warp::terminal::model::terminal_model::BlockIndex; use warp::terminal::shell::{Shell, ShellType}; -use galaxyui_core::integration::{AssertionCallback, AssertionOutcome, TestStep}; -use galaxyui_core::{async_assert, async_assert_eq}; use super::{new_builder, Builder}; use crate::util::skip_if_powershell_core_2303; diff --git a/crates/integration/src/test/video_recording.rs b/crates/integration/src/test/video_recording.rs index dbbae497..f27dec03 100644 --- a/crates/integration/src/test/video_recording.rs +++ b/crates/integration/src/test/video_recording.rs @@ -1,8 +1,8 @@ use std::future::Future; use std::pin::Pin; -use galaxyui::event::{Event, ModifiersState}; -use galaxyui::integration::{TestStep, ARTIFACTS_DIR_ENV_VAR}; +use galaxyui_core::event::{Event, ModifiersState}; +use galaxyui_core::integration::{TestStep, ARTIFACTS_DIR_ENV_VAR}; use pathfinder_geometry::vector::vec2f; use warp::integration_testing::step::new_step_with_default_assertions; use warp::integration_testing::terminal::util::ExpectedExitStatus; @@ -11,8 +11,6 @@ use warp::integration_testing::terminal::{ execute_command_for_single_terminal_in_tab, execute_echo_str, wait_until_bootstrapped_single_pane_for_tab, }; -use galaxyui_core::event::{Event, ModifiersState}; -use galaxyui_core::integration::{TestStep, ARTIFACTS_DIR_ENV_VAR}; use crate::Builder; diff --git a/crates/integration/src/test/workflows.rs b/crates/integration/src/test/workflows.rs index aa0c1059..f5181bc4 100644 --- a/crates/integration/src/test/workflows.rs +++ b/crates/integration/src/test/workflows.rs @@ -1,5 +1,7 @@ use std::time::Duration; +use galaxyui_core::integration::TestStep; +use galaxyui_core::{async_assert_eq, ViewHandle}; use warp::integration_testing::assertions::{go_offline, go_online, join_a_workspace}; use warp::integration_testing::command_palette::{ open_command_palette_and_run_action, TestStepsExt, @@ -17,8 +19,6 @@ use warp::integration_testing::workflow::{ }; use warp::integration_testing::{self, view_of_type}; use warp::workflows::CategoriesView; -use galaxyui_core::integration::TestStep; -use galaxyui_core::{async_assert_eq, ViewHandle}; use super::{new_builder, TEST_ONLY_ASSETS}; use crate::Builder; diff --git a/crates/integration/src/test/workspace.rs b/crates/integration/src/test/workspace.rs index 1bb30e53..165ab073 100644 --- a/crates/integration/src/test/workspace.rs +++ b/crates/integration/src/test/workspace.rs @@ -3,6 +3,10 @@ use std::fs; use std::time::Duration; +use galaxyui_core::event::{Event, ModifiersState}; +use galaxyui_core::integration::{AssertionCallback, AssertionOutcome, StepDataMap, TestStep}; +use galaxyui_core::windowing::WindowManager; +use galaxyui_core::{async_assert, async_assert_eq, SingletonEntity, TypedActionView, WindowId}; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::{vec2f, Vector2F}; use settings::Setting as _; @@ -31,10 +35,6 @@ use warp::settings::PaneSettings; use warp::terminal::shell::ShellType; use warp::workspace::tab_settings::{TabSettings, VerticalTabsDisplayGranularity}; use warp::workspace::{WorkspaceAction, NEW_TAB_BUTTON_POSITION_ID}; -use galaxyui_core::event::{Event, ModifiersState}; -use galaxyui_core::integration::{AssertionCallback, AssertionOutcome, StepDataMap, TestStep}; -use galaxyui_core::windowing::WindowManager; -use galaxyui_core::{async_assert, async_assert_eq, SingletonEntity, TypedActionView, WindowId}; use super::new_builder; use crate::util::skip_if_powershell_core_2303; diff --git a/crates/integration/src/user_defaults.rs b/crates/integration/src/user_defaults.rs index a37a1842..e1869467 100644 --- a/crates/integration/src/user_defaults.rs +++ b/crates/integration/src/user_defaults.rs @@ -1,5 +1,3 @@ -use galaxy::settings::INPUT_MODE; -use galaxy::terminal::block_list_viewport::InputMode; use std::collections::HashMap; use warp::settings::INPUT_MODE; diff --git a/crates/integration/src/util.rs b/crates/integration/src/util.rs index 9f3937e9..2ec7e285 100644 --- a/crates/integration/src/util.rs +++ b/crates/integration/src/util.rs @@ -2,6 +2,7 @@ use std::fs::{create_dir_all, write, OpenOptions}; use std::io::Write; use std::path::{Path, PathBuf}; +use galaxyui_core::{App, WindowId}; use itertools::Itertools as _; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -12,7 +13,6 @@ use warp::integration_testing::terminal::util::{ use warp::integration_testing::view_getters; use warp::terminal::shell; use warp::terminal::shell::ShellType; -use galaxyui_core::{App, WindowId}; use crate::builder::cargo_target_tmpdir; diff --git a/crates/jsonrpc/src/service.rs b/crates/jsonrpc/src/service.rs index 3eb41b31..73e33ce4 100644 --- a/crates/jsonrpc/src/service.rs +++ b/crates/jsonrpc/src/service.rs @@ -5,10 +5,10 @@ use std::sync::{Arc, Mutex}; use anyhow::{anyhow, Result}; use futures::channel::oneshot; use futures::lock::Mutex as AsyncMutex; +use galaxyui_core::r#async::executor::Background; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; use serde_json::Value; -use galaxyui_core::r#async::executor::Background; use crate::transport::Transport; diff --git a/crates/languages/src/lib.rs b/crates/languages/src/lib.rs index a421fb5f..c51d065d 100644 --- a/crates/languages/src/lib.rs +++ b/crates/languages/src/lib.rs @@ -5,10 +5,10 @@ use std::sync::{Arc, Mutex}; use arborium::tree_sitter::{Language as ParserGrammar, Query}; use galaxy_editor::content::text::IndentUnit; +use galaxy_util::standardized_path::StandardizedPath; use lazy_static::lazy_static; use rust_embed::RustEmbed; use serde::{Deserialize, Serialize}; -use galaxy_util::standardized_path::StandardizedPath; #[derive(RustEmbed)] #[folder = "grammars"] @@ -18,7 +18,7 @@ lazy_static! { static ref LANGUAGE_REGISTRY: LanguageRegistry = LanguageRegistry::new(); } -pub const SUPPORTED_LANGUAGES: [&str; 34] = [ +pub const SUPPORTED_LANGUAGES: [&str; 33] = [ "rust", "golang", "yaml", @@ -39,7 +39,6 @@ pub const SUPPORTED_LANGUAGES: [&str; 34] = [ "hcl", "lua", "ruby", - "php", "toml", "swift", "kotlin", @@ -180,7 +179,6 @@ fn language_by_filename_parts( "lua" => language_by_name("lua"), "nix" => language_by_name("nix"), "rb" => language_by_name("ruby"), - "php" | "phtml" => language_by_name("php"), "toml" => language_by_name("toml"), "swift" => language_by_name("swift"), "kt" | "kts" => language_by_name("kotlin"), @@ -277,7 +275,6 @@ fn get_arborium_highlight_query(lang: &str) -> Option<&str> { "lua" => Some(arborium::lang_lua::HIGHLIGHTS_QUERY), "nix" => Some(arborium::lang_nix::HIGHLIGHTS_QUERY), "ruby" => Some(arborium::lang_ruby::HIGHLIGHTS_QUERY), - "php" => Some(arborium::lang_php::HIGHLIGHTS_QUERY), "toml" => Some(arborium::lang_toml::HIGHLIGHTS_QUERY), "swift" => Some(arborium::lang_swift::HIGHLIGHTS_QUERY), "kotlin" => Some(arborium::lang_kotlin::HIGHLIGHTS_QUERY), diff --git a/crates/languages/src/lib_tests.rs b/crates/languages/src/lib_tests.rs index b6f32b95..300a2f09 100644 --- a/crates/languages/src/lib_tests.rs +++ b/crates/languages/src/lib_tests.rs @@ -1,6 +1,6 @@ use std::path::Path; -use warp_util::standardized_path::StandardizedPath; +use galaxy_util::standardized_path::StandardizedPath; use crate::{language_by_filename, language_by_local_filename, load_language, SUPPORTED_LANGUAGES}; diff --git a/crates/local_control/src/discovery_tests.rs b/crates/local_control/src/discovery_tests.rs index f990940c..748a2d5a 100644 --- a/crates/local_control/src/discovery_tests.rs +++ b/crates/local_control/src/discovery_tests.rs @@ -286,7 +286,6 @@ fn discovery_directory_is_owner_only_on_unix() { #[cfg(unix)] #[test] fn discovery_record_is_owner_only_on_unix() { - let dir = tempfile::tempdir().expect("temp dir"); let record = InstanceRecord::for_current_process( Some(ControlEndpoint::localhost(4000)), diff --git a/crates/local_inference/Cargo.toml b/crates/local_inference/Cargo.toml index efea625e..32f0963b 100644 --- a/crates/local_inference/Cargo.toml +++ b/crates/local_inference/Cargo.toml @@ -27,3 +27,4 @@ tokio = { workspace = true, features = ["fs", "sync", "rt", "macros", "rt-multi- [dev-dependencies] env_logger = "0.10" +instant = { workspace = true } diff --git a/crates/local_inference/src/engine/mod.rs b/crates/local_inference/src/engine/mod.rs index 1f372d58..3cd239fa 100644 --- a/crates/local_inference/src/engine/mod.rs +++ b/crates/local_inference/src/engine/mod.rs @@ -8,11 +8,10 @@ use std::sync::atomic::{AtomicBool, Ordering}; use anyhow::{Context as _, Result}; use candle_core::{DType, Tensor}; use candle_transformers::models::llama::{Cache, Config, Llama, LlamaConfig}; +pub use generation::GenerationConfig; use tokenizers::Tokenizer; use tokio::sync::Mutex; -pub use generation::GenerationConfig; - /// A token that can be used to cancel an in-progress generation. /// Clone it and pass to `generate_cancellable`, then call `cancel()` to /// interrupt the generation loop between tokens. @@ -37,6 +36,12 @@ impl CancellationToken { } } +impl Default for CancellationToken { + fn default() -> Self { + Self::new() + } +} + const HF_REPO: &str = "HuggingFaceTB/SmolLM2-135M-Instruct"; const MODEL_FILENAME: &str = "model.safetensors"; const TOKENIZER_FILENAME: &str = "tokenizer.json"; @@ -67,7 +72,7 @@ impl Device { } } - fn to_candle_device(&self) -> Result { + fn to_candle_device(self) -> Result { match self { Device::Cpu => Ok(candle_core::Device::Cpu), #[cfg(feature = "metal")] @@ -183,15 +188,13 @@ impl InferenceEngine { let first_logits = logits.squeeze(0)?; let next_token = generation::sample(&first_logits, config)?; - if let Some(eos) = eos_token_id { - if next_token == eos { - let generated_tokens = &tokens[input_ids.len()..]; - let output = self - .tokenizer - .decode(generated_tokens, true) - .map_err(|e| anyhow::anyhow!("{e}"))?; - return Ok(output.trim().to_string()); - } + if Some(next_token) == eos_token_id { + let generated_tokens = &tokens[input_ids.len()..]; + let output = self + .tokenizer + .decode(generated_tokens, true) + .map_err(|e| anyhow::anyhow!("{e}"))?; + return Ok(output.trim().to_string()); } tokens.push(next_token); @@ -208,10 +211,8 @@ impl InferenceEngine { let next_logits = logits.squeeze(0)?; let next_token = generation::sample(&next_logits, config)?; - if let Some(eos) = eos_token_id { - if next_token == eos { - break; - } + if Some(next_token) == eos_token_id { + break; } tokens.push(next_token); @@ -255,15 +256,13 @@ impl InferenceEngine { let first_logits = logits.squeeze(0)?; let next_token = generation::sample(&first_logits, config)?; - if let Some(eos) = eos_token_id { - if next_token == eos { - let generated_tokens = &tokens[input_ids.len()..]; - let output = self - .tokenizer - .decode(generated_tokens, true) - .map_err(|e| anyhow::anyhow!("{e}"))?; - return Ok(output.trim().to_string()); - } + if Some(next_token) == eos_token_id { + let generated_tokens = &tokens[input_ids.len()..]; + let output = self + .tokenizer + .decode(generated_tokens, true) + .map_err(|e| anyhow::anyhow!("{e}"))?; + return Ok(output.trim().to_string()); } tokens.push(next_token); @@ -276,10 +275,8 @@ impl InferenceEngine { let next_logits = logits.squeeze(0)?; let next_token = generation::sample(&next_logits, config)?; - if let Some(eos) = eos_token_id { - if next_token == eos { - break; - } + if Some(next_token) == eos_token_id { + break; } tokens.push(next_token); diff --git a/crates/local_inference/src/lib.rs b/crates/local_inference/src/lib.rs index eea60405..be200a11 100644 --- a/crates/local_inference/src/lib.rs +++ b/crates/local_inference/src/lib.rs @@ -2,7 +2,6 @@ pub mod engine; pub mod tasks; use async_trait::async_trait; - pub use engine::{CancellationToken, Device, GenerationConfig, InferenceEngine}; pub use tasks::{ InputCategory, InputClassificationInput, InputClassificationResult, InputClassificationTask, diff --git a/crates/local_inference/tests/e2e_scenarios.rs b/crates/local_inference/tests/e2e_scenarios.rs index 1a5dfa02..eb0b9245 100644 --- a/crates/local_inference/tests/e2e_scenarios.rs +++ b/crates/local_inference/tests/e2e_scenarios.rs @@ -2,12 +2,12 @@ //! the local inference engine across all task types (classification, //! prompt suggestion, tab naming). +use instant::Instant; use local_inference::{ Device, InferenceEngine, InferenceTask, InputCategory, InputClassificationInput, InputClassificationTask, PromptSuggestionInput, PromptSuggestionTask, TabNamingInput, TabNamingTask, }; -use std::time::Instant; async fn get_engine() -> InferenceEngine { InferenceEngine::new(Device::Cpu) diff --git a/crates/lsp/Cargo.toml b/crates/lsp/Cargo.toml index 716d4e93..7ba114c7 100644 --- a/crates/lsp/Cargo.toml +++ b/crates/lsp/Cargo.toml @@ -47,3 +47,6 @@ nix = { workspace = true } repo_metadata.workspace = true sha2 = { workspace = true } tokio = { workspace = true, features = ["process"] } + +[dev-dependencies] +galaxyui.workspace = true diff --git a/crates/lsp/examples/rust-lsp/main.rs b/crates/lsp/examples/rust-lsp/main.rs index c15208ab..0aace91a 100644 --- a/crates/lsp/examples/rust-lsp/main.rs +++ b/crates/lsp/examples/rust-lsp/main.rs @@ -12,13 +12,12 @@ use std::sync::Arc; use std::time::Duration; use chrono::Utc; -use galaxyui::r#async::{executor::Background, Timer}; +use galaxyui::r#async::executor::Background; +use galaxyui::r#async::Timer; use log::LevelFilter; use lsp::supported_servers::LSPServerType; use lsp::{spawn_lsp_service, LspServerConfig, LspService, LspServiceInitializationResult}; use lsp_types::Position; -use galaxyui_core::r#async::executor::Background; -use galaxyui_core::r#async::Timer; fn init_logging() { let mut base_logger = env_logger::builder(); diff --git a/crates/lsp/src/lib.rs b/crates/lsp/src/lib.rs index 692619ee..9b47e04a 100644 --- a/crates/lsp/src/lib.rs +++ b/crates/lsp/src/lib.rs @@ -22,7 +22,7 @@ pub mod types; pub use config::{default_init_params, LanguageId, LspServerConfig}; pub use jsonrpc::{JsonRpcService, ServerNotificationEvent, Transport}; pub use lsp_types::notification::{self}; -pub use lsp_types::{Position, Range}; +pub use lsp_types::{CompletionItem, Position, Range}; pub use manager::{LspManagerModel, LspManagerModelEvent}; pub use model::{ BackgroundTaskInfo, DocumentDiagnostics, LanguageServerId, LspEvent, LspServerModel, LspState, @@ -57,12 +57,10 @@ impl std::fmt::Display for LspServerLogLevel { use std::sync::Arc; use anyhow::Result; -use galaxyui::r#async::executor::Background; -use galaxyui::AppContext; -#[cfg(not(target_arch = "wasm32"))] -use simple_logger::SimpleLogger; use galaxyui_core::r#async::executor::Background; use galaxyui_core::AppContext; +#[cfg(not(target_arch = "wasm32"))] +use simple_logger::SimpleLogger; pub struct LspServiceInitializationResult { pub service: LspService, diff --git a/crates/lsp/src/model.rs b/crates/lsp/src/model.rs index 2961a2d3..93ae06a0 100644 --- a/crates/lsp/src/model.rs +++ b/crates/lsp/src/model.rs @@ -5,28 +5,29 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use anyhow::{Error, Result}; -use instant::Instant; -use jsonrpc::ServerNotificationEvent; -use lsp_types::notification::{self, Notification}; -use lsp_types::{ - FormattingOptions, NumberOrString, ProgressParams, ProgressParamsValue, - PublishDiagnosticsParams, WorkDoneProgress, -}; -#[cfg(not(target_arch = "wasm32"))] -use simple_logger::manager::LogManager; #[cfg(not(target_arch = "wasm32"))] use galaxy_core::features::FeatureFlag; use galaxyui_core::r#async::executor::Background; #[cfg(not(target_arch = "wasm32"))] use galaxyui_core::SingletonEntity; use galaxyui_core::{Entity, ModelContext}; +use instant::Instant; +use jsonrpc::ServerNotificationEvent; +use lsp_types::notification::{self, Notification}; +use lsp_types::{ + CompletionItem, CompletionTriggerKind, FormattingOptions, NumberOrString, ProgressParams, + ProgressParamsValue, PublishDiagnosticsParams, Range as LspRange, WorkDoneProgress, +}; +#[cfg(not(target_arch = "wasm32"))] +use simple_logger::manager::LogManager; use crate::config::{lsp_uri_to_path, LanguageId}; use crate::server_repo_watcher::LspRepoWatcher; use crate::supported_servers::LSPServerType; use crate::types::{ - DefinitionLocation, DocumentVersion, HoverResult, Location, ReferenceLocation, - TextDocumentContentChangeEvent, TextEdit, WatchedFileChangeEvent, + CodeActionData, CompletionResult, CompletionTrigger, DefinitionLocation, DocumentVersion, + HoverResult, Location, PrepareRenameResult, ReferenceLocation, RenameResult, + SignatureHelpResult, TextDocumentContentChangeEvent, TextEdit, WatchedFileChangeEvent, }; #[cfg(not(target_arch = "wasm32"))] use crate::{spawn_lsp_service, LspServiceInitializationResult}; diff --git a/crates/lsp/src/server_repo_watcher.rs b/crates/lsp/src/server_repo_watcher.rs index c733251a..8ed6688a 100644 --- a/crates/lsp/src/server_repo_watcher.rs +++ b/crates/lsp/src/server_repo_watcher.rs @@ -4,11 +4,10 @@ use std::pin::Pin; use async_channel::Sender; use galaxy_util::standardized_path::StandardizedPath; -use galaxyui::{ModelContext, SingletonEntity, WeakModelHandle}; +use galaxyui_core::{ModelContext, SingletonEntity, WeakModelHandle}; use lsp_types::FileChangeType; use repo_metadata::repository::{RepositorySubscriber, SubscriberId}; use repo_metadata::{DirectoryWatcher, Repository, RepositoryUpdate}; -use galaxyui_core::{ModelContext, SingletonEntity, WeakModelHandle}; use crate::model::LspServerModel; use crate::types::WatchedFileChangeEvent; diff --git a/crates/lsp/src/servers/typescript_language_server.rs b/crates/lsp/src/servers/typescript_language_server.rs index e0c50b5f..b59378df 100644 --- a/crates/lsp/src/servers/typescript_language_server.rs +++ b/crates/lsp/src/servers/typescript_language_server.rs @@ -4,8 +4,6 @@ use std::sync::Arc; #[cfg(feature = "local_fs")] use anyhow::Context; use async_trait::async_trait; -#[cfg(feature = "local_fs")] -use command::r#async::Command; use crate::language_server_candidate::{LanguageServerCandidate, LanguageServerMetadata}; #[cfg(feature = "local_fs")] diff --git a/crates/lsp/src/service.rs b/crates/lsp/src/service.rs index df6b7be3..2b91b26c 100644 --- a/crates/lsp/src/service.rs +++ b/crates/lsp/src/service.rs @@ -9,12 +9,14 @@ use jsonrpc::{JsonRpcService, RequestId, ServerNotificationEvent}; use lsp_types::notification::{self, Notification}; use lsp_types::request::{self, Request}; use lsp_types::{ - CancelParams, DidChangeTextDocumentParams, DidChangeWatchedFilesParams, - DidChangeWatchedFilesRegistrationOptions, DidCloseTextDocumentParams, - DidOpenTextDocumentParams, DocumentFormattingParams, FileChangeType, FileSystemWatcher, - FormattingOptions, GlobPattern, GotoDefinitionParams, GotoDefinitionResponse, HoverParams, - InitializeParams, InitializedParams, NumberOrString, OneOf, Position, ReferenceParams, - RegistrationParams, RelativePattern, TextDocumentIdentifier, TextDocumentItem, + CancelParams, CodeActionContext, CodeActionParams, CompletionContext, CompletionItem, + CompletionParams, CompletionTriggerKind, DidChangeTextDocumentParams, + DidChangeWatchedFilesParams, DidChangeWatchedFilesRegistrationOptions, + DidCloseTextDocumentParams, DidOpenTextDocumentParams, DocumentFormattingParams, + FileChangeType, FileSystemWatcher, FormattingOptions, GlobPattern, GotoDefinitionParams, + GotoDefinitionResponse, HoverParams, InitializeParams, InitializedParams, NumberOrString, + OneOf, Position, Range as LspRange, ReferenceParams, RegistrationParams, RelativePattern, + RenameParams, SignatureHelpParams, TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, UnregistrationParams, VersionedTextDocumentIdentifier, WatchKind, }; use serde_json::Value; @@ -23,8 +25,9 @@ use simple_logger::SimpleLogger; use crate::config::{lsp_uri_to_path, path_to_lsp_uri, LanguageId}; use crate::types::{ - HoverResult, LspDefinitionLocation, ReferenceLocation, TextDocumentContentChangeEvent, - TextEdit, WatchedFileChangeEvent, + CodeActionData, CompletionResult, FileEdits, HoverResult, Location, LspDefinitionLocation, + PrepareRenameResult, Range, ReferenceLocation, RenameResult, SignatureHelpResult, + TextDocumentContentChangeEvent, TextEdit, WatchedFileChangeEvent, }; use crate::LspServerLogLevel; diff --git a/crates/lsp/src/transport.rs b/crates/lsp/src/transport.rs index e8b2db59..e6ca6177 100644 --- a/crates/lsp/src/transport.rs +++ b/crates/lsp/src/transport.rs @@ -6,10 +6,10 @@ use command::r#async::Command; use futures::future::FutureExt; use futures::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}; use futures::lock::Mutex; -use jsonrpc::Transport; -use simple_logger::SimpleLogger; use galaxyui_core::r#async::executor::{Background, BackgroundTask}; use galaxyui_core::r#async::Timer; +use jsonrpc::Transport; +use simple_logger::SimpleLogger; /// Transport implementation for LSP communication over process stdin/stdout. /// Also manages the LSP server process lifecycle with graceful shutdown capabilities. diff --git a/crates/managed_secrets/src/client.rs b/crates/managed_secrets/src/client.rs index 49ea3540..bc9b36ba 100644 --- a/crates/managed_secrets/src/client.rs +++ b/crates/managed_secrets/src/client.rs @@ -4,9 +4,9 @@ use std::time::Duration; use anyhow::Result; use async_trait::async_trait; use chrono::{DateTime, Utc}; -use vec1::Vec1; use galaxy_graphql::managed_secrets::{ManagedSecret, ManagedSecretConfig, ManagedSecretType}; pub use galaxy_graphql::queries::task_secrets::ManagedSecretValue; +use vec1::Vec1; /// An OIDC identity token issued for a task workload. #[derive(Debug, Clone)] @@ -75,7 +75,7 @@ pub trait ManagedSecretsClient: 'static + Send + Sync { /// Returns an empty list for harnesses that do not use auth secrets (e.g. Oz). async fn list_harness_auth_secrets( &self, - harness: warp_graphql::ai::AgentHarness, + harness: galaxy_graphql::ai::AgentHarness, ) -> Result>; async fn get_task_secrets( diff --git a/crates/managed_secrets/src/manager.rs b/crates/managed_secrets/src/manager.rs index 672de494..39b109e3 100644 --- a/crates/managed_secrets/src/manager.rs +++ b/crates/managed_secrets/src/manager.rs @@ -3,11 +3,11 @@ use std::future::Future; use std::sync::Arc; use std::time::Duration; -use vec1::vec1; use galaxy_core::features::FeatureFlag; use galaxy_graphql::managed_secrets::ManagedSecret; use galaxy_graphql::queries::task_secrets::ManagedSecretValue as GqlManagedSecretValue; use galaxyui_core::{Entity, SingletonEntity}; +use vec1::vec1; use crate::ManagedSecretValue; use crate::client::{ diff --git a/crates/mcp/src/runtime.rs b/crates/mcp/src/runtime.rs index 0041fcde..12828417 100644 --- a/crates/mcp/src/runtime.rs +++ b/crates/mcp/src/runtime.rs @@ -314,7 +314,7 @@ pub async fn spawn_server( let server_info = service.peer_info(); logger.log(format!("[info] MCP: Connected to server: {server_info:#?}")); - let capabilities = server_info.map(|info| &info.capabilities); + let capabilities = server_info.as_ref().map(|info| &info.capabilities); let resources = query_resources_for(capabilities, &server_name, || service.list_all_resources()).await; diff --git a/crates/onboarding/examples/callout.rs b/crates/onboarding/examples/callout.rs index 5da41183..08b746d8 100644 --- a/crates/onboarding/examples/callout.rs +++ b/crates/onboarding/examples/callout.rs @@ -6,20 +6,14 @@ use galaxy_core::ui::theme::{AnsiColor, AnsiColors, Details, Fill, GalaxyTheme, use galaxyui::color::ColorU; use galaxyui::elements::{Rect, Stack}; use galaxyui::fonts::{Cache, FamilyId, Weight}; -use galaxyui::platform; -use galaxyui::{prelude::*, AddWindowOptions, AssetProvider, ModelContext}; +use galaxyui::prelude::*; +use galaxyui::{platform, AddWindowOptions, AssetProvider, ModelContext}; use onboarding::components::onboarding_callout::{ Button as CalloutButton, OnboardingCallout, Options as CalloutOptions, Params as CalloutParams, StepStatus, }; use rust_embed::RustEmbed; use ui_components::Component as _; -use galaxy_core::ui::theme::{AnsiColor, AnsiColors, Details, Fill, TerminalColors, WarpTheme}; -use galaxyui_core::color::ColorU; -use galaxyui_core::elements::{Rect, Stack}; -use galaxyui_core::fonts::{Cache, FamilyId, Weight}; -use galaxyui_core::prelude::*; -use galaxyui_core::{platform, AddWindowOptions, AssetProvider, ModelContext}; #[derive(Clone, Copy, RustEmbed)] #[folder = "../../app/assets"] @@ -36,7 +30,7 @@ impl AssetProvider for Assets { } fn main() -> platform::app::TerminationResult { - let app_builder = warpui::platform::AppBuilder::new( + let app_builder = galaxyui::platform::AppBuilder::new( platform::AppCallbacks::default(), Box::new(ASSETS), None, @@ -51,7 +45,8 @@ fn main() -> platform::app::TerminationResult { "Noto Sans".to_string() }; - let font_family = Cache::handle(ctx).update(ctx, |cache, _ctx| { + let cache_handle = Cache::handle(ctx); + let font_family = cache_handle.update(ctx, |cache, _ctx| { cache.load_system_font(&font_name).unwrap() }); diff --git a/crates/onboarding/examples/callout_flow.rs b/crates/onboarding/examples/callout_flow.rs index 3714c8e1..ba927253 100644 --- a/crates/onboarding/examples/callout_flow.rs +++ b/crates/onboarding/examples/callout_flow.rs @@ -1,15 +1,8 @@ use std::borrow::Cow; use anyhow::Result; -use onboarding::callout::{ - OnboardingCalloutView, OnboardingCalloutViewEvent, OnboardingKeybindings, -}; -use onboarding::OnboardingIntention; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use rust_embed::RustEmbed; use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::theme::{AnsiColor, AnsiColors, Details, Fill, TerminalColors, WarpTheme}; +use galaxy_core::ui::theme::{AnsiColor, AnsiColors, Details, Fill, GalaxyTheme, TerminalColors}; use galaxyui_core::elements::{ ChildAnchor, ChildView, ConstrainedBox, Container, Flex, MainAxisAlignment, MainAxisSize, OffsetPositioning, ParentElement, PositionedElementAnchor, PositionedElementOffsetBounds, Rect, @@ -25,6 +18,10 @@ use galaxyui_core::{ use onboarding::callout::{ OnboardingCalloutView, OnboardingCalloutViewEvent, OnboardingKeybindings, }; +use onboarding::OnboardingIntention; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use rust_embed::RustEmbed; #[derive(Clone, Copy, RustEmbed)] #[folder = "../../app/assets"] @@ -182,7 +179,7 @@ fn main() -> Result<()> { ..Default::default() })?; - let app_builder = warpui::platform::AppBuilder::new( + let app_builder = galaxyui::platform::AppBuilder::new( platform::AppCallbacks::default(), Box::new(ASSETS), None, @@ -258,7 +255,8 @@ fn build_appearance(theme: GalaxyTheme, ctx: &mut AppContext) -> Appearance { } fn load_default_ui_font_family(ctx: &mut AppContext) -> anyhow::Result { - Cache::handle(ctx).update(ctx, |font_cache, _| { + let cache_handle = Cache::handle(ctx); + cache_handle.update(ctx, |font_cache, _| { // On Windows, default to use Segoe UI as the UI font. #[cfg(windows)] if let Ok(font_family_id) = font_cache.load_system_font("Segoe UI") { diff --git a/crates/onboarding/src/agent_onboarding_view.rs b/crates/onboarding/src/agent_onboarding_view.rs index 66b168b4..5fcdfe39 100644 --- a/crates/onboarding/src/agent_onboarding_view.rs +++ b/crates/onboarding/src/agent_onboarding_view.rs @@ -1,13 +1,13 @@ use std::time::Duration; use ai::LLMId; -use instant::Instant; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxyui_core::assets::asset_cache::AssetSource; use galaxyui_core::image_cache::ImageType; use galaxyui_core::windowing::state::{ApplicationStage, StateEvent}; use galaxyui_core::windowing::WindowManager; +use instant::Instant; use crate::components::feature_optout_dialog::{render_feature_optout_dialog, FeatureOptOutDialog}; use crate::model::{ @@ -25,11 +25,8 @@ const APP_BECAME_ACTIVE_DEBOUNCE: Duration = Duration::from_secs(15); const PLAN_ACTIVATED_TOAST_DURATION: Duration = Duration::from_secs(5); -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxy_core::ui::Icon; use galaxyui_core::elements::{ Align, CacheOption, ChildAnchor, ConstrainedBox, Container, CrossAxisAlignment, Dismiss, Empty, @@ -45,6 +42,9 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use ui_components::{button, Component as _, Options as _}; #[derive(Clone, Debug)] pub enum AgentOnboardingEvent { @@ -483,7 +483,7 @@ impl AgentOnboardingView { let ui_builder = appearance.ui_builder(); let check_icon = ConstrainedBox::new(Box::new( - Icon::CheckSkinny.to_warpui_icon(Fill::Solid(text_color)), + Icon::CheckSkinny.to_galaxyui_icon(Fill::Solid(text_color)), )) .with_width(ICON_SIZE) .with_height(ICON_SIZE) diff --git a/crates/onboarding/src/bin/main.rs b/crates/onboarding/src/bin/main.rs index 7ad36e07..f120380e 100644 --- a/crates/onboarding/src/bin/main.rs +++ b/crates/onboarding/src/bin/main.rs @@ -4,12 +4,6 @@ use std::borrow::Cow; use ai::LLMId; use anyhow::Result; -use onboarding::slides::OnboardingModelInfo; -use onboarding::{ - AgentOnboardingEvent, AgentOnboardingView, MockTelemetryContextProvider, SelectedSettings, -}; -use pathfinder_color::ColorU; -use rust_embed::RustEmbed; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::{ @@ -26,9 +20,12 @@ use galaxyui_core::{ platform, AddWindowOptions, AppContext, AssetProvider, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, ViewHandle, }; +use onboarding::slides::OnboardingModelInfo; use onboarding::{ AgentOnboardingEvent, AgentOnboardingView, MockTelemetryContextProvider, SelectedSettings, }; +use pathfinder_color::ColorU; +use rust_embed::RustEmbed; #[derive(Clone, Copy, RustEmbed)] #[folder = "../../app/assets"] diff --git a/crates/onboarding/src/callout/view.rs b/crates/onboarding/src/callout/view.rs index cf7dacbc..27b271c9 100644 --- a/crates/onboarding/src/callout/view.rs +++ b/crates/onboarding/src/callout/view.rs @@ -1,4 +1,3 @@ -use ui_components::Component; use galaxy_core::ui::appearance::Appearance; use galaxyui_core::elements::Empty; use galaxyui_core::keymap::macros::*; @@ -7,6 +6,7 @@ use galaxyui_core::{ AppContext, Element, Entity, EventContext, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use ui_components::Component; /// Display strings for keybindings shown in the onboarding callout. #[derive(Clone, Debug)] diff --git a/crates/onboarding/src/components/feature_optout_dialog.rs b/crates/onboarding/src/components/feature_optout_dialog.rs index 31cd692e..e5b1889d 100644 --- a/crates/onboarding/src/components/feature_optout_dialog.rs +++ b/crates/onboarding/src/components/feature_optout_dialog.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; @@ -10,6 +9,7 @@ use galaxyui_core::elements::{ use galaxyui_core::fonts::Weight; use galaxyui_core::text_layout::TextAlignment; use galaxyui_core::Element; +use pathfinder_color::ColorU; /// Content for a "you'll lose these features" opt-out confirmation dialog. pub struct FeatureOptOutDialog { @@ -62,7 +62,7 @@ pub fn render_feature_optout_dialog( let mut feature_list = Flex::column().with_cross_axis_alignment(CrossAxisAlignment::Stretch); for &item in dialog.features { - let icon_el = ConstrainedBox::new(Icon::X.to_warpui_icon(feature_x_fill).finish()) + let icon_el = ConstrainedBox::new(Icon::X.to_galaxyui_icon(feature_x_fill).finish()) .with_width(16.) .with_height(16.) .finish(); diff --git a/crates/onboarding/src/components/onboarding_callout.rs b/crates/onboarding/src/components/onboarding_callout.rs index f2e448ea..df2a61bf 100644 --- a/crates/onboarding/src/components/onboarding_callout.rs +++ b/crates/onboarding/src/components/onboarding_callout.rs @@ -1,9 +1,5 @@ use std::borrow::Cow; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use ui_components::button::Button as ButtonComponent; -use ui_components::{button, Component, MouseEventHandler, Options as _}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::color::contrast::relative_luminance; @@ -18,6 +14,10 @@ use galaxyui_core::keymap::Keystroke; use galaxyui_core::prelude::*; use galaxyui_core::ui_components::checkbox::Checkbox as WarpCheckbox; use galaxyui_core::ui_components::components::{UiComponent as _, UiComponentStyles}; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use ui_components::button::Button as ButtonComponent; +use ui_components::{button, Component, MouseEventHandler, Options as _}; const CALLOUT_WIDTH: f32 = 480.; const CALLOUT_BORDER_WIDTH: f32 = 1.; diff --git a/crates/onboarding/src/model.rs b/crates/onboarding/src/model.rs index 72ba5624..baf6364d 100644 --- a/crates/onboarding/src/model.rs +++ b/crates/onboarding/src/model.rs @@ -1,4 +1,5 @@ use ai::LLMId; +use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxyui_core::{Entity, ModelContext}; @@ -658,7 +659,6 @@ impl OnboardingStateModel { default_model_id: LLMId, ctx: &mut ModelContext, ) { - // If the user is past the agent slide, don't change the agent model from underneath them. // When the new settings modes flag is on, ThemePicker comes after the agent slides // so it must also be guarded. @@ -990,7 +990,6 @@ impl OnboardingStateModel { /// The `(step_index, step_count)` shown by the bottom-nav progress dots for the /// current step, intention, and flow variant. pub(crate) fn progress(&self) -> (usize, usize) { - let is_terminal = matches!(self.intention, OnboardingIntention::Terminal); if !FeatureFlag::OpenWarpNewSettingsModes.is_enabled() { // Legacy flow: ThemePicker → Intention → Agent → Project. diff --git a/crates/onboarding/src/slides/agent_slide.rs b/crates/onboarding/src/slides/agent_slide.rs index f55ba0f5..428f4379 100644 --- a/crates/onboarding/src/slides/agent_slide.rs +++ b/crates/onboarding/src/slides/agent_slide.rs @@ -1,9 +1,7 @@ use ai::LLMId; -use galaxy_core::ui::icons::Icon; -use pathfinder_color::ColorU; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; +use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; use galaxyui_core::elements::{ @@ -22,6 +20,8 @@ use galaxyui_core::ui_components::components::{UiComponent as _, UiComponentStyl use galaxyui_core::{ AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use pathfinder_color::ColorU; +use ui_components::{button, Component as _, Options as _}; use super::two_line_button::{render_two_line_button, TwoLineButtonSpec}; use super::OnboardingSlide; diff --git a/crates/onboarding/src/slides/ai_access_slide.rs b/crates/onboarding/src/slides/ai_access_slide.rs index 4c29b975..85e79cf9 100644 --- a/crates/onboarding/src/slides/ai_access_slide.rs +++ b/crates/onboarding/src/slides/ai_access_slide.rs @@ -1,4 +1,3 @@ -use ui_components::{button, Component as _, Options as _}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; @@ -18,6 +17,7 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use ui_components::{button, Component as _, Options as _}; use super::OnboardingSlide; use crate::model::{AiAccessChoice, OnboardingAuthState, OnboardingStateModel}; @@ -410,7 +410,7 @@ impl AiAccessSlide { }; let icon = ConstrainedBox::new(Box::new( - Icon::AlertCircle.to_warpui_icon(Fill::Solid(text_color)), + Icon::AlertCircle.to_galaxyui_icon(Fill::Solid(text_color)), )) .with_width(ICON_SIZE) .with_height(ICON_SIZE) diff --git a/crates/onboarding/src/slides/ai_setup_slide.rs b/crates/onboarding/src/slides/ai_setup_slide.rs index a9b298eb..2dba58da 100644 --- a/crates/onboarding/src/slides/ai_setup_slide.rs +++ b/crates/onboarding/src/slides/ai_setup_slide.rs @@ -1,4 +1,3 @@ -use ui_components::{button, Component as _, Options as _}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; @@ -18,6 +17,7 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use ui_components::{button, Component as _, Options as _}; use super::OnboardingSlide; use crate::model::{AiSetupChoice, OnboardingStateModel}; @@ -99,7 +99,7 @@ impl AiSetupSlide { let theme = appearance.theme(); let logo_fill = internal_colors::fg_overlay_4(theme); - let logo = ConstrainedBox::new(Icon::WarpLogoLight.to_warpui_icon(logo_fill).finish()) + let logo = ConstrainedBox::new(Icon::WarpLogoLight.to_galaxyui_icon(logo_fill).finish()) .with_width(64.) .with_height(64.) .finish(); @@ -290,10 +290,11 @@ impl AiSetupSlide { .with_main_axis_size(MainAxisSize::Min) .with_cross_axis_alignment(CrossAxisAlignment::Start); for &item in WARP_AGENT_FEATURES { - let icon_el = ConstrainedBox::new(Icon::Check.to_warpui_icon(check_fill).finish()) - .with_width(16.) - .with_height(16.) - .finish(); + let icon_el = + ConstrainedBox::new(Icon::Check.to_galaxyui_icon(check_fill).finish()) + .with_width(16.) + .with_height(16.) + .finish(); let text_el = appearance .ui_builder() .paragraph(item.to_string()) diff --git a/crates/onboarding/src/slides/customize_slide.rs b/crates/onboarding/src/slides/customize_slide.rs index b67c86ce..68f06aca 100644 --- a/crates/onboarding/src/slides/customize_slide.rs +++ b/crates/onboarding/src/slides/customize_slide.rs @@ -1,4 +1,3 @@ -use ui_components::{button, Component as _, Options as _}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -15,6 +14,7 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use ui_components::{button, Component as _, Options as _}; use super::toggle_card::{render_toggle_card, ChipSpec, ToggleCardSpec}; use super::OnboardingSlide; diff --git a/crates/onboarding/src/slides/intention_slide.rs b/crates/onboarding/src/slides/intention_slide.rs index 4c05b6c4..f6c17f4d 100644 --- a/crates/onboarding/src/slides/intention_slide.rs +++ b/crates/onboarding/src/slides/intention_slide.rs @@ -1,4 +1,3 @@ -use ui_components::{button, Component as _, Options as _}; use galaxy_core::features::FeatureFlag; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -19,6 +18,7 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use ui_components::{button, Component as _, Options as _}; use super::OnboardingSlide; use crate::model::{NoAiConfirmationSource, OnboardingStateModel}; diff --git a/crates/onboarding/src/slides/intro_slide.rs b/crates/onboarding/src/slides/intro_slide.rs index fcce5669..d7a651d3 100644 --- a/crates/onboarding/src/slides/intro_slide.rs +++ b/crates/onboarding/src/slides/intro_slide.rs @@ -1,6 +1,3 @@ -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::vec2f; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -20,6 +17,9 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use pathfinder_color::ColorU; +use pathfinder_geometry::vector::vec2f; +use ui_components::{button, Component as _, Options as _}; use super::OnboardingSlide; use crate::model::OnboardingStateModel; diff --git a/crates/onboarding/src/slides/layout.rs b/crates/onboarding/src/slides/layout.rs index 22637691..f8ba6159 100644 --- a/crates/onboarding/src/slides/layout.rs +++ b/crates/onboarding/src/slides/layout.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::{vec2f, Vector2F}; use galaxyui_core::assets::asset_cache::AssetSource; use galaxyui_core::elements::{ Align, CacheOption, Clipped, ConstrainedBox, Container, CrossAxisAlignment, Empty, Expanded, @@ -10,6 +9,7 @@ use galaxyui_core::{ AfterLayoutContext, AppContext, Element, EventContext, LayoutContext, PaintContext, SizeConstraint, }; +use pathfinder_geometry::vector::{vec2f, Vector2F}; // Onboarding images live under `app/assets/async/` so they are excluded from the WASM // binary (RustEmbed excludes `async/**` on wasm targets). They are still bundled normally diff --git a/crates/onboarding/src/slides/project_slide.rs b/crates/onboarding/src/slides/project_slide.rs index 2d426fd9..f35554bc 100644 --- a/crates/onboarding/src/slides/project_slide.rs +++ b/crates/onboarding/src/slides/project_slide.rs @@ -1,4 +1,3 @@ -use ui_components::{button, keyboard_shortcut, Component as _, Options as _}; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::coloru_with_opacity; @@ -18,6 +17,7 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use ui_components::{button, keyboard_shortcut, Component as _, Options as _}; use super::OnboardingSlide; use crate::model::OnboardingStateModel; diff --git a/crates/onboarding/src/slides/theme_picker_slide.rs b/crates/onboarding/src/slides/theme_picker_slide.rs index 56e7051d..f49fb980 100644 --- a/crates/onboarding/src/slides/theme_picker_slide.rs +++ b/crates/onboarding/src/slides/theme_picker_slide.rs @@ -1,10 +1,8 @@ -use pathfinder_color::ColorU; -use ui_components::{button, Component as _, Options as _}; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui_core::elements::{ Border, ClippedScrollStateHandle, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, FormattedTextElement, Hoverable, MainAxisAlignment, MainAxisSize, @@ -18,6 +16,8 @@ use galaxyui_core::ui_components::components::{UiComponent, UiComponentStyles}; use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity, TypedActionView, View, ViewContext, }; +use pathfinder_color::ColorU; +use ui_components::{button, Component as _, Options as _}; use super::OnboardingSlide; use crate::model::{OnboardingStateEvent, OnboardingStateModel}; diff --git a/crates/onboarding/src/slides/third_party_slide.rs b/crates/onboarding/src/slides/third_party_slide.rs index cb9a2244..6e064174 100644 --- a/crates/onboarding/src/slides/third_party_slide.rs +++ b/crates/onboarding/src/slides/third_party_slide.rs @@ -1,4 +1,3 @@ -use ui_components::{button, Component as _, Options as _}; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxyui_core::elements::{ @@ -14,6 +13,7 @@ use galaxyui_core::{ AppContext, Element, Entity, ModelHandle, SingletonEntity as _, TypedActionView, View, ViewContext, }; +use ui_components::{button, Component as _, Options as _}; use super::toggle_card::{render_toggle_card, ToggleCardSpec}; use super::OnboardingSlide; diff --git a/crates/onboarding/src/slides/toggle_card.rs b/crates/onboarding/src/slides/toggle_card.rs index 21a844b4..f2c9e96c 100644 --- a/crates/onboarding/src/slides/toggle_card.rs +++ b/crates/onboarding/src/slides/toggle_card.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::Vector2F; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; use galaxy_core::ui::theme::Fill; @@ -13,6 +12,7 @@ use galaxyui_core::prelude::Align; use galaxyui_core::presenter::EventContext; use galaxyui_core::text_layout::TextAlignment; use galaxyui_core::{AppContext, Element}; +use pathfinder_geometry::vector::Vector2F; pub(super) type ClickCallback = Box; pub(super) type HoverCallback = diff --git a/crates/onboarding/src/slides/two_line_button.rs b/crates/onboarding/src/slides/two_line_button.rs index 995fdbf1..8caf2c5c 100644 --- a/crates/onboarding/src/slides/two_line_button.rs +++ b/crates/onboarding/src/slides/two_line_button.rs @@ -1,4 +1,3 @@ -use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::color::internal_colors; @@ -11,6 +10,7 @@ use galaxyui_core::elements::{ use galaxyui_core::fonts::{Properties, Weight}; use galaxyui_core::platform::Cursor; use galaxyui_core::Element; +use pathfinder_geometry::vector::vec2f; use super::agent_slide::AgentSlideAction; diff --git a/crates/onboarding/src/visuals/agent_visual.rs b/crates/onboarding/src/visuals/agent_visual.rs index 8c7c0159..bccd7fb8 100644 --- a/crates/onboarding/src/visuals/agent_visual.rs +++ b/crates/onboarding/src/visuals/agent_visual.rs @@ -1,8 +1,6 @@ use galaxyui::elements::Align; use galaxyui::Element; use pathfinder_color::ColorU; -use galaxyui_core::elements::Align; -use galaxyui_core::Element; use super::onboarding_visual::{OnboardingVisual, Pill, RectPct}; diff --git a/crates/onboarding/src/visuals/intention_terminal_visual.rs b/crates/onboarding/src/visuals/intention_terminal_visual.rs index dc6f43ca..1f8b603b 100644 --- a/crates/onboarding/src/visuals/intention_terminal_visual.rs +++ b/crates/onboarding/src/visuals/intention_terminal_visual.rs @@ -1,8 +1,6 @@ use galaxyui::elements::Align; use galaxyui::Element; use pathfinder_color::ColorU; -use galaxyui_core::elements::Align; -use galaxyui_core::Element; use super::onboarding_visual::{OnboardingVisual, Pill, RectPct}; use crate::visuals::onboarding_visual::Rect; diff --git a/crates/onboarding/src/visuals/intention_visual.rs b/crates/onboarding/src/visuals/intention_visual.rs index b76366fc..d6f6760a 100644 --- a/crates/onboarding/src/visuals/intention_visual.rs +++ b/crates/onboarding/src/visuals/intention_visual.rs @@ -1,8 +1,6 @@ use galaxyui::elements::Align; use galaxyui::Element; use pathfinder_color::ColorU; -use galaxyui_core::elements::Align; -use galaxyui_core::Element; use super::onboarding_visual::{OnboardingVisual, Pill, RectPct}; diff --git a/crates/onboarding/src/visuals/onboarding_visual.rs b/crates/onboarding/src/visuals/onboarding_visual.rs index 2208f196..72aae77e 100644 --- a/crates/onboarding/src/visuals/onboarding_visual.rs +++ b/crates/onboarding/src/visuals/onboarding_visual.rs @@ -1,4 +1,3 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::Icon; use galaxyui_core::assets::asset_cache::{AssetCache, AssetSource, AssetState}; use galaxyui_core::elements::{CornerRadius, Fill, Point, Radius}; @@ -10,6 +9,7 @@ use galaxyui_core::{ AfterLayoutContext, AppContext, Element, EventContext, LayoutContext, PaintContext, SingletonEntity as _, SizeConstraint, }; +use pathfinder_color::ColorU; #[derive(Debug, Clone, Copy)] pub(crate) struct RectPct { diff --git a/crates/onboarding/src/visuals/project_visual.rs b/crates/onboarding/src/visuals/project_visual.rs index d0ab245e..fd77800a 100644 --- a/crates/onboarding/src/visuals/project_visual.rs +++ b/crates/onboarding/src/visuals/project_visual.rs @@ -2,8 +2,6 @@ use galaxy_core::ui::Icon; use galaxyui::elements::Align; use galaxyui::Element; use pathfinder_color::ColorU; -use galaxyui_core::elements::Align; -use galaxyui_core::Element; use super::onboarding_visual::{IconPct, OnboardingVisual, Pill, RectPct}; diff --git a/crates/persistence/src/model.rs b/crates/persistence/src/model.rs index d3851271..52f5b6d0 100644 --- a/crates/persistence/src/model.rs +++ b/crates/persistence/src/model.rs @@ -1021,7 +1021,7 @@ fn is_false(value: &bool) -> bool { } // Serializes to `conversation_data` column in `agent_conversations`. -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, Default)] pub struct AgentConversationData { pub server_conversation_token: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -1080,6 +1080,12 @@ pub struct AgentConversationData { /// pill bar. Orchestrator conversations always serialize as `false`. #[serde(default, skip_serializing_if = "is_false")] pub pinned: bool, + /// Progressive summary of older conversation messages. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub progressive_summary: Option, + /// Number of messages that were summarized into progressive_summary. + #[serde(default)] + pub messages_summarized_up_to: usize, } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -1479,6 +1485,14 @@ pub struct ConversationUsageMetadata { pub tool_usage_metadata: ToolUsageMetadata, #[serde(default)] pub context_window_segments: Vec, + #[serde(default)] + pub total_cache_read_tokens: u32, + #[serde(default)] + pub total_cache_write_tokens: u32, + #[serde(default)] + pub total_cache_miss_tokens: u32, + #[serde(default)] + pub total_cost_cents: f32, } impl ConversationUsageMetadata { diff --git a/crates/persistence/src/model_tests.rs b/crates/persistence/src/model_tests.rs index df0dd52d..5d80178a 100644 --- a/crates/persistence/src/model_tests.rs +++ b/crates/persistence/src/model_tests.rs @@ -120,6 +120,8 @@ fn agent_conversation_data_roundtrips_last_event_sequence() { autoexecute_override: None, last_event_sequence: Some(42), pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }; let json = serde_json::to_string(&data).expect("serialize"); let roundtripped: AgentConversationData = serde_json::from_str(&json).expect("deserialize"); @@ -157,6 +159,8 @@ fn agent_conversation_data_roundtrips_remote_child_marker() { autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }; let json = serde_json::to_string(&data).expect("serialize"); let roundtripped: AgentConversationData = serde_json::from_str(&json).expect("deserialize"); @@ -181,6 +185,8 @@ fn agent_conversation_data_roundtrips_optimistic_root_marker() { autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }; let json = serde_json::to_string(&data).expect("serialize"); let roundtripped: AgentConversationData = serde_json::from_str(&json).expect("deserialize"); @@ -217,6 +223,8 @@ fn agent_conversation_data_skips_serializing_none_last_event_sequence() { autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }; let json = serde_json::to_string(&data).expect("serialize"); assert!( @@ -243,6 +251,8 @@ fn agent_conversation_data_roundtrips_pinned() { autoexecute_override: None, last_event_sequence: None, pinned: true, + progressive_summary: None, + messages_summarized_up_to: 0, }; let json = serde_json::to_string(&data).expect("serialize"); let roundtripped: AgentConversationData = serde_json::from_str(&json).expect("deserialize"); @@ -267,6 +277,8 @@ fn agent_conversation_data_skips_serializing_unpinned() { autoexecute_override: None, last_event_sequence: None, pinned: false, + progressive_summary: None, + messages_summarized_up_to: 0, }; let json = serde_json::to_string(&data).expect("serialize"); assert!( diff --git a/crates/remote_server/src/auth.rs b/crates/remote_server/src/auth.rs index 3d7d13fd..d81247cf 100644 --- a/crates/remote_server/src/auth.rs +++ b/crates/remote_server/src/auth.rs @@ -1,4 +1,3 @@ -use galaxyui::r#async::BoxFuture; use std::sync::Arc; use galaxyui_core::r#async::BoxFuture; diff --git a/crates/remote_server/src/client/mod.rs b/crates/remote_server/src/client/mod.rs index 0a713544..5413dd2f 100644 --- a/crates/remote_server/src/client/mod.rs +++ b/crates/remote_server/src/client/mod.rs @@ -26,11 +26,11 @@ use crate::repo_metadata_proto::{proto_snapshot_to_update, proto_to_repo_metadat #[cfg(not(target_family = "wasm"))] mod remote_server_log; +use galaxy_core::{safe_error, safe_warn, SessionId}; +use galaxy_util::standardized_path::StandardizedPath; +use galaxyui_core::r#async::TransportStream; #[cfg(not(target_family = "wasm"))] pub use remote_server_log::RemoteServerLog; -use galaxy_core::{safe_error, safe_warn, SessionId}; -use warp_util::standardized_path::StandardizedPath; -use galaxyui_core::r#async::TransportStream; use crate::protocol::{self, ProtocolError, RequestId}; diff --git a/crates/remote_server/src/client_tests.rs b/crates/remote_server/src/client_tests.rs index a17e23c6..46546275 100644 --- a/crates/remote_server/src/client_tests.rs +++ b/crates/remote_server/src/client_tests.rs @@ -1,7 +1,7 @@ use futures::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; -use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt}; use galaxy_core::SessionId; use galaxyui_core::r#async::executor; +use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt}; use super::*; use crate::proto::{ diff --git a/crates/remote_server/src/manager.rs b/crates/remote_server/src/manager.rs index a2b604ab..51849412 100644 --- a/crates/remote_server/src/manager.rs +++ b/crates/remote_server/src/manager.rs @@ -5,16 +5,16 @@ use std::sync::Arc; use std::time::Duration; use futures::channel::oneshot; -use repo_metadata::RepoMetadataUpdate; -use serde::Serialize; #[cfg(not(target_family = "wasm"))] use galaxy_core::channel::ChannelState; use galaxy_core::SessionId; -use warp_util::remote_path::{RemoteNavigationResult, RemotePath}; -use warp_util::standardized_path::StandardizedPath; +use galaxy_util::remote_path::{RemoteNavigationResult, RemotePath}; +use galaxy_util::standardized_path::StandardizedPath; #[cfg(not(target_family = "wasm"))] use galaxyui_core::r#async::FutureExt as _; use galaxyui_core::{Entity, ModelContext, ModelSpawner, SingletonEntity}; +use repo_metadata::RepoMetadataUpdate; +use serde::Serialize; use crate::auth::RemoteServerAuthContext; #[cfg(not(target_family = "wasm"))] @@ -759,6 +759,7 @@ pub enum HostRequestError { impl From for HostRequestError { fn from(err: crate::client::ClientError) -> Self { + use crate::client::ClientError; match err { ClientError::Disconnected | ClientError::ResponseChannelClosed => { Self::AllSessionsDisconnected @@ -3786,6 +3787,7 @@ impl RemoteServerManager { let code = status.code(); #[cfg(unix)] let signal_killed = { + use std::os::unix::process::ExitStatusExt; status.signal().is_some() }; #[cfg(not(unix))] diff --git a/crates/remote_server/src/manager_tests.rs b/crates/remote_server/src/manager_tests.rs index cb323f25..745fe697 100644 --- a/crates/remote_server/src/manager_tests.rs +++ b/crates/remote_server/src/manager_tests.rs @@ -1,6 +1,6 @@ use futures::channel::oneshot; use galaxy_core::SessionId; -use warp_util::standardized_path::StandardizedPath; +use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::App; use super::{ diff --git a/crates/remote_server/src/repo_metadata_proto_tests.rs b/crates/remote_server/src/repo_metadata_proto_tests.rs index 09a49bff..0ffd68a0 100644 --- a/crates/remote_server/src/repo_metadata_proto_tests.rs +++ b/crates/remote_server/src/repo_metadata_proto_tests.rs @@ -1,6 +1,6 @@ +use galaxy_util::standardized_path::StandardizedPath; use repo_metadata::file_tree_update::RepoMetadataUpdate; use repo_metadata::{StandingQueryContent, StandingQueryResultsDelta}; -use warp_util::standardized_path::StandardizedPath; use super::{proto_snapshot_to_update, proto_to_repo_metadata_update}; use crate::proto; diff --git a/crates/remote_server/src/setup.rs b/crates/remote_server/src/setup.rs index 8e619d76..92b07224 100644 --- a/crates/remote_server/src/setup.rs +++ b/crates/remote_server/src/setup.rs @@ -3,8 +3,8 @@ mod glibc; use std::time::Duration; use anyhow::anyhow; -pub use glibc::{GlibcVersion, RemoteLibc}; use galaxy_core::channel::{Channel, ChannelState}; +pub use glibc::{GlibcVersion, RemoteLibc}; pub const REMOTE_SERVER_ARTIFACT_VERSION_UNPINNED: &str = "unversioned"; /// State machine for the remote server install → launch → initialize flow. @@ -424,7 +424,7 @@ pub fn remote_server_daemon_data_dir(identity_key: &str) -> String { /// Linux, 103 on macOS) for users with moderately long identity keys or /// home directory paths. pub fn version_hash() -> Option { - + use std::hash::{Hash, Hasher}; let version = ChannelState::app_version()?; let mut hasher = std::collections::hash_map::DefaultHasher::new(); version.hash(&mut hasher); diff --git a/crates/remote_server/src/transport.rs b/crates/remote_server/src/transport.rs index 22ae4a2c..ef17dfd3 100644 --- a/crates/remote_server/src/transport.rs +++ b/crates/remote_server/src/transport.rs @@ -16,8 +16,8 @@ use std::path::PathBuf; use std::pin::Pin; use async_channel::Receiver; -use serde::Serialize; use galaxyui_core::r#async::executor; +use serde::Serialize; #[cfg(not(target_family = "wasm"))] use crate::client::RemoteServerLog; diff --git a/crates/repo_metadata/src/entry.rs b/crates/repo_metadata/src/entry.rs index c4fc1cc9..8a5adc4b 100644 --- a/crates/repo_metadata/src/entry.rs +++ b/crates/repo_metadata/src/entry.rs @@ -7,13 +7,13 @@ use std::sync::atomic::{AtomicUsize, Ordering}; #[cfg(feature = "local_fs")] use std::sync::Arc; +use galaxy_util::standardized_path::StandardizedPath; use ignore::gitignore::Gitignore; #[cfg(feature = "local_fs")] use notify_debouncer_full::notify::WatchFilter; use thiserror::Error; use crate::standing_queries::{StandingQueryDefinitions, StandingQueryResults}; -use galaxy_util::standardized_path::StandardizedPath; /// Maximum file size allowed for treesitter parsing (3MB). const MAX_FILE_SIZE: usize = 3 * 1000 * 1000; diff --git a/crates/repo_metadata/src/entry_tests.rs b/crates/repo_metadata/src/entry_tests.rs index d5bfd81d..516917d3 100644 --- a/crates/repo_metadata/src/entry_tests.rs +++ b/crates/repo_metadata/src/entry_tests.rs @@ -1,4 +1,5 @@ use std::fs; +use std::path::Path; use ignore::gitignore::Gitignore; @@ -791,7 +792,6 @@ fn lazy_loaded_ignored_directory_marks_loaded_children_as_ignored() { #[test] fn should_watch_directory_in_git_path_prunes_non_allowlisted_subtrees() { - use super::should_watch_directory_in_git_path; for path in [ "/repo/.git", @@ -845,7 +845,6 @@ fn should_watch_directory_in_git_path_prunes_non_allowlisted_subtrees() { /// emit predicate only suppresses non-allowlisted `.git/` internals). #[test] fn gitignore_affects_descend_predicate_but_not_emitted_events() { - use super::{gitignores_for_directory, should_ignore_git_path, should_watch_repo_directory}; let temp_dir = tempfile::tempdir().unwrap(); @@ -879,7 +878,6 @@ fn gitignore_affects_descend_predicate_but_not_emitted_events() { #[test] fn test_is_shared_git_ref() { - use super::is_shared_git_ref; // Shared refs — broadcast to all repos diff --git a/crates/repo_metadata/src/file_tree_store.rs b/crates/repo_metadata/src/file_tree_store.rs index 5c48d939..e9394141 100644 --- a/crates/repo_metadata/src/file_tree_store.rs +++ b/crates/repo_metadata/src/file_tree_store.rs @@ -2,9 +2,9 @@ mod file_tree_state; use std::sync::Arc; -use ignore::gitignore::Gitignore; use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::ModelHandle; +use ignore::gitignore::Gitignore; use crate::file_tree_store::file_tree_state::FileTreeMapStore; use crate::{BuildTreeError, Entry, FileId, FileMetadata, Repository}; diff --git a/crates/repo_metadata/src/file_tree_store/file_tree_state.rs b/crates/repo_metadata/src/file_tree_store/file_tree_state.rs index 1dfa6004..2861afe4 100644 --- a/crates/repo_metadata/src/file_tree_store/file_tree_state.rs +++ b/crates/repo_metadata/src/file_tree_store/file_tree_state.rs @@ -2,8 +2,8 @@ use std::collections::{HashMap, HashSet}; use std::iter; use std::sync::Arc; -use ignore::gitignore::Gitignore; use galaxy_util::standardized_path::StandardizedPath; +use ignore::gitignore::Gitignore; use crate::file_tree_store::{FileTreeDirectoryEntryState, FileTreeEntry, FileTreeEntryState}; use crate::{BuildTreeError, DirectoryEntry, Entry}; diff --git a/crates/repo_metadata/src/file_tree_update_tests.rs b/crates/repo_metadata/src/file_tree_update_tests.rs index d0027f01..9669c5fc 100644 --- a/crates/repo_metadata/src/file_tree_update_tests.rs +++ b/crates/repo_metadata/src/file_tree_update_tests.rs @@ -5,7 +5,7 @@ use galaxy_util::standardized_path::StandardizedPath; use crate::entry::{DirectoryEntry, Entry, FileId, FileMetadata}; use crate::file_tree_store::{FileTreeEntry, FileTreeEntryState}; use crate::file_tree_update::*; -use crate::local_model::LocalRepoMetadataModel; +use crate::local_model::{FileTreeMutation, LocalRepoMetadataModel}; // ── Helpers ────────────────────────────────────────────────────────── @@ -148,7 +148,6 @@ fn apply_mutations_generates_update_for_remove() { #[test] fn apply_mutations_generates_update_for_add_file() { - let initial = dir("/repo", vec![dir("/repo/src", vec![])]); let mut tree = build_tree_from_entry(initial); let mutations = vec![FileTreeMutation::AddFile { @@ -178,7 +177,6 @@ fn apply_mutations_generates_update_for_add_file() { #[test] fn apply_mutations_generates_update_for_add_directory_subtree() { - let subtree = dir( "/repo/src/components", vec![ @@ -212,7 +210,6 @@ fn apply_mutations_generates_update_for_add_directory_subtree() { #[test] fn apply_mutations_generates_update_for_add_empty_directory() { - let initial = dir("/repo", vec![dir("/repo/src", vec![])]); let mut tree = build_tree_from_entry(initial); let mutations = vec![FileTreeMutation::AddUnloadedDirectory { @@ -236,7 +233,6 @@ fn apply_mutations_generates_update_for_add_empty_directory() { #[test] fn apply_mutations_generates_update_for_mixed_mutations() { - let initial = dir("/repo", vec![file("/repo/old.rs")]); let mut tree = build_tree_from_entry(initial); let mutations = vec![ @@ -262,7 +258,6 @@ fn apply_mutations_generates_update_for_mixed_mutations() { #[test] fn apply_mutations_returns_none_when_emit_updates_is_false() { - let initial = dir("/repo", vec![file("/repo/old.rs")]); let mut tree = build_tree_from_entry(initial); let mutations = vec![FileTreeMutation::Remove(mutation_path("/repo/old.rs"))]; @@ -477,7 +472,6 @@ fn apply_incomplete_update_missing_parent_from_undelivered_page() { #[test] fn round_trip_apply_mutations_then_apply_update_produces_equivalent_tree() { - let server_tree_entry = dir( "/repo", vec![dir("/repo/src", vec![file("/repo/src/lib.rs")])], @@ -546,7 +540,6 @@ fn round_trip_apply_mutations_then_apply_update_produces_equivalent_tree() { #[test] fn lazy_load_filters_mutations_for_unloaded_parents() { - let initial = Entry::Directory(DirectoryEntry { path: std_path("/repo"), children: vec![ diff --git a/crates/repo_metadata/src/lib.rs b/crates/repo_metadata/src/lib.rs index 809f10e3..d0aa6e42 100644 --- a/crates/repo_metadata/src/lib.rs +++ b/crates/repo_metadata/src/lib.rs @@ -6,9 +6,9 @@ use std::borrow::Borrow; use std::path::{Path, PathBuf}; use galaxy_util::standardized_path::StandardizedPath; -use thiserror::Error; #[cfg(not(target_family = "wasm"))] use galaxyui_core::SingletonEntity; +use thiserror::Error; /// Errors that can occur when working with repository metadata. #[derive(Error, Debug)] diff --git a/crates/repo_metadata/src/local_model.rs b/crates/repo_metadata/src/local_model.rs index 4ae81e54..d5f51d60 100644 --- a/crates/repo_metadata/src/local_model.rs +++ b/crates/repo_metadata/src/local_model.rs @@ -61,8 +61,8 @@ cfg_if::cfg_if! { } } -use ignore::gitignore::Gitignore; use galaxyui_core::ModelContext; +use ignore::gitignore::Gitignore; use crate::file_tree_store::{ FileTreeDirectoryEntryState, FileTreeEntry, FileTreeEntryState, FileTreeFileMetadata, diff --git a/crates/repo_metadata/src/local_model_test.rs b/crates/repo_metadata/src/local_model_test.rs deleted file mode 100644 index c5341174..00000000 --- a/crates/repo_metadata/src/local_model_test.rs +++ /dev/null @@ -1,1256 +0,0 @@ -//! Tests for the LocalRepoMetadataModel. - -#[cfg(test)] -#[allow(clippy::module_inception)] -mod tests { - use crate::entry::{DirectoryEntry, Entry, FileMetadata}; - use crate::file_tree_store::{FileTreeEntry, FileTreeEntryState, FileTreeState}; - use crate::local_model::{ - GetContentsArgs, IndexedRepoState, LocalRepoMetadataModel, RepoUpdate, - RepositoryMetadataEvent, - }; - use crate::repositories::DetectedRepositories; - use crate::watcher::DirectoryWatcher; - use futures::channel::oneshot; - use futures::executor::block_on; - use galaxy_util::standardized_path::StandardizedPath; - use galaxyui_core::r#async::FutureExt as _; - use galaxyui_core::App; - use ignore::gitignore::Gitignore; - use std::cell::RefCell; - use std::collections::HashMap; - use std::path::PathBuf; - use std::rc::Rc; - use std::time::Duration; - use virtual_fs::{Stub, VirtualFS}; - - impl LocalRepoMetadataModel { - fn new_for_test() -> Self { - Self { - repositories: HashMap::new(), - lazy_loaded_paths: Default::default(), - #[cfg(feature = "local_fs")] - watcher: Default::default(), - emit_incremental_updates: false, - } - } - } - - #[test] - fn test_get_repo_contents() { - VirtualFS::test("repo_contents_test", |dirs, mut vfs| { - let test_repo = dirs.tests().join("test_repo"); - - // Create a test repository structure using VirtualFS with .git directory - vfs.mkdir("test_repo/.git/objects") - .mkdir("test_repo/subdir") - .with_files(vec![ - Stub::FileWithContent("test_repo/.git/HEAD", "ref: refs/heads/main"), - Stub::FileWithContent( - "test_repo/.git/config", - "[core]\n\trepositoryformatversion = 0", - ), - Stub::FileWithContent("test_repo/file1.txt", "content1"), - Stub::FileWithContent("test_repo/subdir/file2.rs", "content2"), - Stub::FileWithContent("test_repo/subdir/file3.py", "content3"), - Stub::FileWithContent("test_repo/file4.md", "content4"), - Stub::FileWithContent("test_repo/.gitignore", ""), - ]); - - // Create a mock file tree structure - let file1 = Entry::File(FileMetadata::new(test_repo.join("file1.txt"), false)); - let file2 = Entry::File(FileMetadata::new(test_repo.join("subdir/file2.rs"), false)); - let file3 = Entry::File(FileMetadata::new(test_repo.join("subdir/file3.py"), false)); - let file4 = Entry::File(FileMetadata::new(test_repo.join("file4.md"), false)); - - let subdir = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo.join("subdir")).unwrap(), - children: vec![file2, file3], - ignored: false, - loaded: true, - }); - - let root = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo).unwrap(), - children: vec![file1, subdir, file4], - ignored: false, - loaded: true, - }); - - let (gitignore, _) = Gitignore::new(test_repo.join(".gitignore")); - - App::test((), |mut app| async move { - // Create RepoWatcher and get Repository handle through it - let repo_watcher = app.add_singleton_model(DirectoryWatcher::new); - let repo_handle = repo_watcher.update(&mut app, |repo_watcher, ctx| { - repo_watcher - .add_directory( - StandardizedPath::from_local_canonicalized(&test_repo).unwrap(), - ctx, - ) - .unwrap() - }); - let state = FileTreeState::new(root, vec![gitignore], Some(repo_handle)); - - let model_handle = app.add_model(|_| LocalRepoMetadataModel::new_for_test()); - - model_handle.update(&mut app, |model, _ctx| { - // Use the CanonicalizedPath as the key - let canonical_key = - StandardizedPath::from_local_canonicalized(&test_repo).unwrap(); - model - .repositories - .insert(canonical_key, IndexedRepoState::Indexed(state)); - }); - - // Test getting all files - model_handle.read(&app, |model, _ctx| { - let args = GetContentsArgs { - include_folders: false, - include_ignored: false, - filter: None, - }; - let files = model - .get_repo_contents( - &StandardizedPath::from_local_canonicalized(&test_repo).unwrap(), - args, - ) - .unwrap(); - - // Should have 4 files total (file1.txt, file2.rs, file3.py, file4.md) - assert_eq!(files.len(), 4); - - // Test with non-existent repository - let non_existent = StandardizedPath::try_new("/non_existent_repo").unwrap(); - let args = GetContentsArgs { - include_folders: false, - include_ignored: false, - filter: None, - }; - let non_existent_result = model.get_repo_contents(&non_existent, args); - assert!(non_existent_result.is_none()); - }); - }); - }); - } - - #[cfg(feature = "local_fs")] - #[test] - fn test_lazy_loaded_path_registrations_are_refcounted() { - VirtualFS::test("lazy_loaded_path_refcount", |dirs, mut vfs| { - vfs.mkdir("shared_dir") - .with_files(vec![Stub::FileWithContent( - "shared_dir/file.txt", - "content", - )]); - - let shared_dir = dirs.tests().join("shared_dir"); - - App::test((), |mut app| async move { - let model_handle = app.add_model(|_| LocalRepoMetadataModel::new_for_test()); - - let shared_dir_for_index = - StandardizedPath::from_local_canonicalized(&shared_dir).unwrap(); - model_handle.update(&mut app, |model, ctx| { - model - .index_lazy_loaded_path(&shared_dir_for_index, ctx) - .unwrap(); - model - .index_lazy_loaded_path(&shared_dir_for_index, ctx) - .unwrap(); - }); - - model_handle.read(&app, |model, _ctx| { - assert!(model.is_lazy_loaded_path( - &StandardizedPath::from_local_canonicalized(&shared_dir).unwrap() - )); - assert!(model.has_repository( - &StandardizedPath::from_local_canonicalized(&shared_dir).unwrap() - )); - }); - - let shared_dir_std = - StandardizedPath::from_local_canonicalized(&shared_dir).unwrap(); - - model_handle.update(&mut app, |model, ctx| { - model.remove_lazy_loaded_path(&shared_dir_std, ctx); - }); - - model_handle.read(&app, |model, _ctx| { - assert!(model.is_lazy_loaded_path(&shared_dir_std)); - assert!(model.has_repository(&shared_dir_std)); - }); - - model_handle.update(&mut app, |model, ctx| { - model.remove_lazy_loaded_path(&shared_dir_std, ctx); - }); - - model_handle.read(&app, |model, _ctx| { - assert!(!model.is_lazy_loaded_path( - &StandardizedPath::from_local_canonicalized(&shared_dir).unwrap() - )); - assert!(!model.has_repository( - &StandardizedPath::from_local_canonicalized(&shared_dir).unwrap() - )); - }); - }); - }); - } - - #[cfg(feature = "local_fs")] - #[test] - fn test_index_directory_upgrades_lazy_loaded_path_to_repo() { - VirtualFS::test("lazy_loaded_path_upgrade", |dirs, mut vfs| { - vfs.mkdir("repo/.git/objects") - .mkdir("repo/src/nested") - .with_files(vec![ - Stub::FileWithContent("repo/.git/HEAD", "ref: refs/heads/main"), - Stub::FileWithContent( - "repo/.git/config", - "[core]\n\trepositoryformatversion = 0", - ), - Stub::FileWithContent("repo/src/nested/main.rs", "fn main() {}\n"), - ]); - - let repo_root = dirs.tests().join("repo"); - let src_dir = repo_root.join("src"); - let source_file = repo_root.join("src/nested/main.rs"); - - App::test((), |mut app| async move { - let directory_watcher = app.add_singleton_model(DirectoryWatcher::new); - let repository_handle = directory_watcher.update(&mut app, |watcher, ctx| { - watcher - .add_directory( - StandardizedPath::from_local_canonicalized(&repo_root).unwrap(), - ctx, - ) - .unwrap() - }); - let model_handle = app.add_model(|_| LocalRepoMetadataModel::new_for_test()); - - let repo_root_for_index = - StandardizedPath::from_local_canonicalized(&repo_root).unwrap(); - model_handle.update(&mut app, |model, ctx| { - model - .index_lazy_loaded_path(&repo_root_for_index, ctx) - .unwrap(); - }); - - model_handle.read(&app, |model, _ctx| { - assert!(model.is_lazy_loaded_path( - &StandardizedPath::from_local_canonicalized(&repo_root).unwrap() - )); - let Some(IndexedRepoState::Indexed(state)) = model.repository_state( - &StandardizedPath::from_local_canonicalized(&repo_root).unwrap(), - ) else { - panic!("expected indexed lazy-loaded path"); - }; - assert!(state - .entry - .contains(&StandardizedPath::try_from_local(&src_dir).unwrap())); - assert!(!state - .entry - .contains(&StandardizedPath::try_from_local(&source_file).unwrap())); - }); - - let (tx, rx) = oneshot::channel(); - let repo_root_for_event = repo_root.clone(); - let upgrade_completed = Rc::new(RefCell::new(Some(tx))); - let upgrade_completed_for_event = upgrade_completed.clone(); - app.update(|ctx| { - ctx.subscribe_to_model(&model_handle, move |_, event, _ctx| { - if matches!( - event, - RepositoryMetadataEvent::RepositoryUpdated { path } - if path.to_local_path().as_ref() == Some(&repo_root_for_event) - ) { - if let Some(tx) = upgrade_completed_for_event.borrow_mut().take() { - let _ = tx.send(()); - } - } - }); - }); - - model_handle.update(&mut app, |model, ctx| { - model.index_directory(repository_handle, ctx).unwrap(); - }); - rx.with_timeout(Duration::from_secs(5)) - .await - .expect("timed out waiting for repo upgrade") - .expect("repo upgrade completion sender dropped"); - - model_handle.read(&app, |model, _ctx| { - assert!(!model.is_lazy_loaded_path( - &StandardizedPath::from_local_canonicalized(&repo_root).unwrap() - )); - let Some(IndexedRepoState::Indexed(state)) = model.repository_state( - &StandardizedPath::from_local_canonicalized(&repo_root).unwrap(), - ) else { - panic!("expected indexed repo after upgrade"); - }; - assert!(state - .entry - .contains(&StandardizedPath::try_from_local(&source_file).unwrap())); - }); - }); - }); - } - - #[test] - fn test_get_repo_contents_include_ignored() { - VirtualFS::test("repo_contents_include_ignored_test", |dirs, mut vfs| { - let test_repo = dirs.tests().join("test_repo"); - - // Create a test repository structure with both ignored and non-ignored files - vfs.mkdir("test_repo/.git/objects") - .mkdir("test_repo/src") - .mkdir("test_repo/target/debug") - .mkdir("test_repo/node_modules") - .with_files(vec![ - Stub::FileWithContent("test_repo/.git/HEAD", "ref: refs/heads/main"), - Stub::FileWithContent( - "test_repo/.git/config", - "[core]\n\trepositoryformatversion = 0", - ), - Stub::FileWithContent("test_repo/src/main.rs", "fn main() {}"), - Stub::FileWithContent("test_repo/README.md", "# Project"), - Stub::FileWithContent("test_repo/target/debug/binary", "binary"), - Stub::FileWithContent("test_repo/node_modules/package.json", "{}"), - Stub::FileWithContent("test_repo/debug.log", "log"), - Stub::FileWithContent("test_repo/.gitignore", "*.log\n/target/\nnode_modules/"), - ]); - - // Create mock file tree with ignored and non-ignored entries - let main_rs = Entry::File(FileMetadata::new(test_repo.join("src/main.rs"), false)); - let readme = Entry::File(FileMetadata::new(test_repo.join("README.md"), false)); - let debug_log = Entry::File(FileMetadata::new(test_repo.join("debug.log"), true)); - let binary = Entry::File(FileMetadata::new( - test_repo.join("target/debug/binary"), - true, - )); - let package_json = Entry::File(FileMetadata::new( - test_repo.join("node_modules/package.json"), - true, - )); - - let src_dir = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo.join("src")).unwrap(), - children: vec![main_rs], - ignored: false, - loaded: true, - }); - - let debug_dir = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo.join("target/debug")).unwrap(), - children: vec![binary], - ignored: true, - loaded: true, - }); - - let target_dir = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo.join("target")).unwrap(), - children: vec![debug_dir], - ignored: true, - loaded: true, - }); - - let node_modules_dir = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo.join("node_modules")).unwrap(), - children: vec![package_json], - ignored: true, - loaded: true, - }); - - let root = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&test_repo).unwrap(), - children: vec![src_dir, readme, debug_log, target_dir, node_modules_dir], - ignored: false, - loaded: true, - }); - - let (gitignore, _) = Gitignore::new(test_repo.join(".gitignore")); - - App::test((), |mut app| async move { - let repo_watcher = app.add_singleton_model(DirectoryWatcher::new); - let repo_handle = repo_watcher.update(&mut app, |repo_watcher, ctx| { - repo_watcher - .add_directory( - StandardizedPath::from_local_canonicalized(&test_repo).unwrap(), - ctx, - ) - .unwrap() - }); - let state = FileTreeState::new(root, vec![gitignore], Some(repo_handle)); - - let model_handle = app.add_model(|_| LocalRepoMetadataModel::new_for_test()); - - model_handle.update(&mut app, |model, _ctx| { - let canonical_key = - StandardizedPath::from_local_canonicalized(&test_repo).unwrap(); - model - .repositories - .insert(canonical_key, IndexedRepoState::Indexed(state)); - }); - - // Test with include_ignored = false (should exclude ignored files and directories) - model_handle.read(&app, |model, _ctx| { - let args = GetContentsArgs { - include_folders: true, - include_ignored: false, - filter: None, - }; - let contents = model - .get_repo_contents( - &StandardizedPath::from_local_canonicalized(&test_repo).unwrap(), - args, - ) - .unwrap(); - - let paths: Vec = contents - .iter() - .map(|c| match c { - crate::RepoContent::File(f) => f.path.to_local_path_lossy(), - crate::RepoContent::Directory(d) => d.path.to_local_path_lossy(), - }) - .collect(); - - // Should include non-ignored files and directories - assert!(paths.contains(&test_repo.join("src"))); - assert!(paths.contains(&test_repo.join("src/main.rs"))); - assert!(paths.contains(&test_repo.join("README.md"))); - - // Should NOT include ignored directories or files - assert!(!paths.contains(&test_repo.join("target"))); - assert!(!paths.contains(&test_repo.join("node_modules"))); - assert!(!paths.contains(&test_repo.join("debug.log"))); - }); - - // Test with include_ignored = true (should include everything) - model_handle.read(&app, |model, _ctx| { - let args = GetContentsArgs { - include_folders: true, - include_ignored: true, - filter: None, - }; - let contents = model - .get_repo_contents( - &StandardizedPath::from_local_canonicalized(&test_repo).unwrap(), - args, - ) - .unwrap(); - - let paths: Vec = contents - .iter() - .map(|c| match c { - crate::RepoContent::File(f) => f.path.to_local_path_lossy(), - crate::RepoContent::Directory(d) => d.path.to_local_path_lossy(), - }) - .collect(); - - // Should include everything - assert!(paths.contains(&test_repo.join("src"))); - assert!(paths.contains(&test_repo.join("target"))); - assert!(paths.contains(&test_repo.join("target/debug"))); - assert!(paths.contains(&test_repo.join("node_modules"))); - assert!(paths.contains(&test_repo.join("src/main.rs"))); - assert!(paths.contains(&test_repo.join("README.md"))); - assert!(paths.contains(&test_repo.join("debug.log"))); - assert!(paths.contains(&test_repo.join("target/debug/binary"))); - assert!(paths.contains(&test_repo.join("node_modules/package.json"))); - }); - }); - }); - } - - #[test] - fn test_should_include_path_respects_gitignore() { - VirtualFS::test("gitignore_test", |dirs, mut fs| { - let repo_path = dirs.tests(); - - // Create directory structure and files using VirtualFS - fs.mkdir("src") - .mkdir("target/debug") - .mkdir("node_modules/package") - .mkdir("docs") - .with_files(vec![ - Stub::FileWithContent("debug.log", "log"), - Stub::FileWithContent("target/debug/main", "binary"), - Stub::FileWithContent("node_modules/package/index.js", "js"), - Stub::FileWithContent(".env", "env"), - Stub::FileWithContent("src/main.rs", "rust"), - Stub::FileWithContent("README.md", "readme"), - Stub::FileWithContent("package.json", "json"), - Stub::FileWithContent("docs/guide.md", "guide"), - Stub::FileWithContent(".gitignore", "*.log\n/target/\nnode_modules/\n.env"), - ]); - - let gitignore_path = repo_path.join(".gitignore"); - - // Create the gitignore object - let (gitignore, _) = Gitignore::new(&gitignore_path); - let gitignores = vec![gitignore]; - - // Test files that should be excluded - let excluded_paths = vec![ - repo_path.join("debug.log"), - repo_path.join("target").join("debug").join("main"), - repo_path - .join("node_modules") - .join("package") - .join("index.js"), - repo_path.join(".env"), - ]; - - for path in excluded_paths { - assert!( - LocalRepoMetadataModel::path_is_ignored(&path, &gitignores), - "Path should be excluded by gitignore: {path:?}" - ); - } - - // Test files that should be included - let included_paths = vec![ - repo_path.join("src").join("main.rs"), - repo_path.join("README.md"), - repo_path.join("package.json"), - repo_path.join("docs").join("guide.md"), - ]; - - for path in included_paths { - assert!( - !LocalRepoMetadataModel::path_is_ignored(&path, &gitignores), - "Path should be included: {path:?}" - ); - } - }); - } - - #[test] - fn test_update_file_tree_entry_respects_gitignore() { - VirtualFS::test("tree_update_test", |dirs, mut fs| { - let repo_path = dirs.tests(); - - // Create initial directory structure and files - fs.mkdir("src") - .with_files(vec![ - Stub::FileWithContent("src/main.rs", "fn main() {}"), - Stub::FileWithContent(".gitignore", "*.log\n/target/"), - Stub::FileWithContent("debug.log", "log content"), - Stub::FileWithContent("README.md", "# Project"), - ]) - .mkdir("target"); - - let gitignore_path = repo_path.join(".gitignore"); - let (gitignore, _) = Gitignore::new(&gitignore_path); - let gitignores = vec![gitignore]; - - // Create an initial file tree - let root_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(repo_path).unwrap(), - children: vec![Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&repo_path.join("src")).unwrap(), - children: vec![Entry::File(FileMetadata::new( - repo_path.join("src").join("main.rs"), - false, - ))], - ignored: false, - loaded: true, - })], - ignored: false, - loaded: true, - }); - let mut root = FileTreeEntry::from(root_entry); - - // Create files to test adding - some should be ignored - let log_file = repo_path.join("debug.log"); - let target_dir = repo_path.join("target"); - let readme_file = repo_path.join("README.md"); - - // Create update with both ignored and allowed files - let update = RepoUpdate { - added: vec![log_file.clone(), readme_file.clone(), target_dir.clone()], - deleted: vec![], - moved: HashMap::new(), - }; - - // Compute mutations on the "background thread" then apply on the "main thread". - let mutations = block_on(LocalRepoMetadataModel::compute_file_tree_mutations( - &update, - &gitignores, - )); - LocalRepoMetadataModel::apply_file_tree_mutations(&mut root, mutations, false, false); - - // Verify that only the README.md was added (log file and target dir should be ignored) - let mut all_paths = Vec::new(); - collect_all_paths(&root, &mut all_paths); - - // Should contain all files - let readme_std = StandardizedPath::try_from_local(&readme_file).unwrap(); - let log_std = StandardizedPath::try_from_local(&log_file).unwrap(); - let target_std = StandardizedPath::try_from_local(&target_dir).unwrap(); - assert!(all_paths.contains(&readme_std)); - assert!(all_paths.contains(&log_std)); - assert!(all_paths.contains(&target_std)); - - // Make sure that the ignored files and folders are marked as ignored. - assert!(root - .get(&StandardizedPath::try_from_local(&log_file).unwrap()) - .unwrap() - .ignored()); - assert!(root - .get(&StandardizedPath::try_from_local(&target_dir).unwrap()) - .unwrap() - .ignored()); - - // Make sure that the ignored folder is not eagerly loaded. - assert!(!root - .get(&StandardizedPath::try_from_local(&target_dir).unwrap()) - .unwrap() - .loaded()); - }); - } - - #[test] - fn test_gitignore_patterns_comprehensive() { - VirtualFS::test("comprehensive_test", |dirs, mut fs| { - let repo_path = dirs.tests(); - - // Create directory structure and files using VirtualFS - fs.mkdir("target/debug") - .mkdir("dist") - .mkdir("build") - .mkdir("logs") - .mkdir("node_modules/react") - .mkdir("vendor") - .mkdir(".vscode") - .mkdir(".idea") - .mkdir("src") - .mkdir("docs") - .mkdir("tests") - .mkdir(".github/workflows"); - - // Create a comprehensive .gitignore - let gitignore_content = r#" -# Build outputs -/target/ -/dist/ -build/ - -# Logs -*.log -logs/ - -# Dependencies -node_modules/ -/vendor/ - -# IDE files -.vscode/ -.idea/ -*.swp - -# Environment -.env -.env.local - -# OS files -.DS_Store -Thumbs.db -"#; - - // Create all files - fs.with_files(vec![ - Stub::FileWithContent("target/debug/main", "binary"), - Stub::FileWithContent("dist/bundle.js", "js"), - Stub::FileWithContent("logs/app.log", "log"), - Stub::FileWithContent("debug.log", "log"), - Stub::FileWithContent("node_modules/react/index.js", "js"), - Stub::FileWithContent(".vscode/settings.json", "json"), - Stub::FileWithContent(".env", "env"), - Stub::FileWithContent(".DS_Store", "store"), - Stub::FileWithContent("temp.swp", "swap"), - Stub::FileWithContent("src/main.rs", "rust"), - Stub::FileWithContent("README.md", "readme"), - Stub::FileWithContent("package.json", "json"), - Stub::FileWithContent("docs/guide.md", "guide"), - Stub::FileWithContent("tests/integration.rs", "test"), - Stub::FileWithContent(".github/workflows/ci.yml", "yml"), - Stub::FileWithContent(".gitignore", gitignore_content), - ]); - - let gitignore_path = repo_path.join(".gitignore"); - - let (gitignore, _) = Gitignore::new(&gitignore_path); - let gitignores = vec![gitignore]; - - // Test various patterns - let test_cases = vec![ - // Should be ignored - (repo_path.join("target").join("debug").join("main"), false), - (repo_path.join("dist").join("bundle.js"), false), - (repo_path.join("logs").join("app.log"), false), - (repo_path.join("debug.log"), false), - ( - repo_path - .join("node_modules") - .join("react") - .join("index.js"), - false, - ), - (repo_path.join(".vscode").join("settings.json"), false), - (repo_path.join(".env"), false), - (repo_path.join(".DS_Store"), false), - (repo_path.join("temp.swp"), false), - // Should be included - (repo_path.join("src").join("main.rs"), true), - (repo_path.join("README.md"), true), - (repo_path.join("package.json"), true), - (repo_path.join("docs").join("guide.md"), true), - (repo_path.join("tests").join("integration.rs"), true), - ( - repo_path.join(".github").join("workflows").join("ci.yml"), - true, - ), - ]; - - for (path, should_include) in test_cases { - let actual = !LocalRepoMetadataModel::path_is_ignored(&path, &gitignores); - assert_eq!( - actual, should_include, - "Path {path:?} - expected: {should_include}, actual: {actual}" - ); - } - }); - } - - #[test] - fn test_git_directory_exclusion() { - VirtualFS::test("git_exclusion_test", |dirs, mut fs| { - let repo_path = dirs.tests(); - - // Create .git directory and files using VirtualFS - fs.mkdir(".git/objects").mkdir("src").with_files(vec![ - Stub::FileWithContent(".git/config", "config"), - Stub::FileWithContent(".git/objects/abc123", "object"), - Stub::FileWithContent("src/main.rs", "rust"), - ]); - - let gitignores = vec![]; // Empty gitignore rules - - // .git directory and its contents should be excluded - assert!(LocalRepoMetadataModel::path_is_ignored( - &repo_path.join(".git"), - &gitignores - )); - assert!(LocalRepoMetadataModel::path_is_ignored( - &repo_path.join(".git").join("config"), - &gitignores - )); - assert!(LocalRepoMetadataModel::path_is_ignored( - &repo_path.join(".git").join("objects").join("abc123"), - &gitignores - )); - - // Regular files should be included - assert!(!LocalRepoMetadataModel::path_is_ignored( - &repo_path.join("src").join("main.rs"), - &gitignores - )); - }); - } - - #[test] - fn test_nested_gitignore_rules() { - VirtualFS::test("nested_gitignore_test", |dirs, mut fs| { - let repo_path = dirs.tests(); - - // Create nested directory structure and files using VirtualFS - fs.mkdir("frontend/dist") - .mkdir("backend/target") - .mkdir("frontend/src") - .with_files(vec![ - Stub::FileWithContent("frontend/dist/bundle.js", "js"), - Stub::FileWithContent("backend/target/binary", "bin"), - Stub::FileWithContent("frontend/src/main.ts", "ts"), - Stub::FileWithContent(".gitignore", "*/dist/\n*/target/"), - Stub::FileWithContent("frontend/.gitignore", "!dist/important.js"), - ]); - - // Create gitignore objects - let root_gitignore_path = repo_path.join(".gitignore"); - let frontend_gitignore_path = repo_path.join("frontend").join(".gitignore"); - - let (root_gitignore, _) = Gitignore::new(&root_gitignore_path); - let (frontend_gitignore, _) = Gitignore::new(&frontend_gitignore_path); - let gitignores = vec![root_gitignore, frontend_gitignore]; - - // Test that nested gitignore rules are respected - assert!(LocalRepoMetadataModel::path_is_ignored( - &repo_path.join("frontend").join("dist").join("bundle.js"), - &gitignores - )); - assert!(LocalRepoMetadataModel::path_is_ignored( - &repo_path.join("backend").join("target").join("binary"), - &gitignores - )); - assert!(!LocalRepoMetadataModel::path_is_ignored( - &repo_path.join("frontend").join("src").join("main.ts"), - &gitignores - )); - }); - } - - #[test] - fn test_ensure_parent_directories_exist() { - use crate::local_model::LocalRepoMetadataModel; - - // Test case 1: Normal operation - creating nested parent directories - let root_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/test_repo").unwrap(), - children: vec![Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/test_repo/src").unwrap(), - children: vec![], - ignored: false, - loaded: true, - })], - ignored: false, - loaded: true, - }); - let mut root = FileTreeEntry::from(root_entry); - - // Try to ensure parent directories exist for a deeply nested path - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut root, - &StandardizedPath::try_new("/test_repo/src/components/ui/forms").unwrap(), - ); - - // Verify that all intermediate directories were created - let mut all_paths = Vec::new(); - collect_all_paths(&root, &mut all_paths); - - assert!(all_paths.contains(&StandardizedPath::try_new("/test_repo").unwrap())); - assert!(all_paths.contains(&StandardizedPath::try_new("/test_repo/src").unwrap())); - assert!( - all_paths.contains(&StandardizedPath::try_new("/test_repo/src/components").unwrap()) - ); - assert!( - all_paths.contains(&StandardizedPath::try_new("/test_repo/src/components/ui").unwrap()) - ); - assert!(all_paths - .contains(&StandardizedPath::try_new("/test_repo/src/components/ui/forms").unwrap())); - - // Test case 2: Existing directories should not be recreated - let initial_count = all_paths.len(); - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut root, - &StandardizedPath::try_new("/test_repo/src/components/ui/forms").unwrap(), - ); - - let mut updated_paths = Vec::new(); - collect_all_paths(&root, &mut updated_paths); - assert_eq!( - initial_count, - updated_paths.len(), - "No new directories should be created when they already exist" - ); - - // Test case 3: Edge case - file exists where directory is expected - // This tests the edge case documented in the function's comment - let root_with_file_conflict_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/test_repo").unwrap(), - children: vec![ - // Create a file at the path where we'll try to create a directory - Entry::File(FileMetadata::from_standardized( - StandardizedPath::try_new("/test_repo/conflicting_path").unwrap(), - false, - )), - ], - ignored: false, - loaded: true, - }); - let mut root_with_file_conflict = FileTreeEntry::from(root_with_file_conflict_entry); - - // Try to create parent directories where a file already exists - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut root_with_file_conflict, - &StandardizedPath::try_new("/test_repo/conflicting_path/nested/deep").unwrap(), - ); - - // Verify that the function returned early and didn't corrupt the tree - let mut conflict_paths = Vec::new(); - collect_all_paths(&root_with_file_conflict, &mut conflict_paths); - - // The function should detect the file conflict and return early without creating - // any nested directories beyond the conflicting file. - - // Should still have the original file - assert!(conflict_paths - .contains(&StandardizedPath::try_new("/test_repo/conflicting_path").unwrap())); - // Should NOT have created nested directories beyond the conflict - assert!(!conflict_paths - .contains(&StandardizedPath::try_new("/test_repo/conflicting_path/nested").unwrap())); - assert!(!conflict_paths.contains( - &StandardizedPath::try_new("/test_repo/conflicting_path/nested/deep").unwrap() - )); - - // Verify the conflicting entry is still a file, not a directory - let conflicting_entry = root_with_file_conflict - .get(&StandardizedPath::try_new("/test_repo/conflicting_path").unwrap()) - .expect("Conflicting entry should exist"); - assert!( - matches!(conflicting_entry, FileTreeEntryState::File(_)), - "Conflicting entry should remain a file" - ); - - { - // Test case 3b: File conflict at intermediate level - let root_with_intermediate_conflict_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/test_repo").unwrap(), - children: vec![Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/test_repo/src").unwrap(), - children: vec![ - // Create a file where we expect a directory - Entry::File(FileMetadata::from_standardized( - StandardizedPath::try_new("/test_repo/src/components").unwrap(), - false, - )), - ], - ignored: false, - loaded: true, - })], - ignored: false, - loaded: true, - }); - let mut root_with_intermediate_conflict = - FileTreeEntry::from(root_with_intermediate_conflict_entry); - - // Try to create nested directories where an intermediate path has a file conflict - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut root_with_intermediate_conflict, - &StandardizedPath::try_new("/test_repo/src/components/ui/forms").unwrap(), - ); - - // Verify that the function handled the conflict properly - let mut intermediate_conflict_paths = Vec::new(); - collect_all_paths( - &root_with_intermediate_conflict, - &mut intermediate_conflict_paths, - ); - - // Should still have the original file at components level - assert!(intermediate_conflict_paths - .contains(&StandardizedPath::try_new("/test_repo/src/components").unwrap())); - - // Should NOT have created deeper nested directories beyond the conflict - assert!(!intermediate_conflict_paths - .contains(&StandardizedPath::try_new("/test_repo/src/components/ui").unwrap())); - assert!(!intermediate_conflict_paths.contains( - &StandardizedPath::try_new("/test_repo/src/components/ui/forms").unwrap() - )); - - // Verify the conflicting entry is still a file, not a directory - let conflicting_entry = root_with_intermediate_conflict - .get(&StandardizedPath::try_new("/test_repo/src/components").unwrap()) - .expect("Conflicting entry should exist"); - assert!( - matches!(conflicting_entry, FileTreeEntryState::File(_)), - "Conflicting entry should remain a file" - ); - - // Test case 4: Single level directory creation - let simple_root_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/simple").unwrap(), - children: vec![], - ignored: false, - loaded: true, - }); - let mut simple_root = FileTreeEntry::from(simple_root_entry); - - let simple_target = StandardizedPath::try_new("/simple/new_dir").unwrap(); - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut simple_root, - &simple_target, - ); - - let mut simple_paths = Vec::new(); - collect_all_paths(&simple_root, &mut simple_paths); - assert!(simple_paths.contains(&StandardizedPath::try_new("/simple/new_dir").unwrap())); - - // Test case 5: Target parent is the root itself (edge case) - let root_target_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/root").unwrap(), - children: vec![], - ignored: false, - loaded: true, - }); - let mut root_target = FileTreeEntry::from(root_target_entry); - - // This should not crash or create any new directories - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut root_target, - &StandardizedPath::try_new("/root").unwrap(), - ); - - let mut root_paths = Vec::new(); - collect_all_paths(&root_target, &mut root_paths); - assert_eq!(root_paths.len(), 1); // Should only contain the root itself - - // Test case 6: Empty path handling - let empty_root_entry = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_new("/empty").unwrap(), - children: vec![], - ignored: false, - loaded: true, - }); - let mut empty_root = FileTreeEntry::from(empty_root_entry); - - // Test with a path that has no additional parents to create - let same_level_target = StandardizedPath::try_new("/empty").unwrap(); - LocalRepoMetadataModel::ensure_parent_directories_exist( - &mut empty_root, - &same_level_target, - ); - - let mut empty_paths = Vec::new(); - collect_all_paths(&empty_root, &mut empty_paths); - assert_eq!(empty_paths.len(), 1); // Should still only contain the root - } - } - - /// Helper function to collect all paths in a file tree - fn collect_all_paths(entry: &FileTreeEntry, paths: &mut Vec) { - let root_path = entry.root_directory().clone(); - collect_paths_recursive(entry, &root_path, paths); - } - - fn collect_paths_recursive( - entry: &FileTreeEntry, - current_path: &StandardizedPath, - paths: &mut Vec, - ) { - paths.push(current_path.clone()); - if let Some(FileTreeEntryState::Directory(_)) = entry.get(current_path) { - for child in entry.child_paths(current_path) { - collect_paths_recursive(entry, child, paths); - } - } - } - - #[test] - fn test_canonicalized_path_functionality() { - VirtualFS::test("canonicalized_path_test", |dirs, mut vfs| { - let repo_path = dirs.tests(); - - // Create a directory structure with symlinks - vfs.mkdir("real_dir/subdir") - .mkdir("other_dir") - .with_files(vec![ - Stub::FileWithContent("real_dir/file.txt", "content"), - Stub::FileWithContent("real_dir/subdir/nested.rs", "rust code"), - ]); - - let real_dir = repo_path.join("real_dir"); - let symlink_dir = repo_path.join("symlinked_dir"); - let relative_path = repo_path.join("./real_dir"); - - // Create a symlink to real_dir - #[cfg(unix)] - let symlink_created = std::os::unix::fs::symlink(&real_dir, &symlink_dir).is_ok(); - #[cfg(windows)] - let symlink_created = - std::os::windows::fs::symlink_dir(&real_dir, &symlink_dir).is_ok(); - - if symlink_created { - // Test that different path representations canonicalize to the same path - let canonical_real = StandardizedPath::from_local_canonicalized(&real_dir).unwrap(); - let canonical_symlink = - StandardizedPath::from_local_canonicalized(&symlink_dir).unwrap(); - let canonical_relative = - StandardizedPath::from_local_canonicalized(&relative_path).unwrap(); - - // All should point to the same canonical path - assert_eq!(canonical_real, canonical_symlink); - assert_eq!(canonical_real, canonical_relative); - - // Test that the canonical path is absolute and resolved - let local = canonical_real.to_local_path().unwrap(); - assert!(local.is_absolute()); - assert!(!local.to_string_lossy().contains("./")); - } - - // Test with various input types - let path_buf = real_dir.clone(); - let path_ref = real_dir.as_path(); - - let canonical_from_pathbuf = - StandardizedPath::from_local_canonicalized(&path_buf).unwrap(); - let canonical_from_path = StandardizedPath::from_local_canonicalized(path_ref).unwrap(); - - // All should be equal - assert_eq!(canonical_from_pathbuf, canonical_from_path); - - // Test conversion to local path - let canonical = StandardizedPath::from_local_canonicalized(&real_dir).unwrap(); - let local_path = canonical.to_local_path().unwrap(); - - // Test internal consistency - compare with dunce-canonicalized version - let expected_canonical = dunce::canonicalize(&real_dir).unwrap(); - assert_eq!(local_path, expected_canonical); - - // Test error handling for non-existent paths - let nonexistent = repo_path.join("nonexistent"); - let result = StandardizedPath::from_local_canonicalized(&nonexistent); - assert!(result.is_err()); - }); - } - - #[test] - fn test_repository_operations_with_standardized_paths() { - - VirtualFS::test("repo_canonicalized_test", |dirs, mut vfs| { - let test_root = dirs.tests(); - - // Create a real repository directory - vfs.mkdir("real_repo/src") - .mkdir("other_location") - .with_files(vec![ - Stub::FileWithContent("real_repo/src/main.rs", "fn main() {}"), - Stub::FileWithContent("real_repo/.gitignore", "*.log\n/target/"), - Stub::FileWithContent("real_repo/README.md", "# Project"), - ]); - - let real_repo = test_root.join("real_repo"); - let symlink_repo = test_root.join("symlinked_repo"); - let relative_repo = test_root.join("./real_repo"); - - // Create symlink to the repo - #[cfg(unix)] - let symlink_created = std::os::unix::fs::symlink(&real_repo, &symlink_repo).is_ok(); - #[cfg(windows)] - let symlink_created = - std::os::windows::fs::symlink_dir(&real_repo, &symlink_repo).is_ok(); - - if symlink_created { - App::test((), |mut app| async move { - let repo_watcher = app.add_singleton_model(DirectoryWatcher::new); - let _detected_repo = - app.add_singleton_model(|_| DetectedRepositories::default()); - let model_handle = app.add_model(LocalRepoMetadataModel::new); - - // Create file tree state for testing - let src_file = - Entry::File(FileMetadata::new(real_repo.join("src/main.rs"), false)); - let readme_file = - Entry::File(FileMetadata::new(real_repo.join("README.md"), false)); - let src_dir = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&real_repo.join("src")).unwrap(), - children: vec![src_file], - ignored: false, - loaded: true, - }); - let root = Entry::Directory(DirectoryEntry { - path: StandardizedPath::try_from_local(&real_repo).unwrap(), - children: vec![src_dir, readme_file], - ignored: false, - loaded: true, - }); - - let (gitignore, _) = Gitignore::new(real_repo.join(".gitignore")); - let repo_handle = repo_watcher.update(&mut app, |repo_watcher, ctx| { - repo_watcher - .add_directory( - StandardizedPath::from_local_canonicalized(&real_repo).unwrap(), - ctx, - ) - .unwrap() - }); - let state = FileTreeState::new(root, vec![gitignore], Some(repo_handle)); - - // Test adding repository using different path representations - model_handle.update(&mut app, |model, ctx| { - // Add using real path - let result1 = model.add_repository_internal( - StandardizedPath::from_local_canonicalized(&real_repo).unwrap(), - state.clone(), - ctx, - ); - assert!(result1.is_ok()); - - // Try to add using symlink path - this should canonicalize to the same path - let result2 = model.add_repository_internal( - StandardizedPath::from_local_canonicalized(&symlink_repo).unwrap(), - state.clone(), - ctx, - ); - assert!(result2.is_ok()); - - // Try to add using relative path - let result3 = model.add_repository_internal( - StandardizedPath::from_local_canonicalized(&relative_repo).unwrap(), - state.clone(), - ctx, - ); - assert!(result3.is_ok()); - - // Verify that only one repository entry exists (all paths canonicalized to the same) - let canonical_path = - StandardizedPath::from_local_canonicalized(&real_repo).unwrap(); - assert!(model.repositories.contains_key(&canonical_path)); - }); - - // Test find_repository_for_path with different path formats - model_handle.read(&app, |model, _ctx| { - let file_in_repo = real_repo.join("src/main.rs"); - let symlink_file = symlink_repo.join("src/main.rs"); - - let found_real = model.find_repository_for_path(&file_in_repo); - let found_symlink = model.find_repository_for_path(&symlink_file); - - // Both should find the same repository - assert!(found_real.is_some()); - assert!(found_symlink.is_some()); - assert_eq!(found_real, found_symlink); - }); - }); - } - }); - } - - #[test] - fn test_standardized_path_edge_cases() { - - VirtualFS::test("canonicalized_edge_cases", |dirs, mut vfs| { - let test_root = dirs.tests(); - - // Create test files and directories - vfs.mkdir("existing_dir") - .with_files(vec![Stub::FileWithContent("existing_file.txt", "content")]); - - let existing_dir = test_root.join("existing_dir"); - let existing_file = test_root.join("existing_file.txt"); - let nonexistent = test_root.join("nonexistent"); - - // Test successful canonicalization - assert!(StandardizedPath::from_local_canonicalized(&existing_dir).is_ok()); - assert!(StandardizedPath::from_local_canonicalized(&existing_file).is_ok()); - - // Test failed canonicalization - assert!(StandardizedPath::from_local_canonicalized(&nonexistent).is_err()); - - // Test equality and hashing - let canonical1 = StandardizedPath::from_local_canonicalized(&existing_dir).unwrap(); - let canonical2 = StandardizedPath::from_local_canonicalized(&existing_dir).unwrap(); - - assert_eq!(canonical1, canonical2); - - // Test that they can be used in HashMaps - let mut map = std::collections::HashMap::new(); - map.insert(canonical1.clone(), "value1"); - assert_eq!(map.get(&canonical2), Some(&"value1")); - - // Test Debug trait - let debug_str = format!("{canonical1:?}"); - assert!(debug_str.contains("StandardizedPath")); - }); - } -} diff --git a/crates/repo_metadata/src/local_model_tests.rs b/crates/repo_metadata/src/local_model_tests.rs index 2b423bb9..452e5f28 100644 --- a/crates/repo_metadata/src/local_model_tests.rs +++ b/crates/repo_metadata/src/local_model_tests.rs @@ -9,11 +9,11 @@ use std::time::Duration; use futures::channel::oneshot; use futures::executor::block_on; -use ignore::gitignore::Gitignore; -use virtual_fs::{Stub, VirtualFS}; use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::r#async::FutureExt as _; use galaxyui_core::App; +use ignore::gitignore::Gitignore; +use virtual_fs::{Stub, VirtualFS}; #[cfg(feature = "local_fs")] use watcher::BulkFilesystemWatcherEvent; @@ -2006,7 +2006,6 @@ fn test_canonicalized_path_functionality() { #[test] fn test_repository_operations_with_standardized_paths() { - VirtualFS::test("repo_canonicalized_test", |dirs, mut vfs| { let test_root = dirs.tests(); @@ -2118,7 +2117,6 @@ fn test_repository_operations_with_standardized_paths() { #[test] fn test_standardized_path_edge_cases() { - VirtualFS::test("canonicalized_edge_cases", |dirs, mut vfs| { let test_root = dirs.tests(); diff --git a/crates/repo_metadata/src/repositories.rs b/crates/repo_metadata/src/repositories.rs index e602a660..68e9eb64 100644 --- a/crates/repo_metadata/src/repositories.rs +++ b/crates/repo_metadata/src/repositories.rs @@ -3,8 +3,6 @@ use std::future::Future; use std::path::{Path, PathBuf}; use futures::future::{ready, Either}; -#[cfg(test)] -use virtual_fs::{Stub, VirtualFS}; use galaxy_util::host_id::HostId; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxy_util::remote_path::{RemoteNavigationResult, RemotePath}; @@ -12,6 +10,8 @@ use galaxy_util::standardized_path::StandardizedPath; #[cfg(test)] use galaxyui_core::r#async::FutureId; use galaxyui_core::{AppContext, Entity, ModelContext, ModelHandle, SingletonEntity}; +#[cfg(test)] +use virtual_fs::{Stub, VirtualFS}; use crate::{DirectoryWatcher, Repository}; diff --git a/crates/repo_metadata/src/repositories_tests.rs b/crates/repo_metadata/src/repositories_tests.rs index 666e4c25..6dbf0c2c 100644 --- a/crates/repo_metadata/src/repositories_tests.rs +++ b/crates/repo_metadata/src/repositories_tests.rs @@ -1,9 +1,9 @@ use std::fs; -use virtual_fs::{Stub, VirtualFS}; use galaxy_util::local_or_remote_path::LocalOrRemotePath; use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::App; +use virtual_fs::{Stub, VirtualFS}; use crate::repositories::{stub_git_repository, DetectedRepositories, RepoDetectionSource}; use crate::watcher::DirectoryWatcher; diff --git a/crates/repo_metadata/src/repository.rs b/crates/repo_metadata/src/repository.rs index 0761baa8..5cf7156f 100644 --- a/crates/repo_metadata/src/repository.rs +++ b/crates/repo_metadata/src/repository.rs @@ -14,8 +14,8 @@ use galaxyui_core::SingletonEntity; use galaxyui_core::{Entity, ModelContext, ModelHandle}; #[cfg(feature = "local_fs")] use ignore::gitignore::Gitignore; -#[cfg(feature = "local_fs")] +#[cfg(feature = "local_fs")] #[cfg(feature = "local_fs")] use crate::watcher::DirectoryWatcher; use crate::watcher::TaskQueue; diff --git a/crates/repo_metadata/src/repository_tests.rs b/crates/repo_metadata/src/repository_tests.rs index ec750437..17447fab 100644 --- a/crates/repo_metadata/src/repository_tests.rs +++ b/crates/repo_metadata/src/repository_tests.rs @@ -5,10 +5,10 @@ use std::time::Duration; use futures::channel::mpsc; use futures::{FutureExt as _, StreamExt as _}; -use virtual_fs::{Stub, VirtualFS}; use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::r#async::Timer; use galaxyui_core::{App, ModelContext}; +use virtual_fs::{Stub, VirtualFS}; use super::{merge_repository_updates, Repository, RepositorySubscriber, TrackedRemoteRef}; use crate::repositories::stub_git_repository; diff --git a/crates/repo_metadata/src/telemetry.rs b/crates/repo_metadata/src/telemetry.rs index e989cdb0..f533a8dd 100644 --- a/crates/repo_metadata/src/telemetry.rs +++ b/crates/repo_metadata/src/telemetry.rs @@ -1,7 +1,7 @@ -use serde_json::{json, Value}; -use strum_macros::{EnumDiscriminants, EnumIter}; use galaxy_core::register_telemetry_event; use galaxy_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc}; +use serde_json::{json, Value}; +use strum_macros::{EnumDiscriminants, EnumIter}; #[derive(Clone, EnumDiscriminants)] #[strum_discriminants(derive(EnumIter))] diff --git a/crates/repo_metadata/src/watcher_tests.rs b/crates/repo_metadata/src/watcher_tests.rs index c55a704c..b1453075 100644 --- a/crates/repo_metadata/src/watcher_tests.rs +++ b/crates/repo_metadata/src/watcher_tests.rs @@ -7,10 +7,10 @@ use std::time::Duration; use futures::channel::mpsc; use futures::{FutureExt as _, StreamExt as _}; -use virtual_fs::{Stub, VirtualFS}; use galaxy_util::standardized_path::StandardizedPath; use galaxyui_core::r#async::Timer; use galaxyui_core::{App, ModelContext, ModelHandle}; +use virtual_fs::{Stub, VirtualFS}; use crate::repositories::stub_git_repository; use crate::repository::{RepositorySubscriber, TrackedRemoteRef}; diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs index 0fac10ae..a7384e2b 100644 --- a/crates/settings/src/lib.rs +++ b/crates/settings/src/lib.rs @@ -7,6 +7,8 @@ pub mod schema; use std::fmt::Debug; use std::ops::Deref; +// Re-export galaxyui_core for use by macros. +pub use galaxyui_core; // Re-export crates used by macro expansions in downstream crates. #[doc(hidden)] pub use inventory as _inventory; @@ -17,8 +19,6 @@ pub use schemars as _schemars; #[doc(hidden)] pub use settings_value as _settings_value; pub use settings_value::SettingsValue; -// Re-export galaxyui_core for use by macros. -pub use galaxyui_core; /// Extracts the storage key (last segment after the final `.`) from a toml_path. /// @@ -59,12 +59,12 @@ pub const fn toml_path_hierarchy(path: &str) -> Option<&str> { } use anyhow::{Context, Result}; -use serde::Serialize; -use serde::de::DeserializeOwned; use galaxy_features::FeatureFlag; use galaxyui_core::{AppContext, Entity, ModelContext}; use galaxyui_extras::secure_storage::{self, AppContextExt as _}; use galaxyui_extras::user_preferences::UserPreferences; +use serde::Serialize; +use serde::de::DeserializeOwned; /// A newtype wrapper for the public preferences backend. /// diff --git a/crates/settings/src/macros.rs b/crates/settings/src/macros.rs index 429621a3..67700f73 100644 --- a/crates/settings/src/macros.rs +++ b/crates/settings/src/macros.rs @@ -315,12 +315,11 @@ macro_rules! define_setting { &mut self, ctx: &mut $crate::galaxyui_core::ModelContext, ) -> anyhow::Result<()> { - use $crate::ChangeEventReason; Self::clear_from_preferences(Self::preferences_for_setting(ctx))?; self.inner = self.validate(Self::default_value()); self.is_explicitly_set = false; ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::Clear, + change_event_reason: $crate::ChangeEventReason::Clear, }})); Ok(()) } @@ -336,7 +335,7 @@ macro_rules! define_setting { self.inner = self.validate(new_value); self.is_explicitly_set = true; ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::CloudSync, + change_event_reason: $crate::ChangeEventReason::CloudSync, }})); } Ok(()) @@ -353,7 +352,7 @@ macro_rules! define_setting { self.inner = self.validate(new_value); self.is_explicitly_set = true; ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::LocalChange, + change_event_reason: $crate::ChangeEventReason::LocalChange, }})); } Ok(()) @@ -370,7 +369,7 @@ macro_rules! define_setting { self.inner = validated; self.is_explicitly_set = explicitly_set; ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::LocalChange, + change_event_reason: $crate::ChangeEventReason::LocalChange, }})); } Ok(()) @@ -585,7 +584,7 @@ macro_rules! implement_setting_for_enum { Self::clear_from_preferences(Self::preferences_for_setting(ctx))?; *self = self.validate(Self::default_value()); ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::Clear, + change_event_reason: $crate::ChangeEventReason::Clear, }})); Ok(()) } @@ -600,7 +599,7 @@ macro_rules! implement_setting_for_enum { if self.value() != &new_value || changed_in_storage { *self = self.validate(new_value); ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::CloudSync, + change_event_reason: $crate::ChangeEventReason::CloudSync, }})); } Ok(()) @@ -616,7 +615,7 @@ macro_rules! implement_setting_for_enum { if self.value() != &new_value || changed_in_storage { *self = self.validate(new_value); ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::LocalChange, + change_event_reason: $crate::ChangeEventReason::LocalChange, }})); } Ok(()) @@ -632,7 +631,7 @@ macro_rules! implement_setting_for_enum { if self.value() != &validated { *self = validated; ctx.emit($crate::macros::concat_idents!(EventName = $group, ChangedEvent { EventName::$name { - change_event_reason: ChangeEventReason::LocalChange, + change_event_reason: $crate::ChangeEventReason::LocalChange, }})); } Ok(()) @@ -856,7 +855,7 @@ macro_rules! generate_settings_event_fn { let value = serde_json::from_str::(&value) .ok() .and_then(|json_val| { - <$setting as $crate::Setting>::Value::from_file_value(&json_val) + <<$setting as $crate::Setting>::Value as $crate::_settings_value::SettingsValue>::from_file_value(&json_val) }) .or_else(|| serde_json::from_str(&value).ok()); let Some(value) = value else { @@ -893,7 +892,7 @@ macro_rules! generate_settings_event_fn { let value = serde_json::from_str::(&value) .ok() .and_then(|json_val| { - <$setting as $crate::Setting>::Value::from_file_value(&json_val) + <<$setting as $crate::Setting>::Value as $crate::_settings_value::SettingsValue>::from_file_value(&json_val) }) .or_else(|| serde_json::from_str(&value).ok()); let Some(value) = value else { @@ -910,7 +909,7 @@ macro_rules! generate_settings_event_fn { let parse = |s: &str| -> anyhow::Result<<$setting as $crate::Setting>::Value> { let json_val = serde_json::from_str::(s)?; - <$setting as $crate::Setting>::Value::from_file_value(&json_val) + <<$setting as $crate::Setting>::Value as $crate::_settings_value::SettingsValue>::from_file_value(&json_val) .or_else(|| serde_json::from_str(s).ok()) .ok_or_else(|| { anyhow!( diff --git a/crates/settings/src/mod_tests.rs b/crates/settings/src/mod_tests.rs index 7f4b12d4..92a6b057 100644 --- a/crates/settings/src/mod_tests.rs +++ b/crates/settings/src/mod_tests.rs @@ -153,7 +153,7 @@ fn test_is_setting_syncable_on_current_platform() { } mod reload_all_public_settings_tests { - + use super::*; define_settings_group!(ReloadTestSettings, settings: [ public_flag: PublicFlag { @@ -443,6 +443,8 @@ mod reload_all_public_settings_tests { } mod write_to_preferences_tests { + use galaxyui_extras::user_preferences::toml_backed::TomlBackedUserPreferences; + use crate::*; #[derive( @@ -533,9 +535,9 @@ mod write_to_preferences_tests { /// Option fields — reproduces the exact QuakeModeSettings scenario. #[test] fn test_no_spurious_write_with_hashmap_and_missing_options() { - use galaxyui_extras::user_preferences::toml_backed::TomlBackedUserPreferences; use std::collections::HashMap; + use galaxyui_extras::user_preferences::toml_backed::TomlBackedUserPreferences; #[derive( Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema, @@ -598,7 +600,6 @@ mod write_to_preferences_tests { /// null-stripping and key-reordering happens. #[test] fn test_no_spurious_write_with_toml_backend() { - let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("settings.toml"); let (prefs, _) = TomlBackedUserPreferences::new(file_path.clone()); diff --git a/crates/simple_logger/src/manager.rs b/crates/simple_logger/src/manager.rs index 9adabe59..f4a976d4 100644 --- a/crates/simple_logger/src/manager.rs +++ b/crates/simple_logger/src/manager.rs @@ -3,9 +3,9 @@ use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::sync::{Arc, Weak}; -use thiserror::Error; use galaxyui_core::r#async::executor::Background; use galaxyui_core::{Entity, SingletonEntity}; +use thiserror::Error; use crate::{LogFileWriter, SimpleLogger}; diff --git a/crates/syntax_tree/src/lib.rs b/crates/syntax_tree/src/lib.rs index cc8b1f3f..f33d6064 100644 --- a/crates/syntax_tree/src/lib.rs +++ b/crates/syntax_tree/src/lib.rs @@ -5,13 +5,6 @@ use std::sync::Arc; use arborium::tree_sitter::{InputEdit, Parser, Tree}; use futures::stream::AbortHandle; -use languages::Language; -use parking_lot::Mutex; -use queries::highlight_query::HighlightQuery; -pub use queries::highlight_query::{ColorMap, TextSlice}; -use queries::indent_query::{indentation_delta, IndentDelta}; -use rangemap::{RangeMap, RangeSet}; -use string_offset::{ByteOffset, CharOffset}; use galaxy_editor::content::buffer::{Buffer, BufferSnapshot}; use galaxy_editor::content::edit::PreciseDelta; use galaxy_editor::content::text::IndentUnit; @@ -20,6 +13,13 @@ use galaxy_editor::decoration::DecorationLayer; use galaxyui_core::color::ColorU; use galaxyui_core::text::point::Point; use galaxyui_core::{AppContext, Entity, ModelContext, WeakModelHandle}; +use languages::Language; +use parking_lot::Mutex; +use queries::highlight_query::HighlightQuery; +pub use queries::highlight_query::{ColorMap, TextSlice}; +use queries::indent_query::{indentation_delta, IndentDelta}; +use rangemap::{RangeMap, RangeSet}; +use string_offset::{ByteOffset, CharOffset}; const MAX_SYNTAX_TREES: usize = 3; diff --git a/crates/syntax_tree/src/queries/highlight_query.rs b/crates/syntax_tree/src/queries/highlight_query.rs index a2489218..4226495b 100644 --- a/crates/syntax_tree/src/queries/highlight_query.rs +++ b/crates/syntax_tree/src/queries/highlight_query.rs @@ -2,12 +2,12 @@ use std::iter; use std::ops::Range; use arborium::tree_sitter::{Node, Query, QueryCursor, TextProvider, Tree}; -use rangemap::RangeMap; -use streaming_iterator::StreamingIterator; -use string_offset::{ByteOffset, CharOffset}; use galaxy_editor::content::buffer::{Buffer, ToBufferByteOffset, ToBufferCharOffset}; use galaxy_editor::content::text::Bytes; use galaxyui_core::color::ColorU; +use rangemap::RangeMap; +use streaming_iterator::StreamingIterator; +use string_offset::{ByteOffset, CharOffset}; /// Color mapping from parsed syntax token name to its corresponding highlighting color. #[derive(Clone, Copy)] diff --git a/crates/syntax_tree/src/queries/indent_query.rs b/crates/syntax_tree/src/queries/indent_query.rs index ef0e9a08..182ae2be 100644 --- a/crates/syntax_tree/src/queries/indent_query.rs +++ b/crates/syntax_tree/src/queries/indent_query.rs @@ -3,9 +3,8 @@ use std::ops::Range; use arborium::tree_sitter::{Node, Query, QueryCursor, Tree}; use galaxy_editor::content::buffer::Buffer; -use galaxyui::text::point::Point; -use streaming_iterator::StreamingIterator; use galaxyui_core::text::point::Point; +use streaming_iterator::StreamingIterator; use super::highlight_query::TextBuffer; diff --git a/crates/syntax_tree/src/queries/indent_query_tests.rs b/crates/syntax_tree/src/queries/indent_query_tests.rs index 9ffd4c0b..e493bad2 100644 --- a/crates/syntax_tree/src/queries/indent_query_tests.rs +++ b/crates/syntax_tree/src/queries/indent_query_tests.rs @@ -4,10 +4,9 @@ use arborium::tree_sitter::Tree; use galaxy_editor::content::buffer::{Buffer, BufferSnapshot}; use galaxy_editor::content::selection_model::BufferSelectionModel; use galaxy_editor::content::text::IndentBehavior; +use galaxy_util::standardized_path::StandardizedPath; use galaxyui::App; use languages::{language_by_filename, Language}; -use galaxy_util::standardized_path::StandardizedPath; -use galaxyui_core::App; use super::*; use crate::SyntaxTreeState; diff --git a/crates/ui_components/examples/library.rs b/crates/ui_components/examples/library.rs index 18e398b3..58f861cd 100644 --- a/crates/ui_components/examples/library.rs +++ b/crates/ui_components/examples/library.rs @@ -3,10 +3,6 @@ use std::sync::Arc; use std::time::Duration; use anyhow::{Result, anyhow}; -use pathfinder_geometry::vector::Vector2F; -use rust_embed::RustEmbed; -use ui_components::lightbox::{self, LightboxImage, LightboxImageSource, NavigationDirection}; -use ui_components::{Component as _, Options, button, dialog, switch, tooltip}; use galaxy_core::ui::Icon; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::theme::color::internal_colors; @@ -17,6 +13,10 @@ use galaxyui_core::image_cache::ImageType; use galaxyui_core::keymap::FixedBinding; use galaxyui_core::prelude::*; use galaxyui_core::{AssetProvider, SingletonEntity, Tracked, platform}; +use pathfinder_geometry::vector::Vector2F; +use rust_embed::RustEmbed; +use ui_components::lightbox::{self, LightboxImage, LightboxImageSource, NavigationDirection}; +use ui_components::{Component as _, Options, button, dialog, switch, tooltip}; #[derive(Clone, Copy, RustEmbed)] #[folder = "../../app/assets"] @@ -41,7 +41,7 @@ fn main() -> galaxyui_core::platform::app::TerminationResult { .install_default() .expect("must be able to initialize crypto provider for TLS support"); - let app_builder = warpui::platform::AppBuilder::new( + let app_builder = galaxyui::platform::AppBuilder::new( platform::AppCallbacks::default(), Box::new(ASSETS), None, @@ -55,7 +55,8 @@ fn main() -> galaxyui_core::platform::app::TerminationResult { "Noto Sans".to_string() }; - let font_family = galaxyui_core::fonts::Cache::handle(ctx).update(ctx, |cache, _ctx| { + let cache_handle = galaxyui_core::fonts::Cache::handle(ctx); + let font_family = cache_handle.update(ctx, |cache, _ctx| { cache.load_system_font(&font_name).unwrap() }); ctx.add_singleton_model(|ctx| { diff --git a/crates/ui_components/src/button.rs b/crates/ui_components/src/button.rs index a946ba2b..851a6d28 100644 --- a/crates/ui_components/src/button.rs +++ b/crates/ui_components/src/button.rs @@ -1,13 +1,13 @@ mod params; pub mod themes; -pub use params::*; -pub use themes::Theme; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::ContrastingColor as _; use galaxy_core::ui::color::contrast::MinimumAllowedContrast; use galaxyui_core::elements::{MouseState, MouseStateHandle}; use galaxyui_core::prelude::*; +pub use params::*; +pub use themes::Theme; use crate::{keyboard_shortcut, tooltip}; diff --git a/crates/ui_components/src/button/themes.rs b/crates/ui_components/src/button/themes.rs index 3c935980..83e8c951 100644 --- a/crates/ui_components/src/button/themes.rs +++ b/crates/ui_components/src/button/themes.rs @@ -1,8 +1,8 @@ -use pathfinder_color::ColorU; use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::coloru_with_opacity; use galaxy_core::ui::theme::Fill; use galaxy_core::ui::theme::color::internal_colors; +use pathfinder_color::ColorU; /// Theming delegate for a button. pub trait Theme { diff --git a/crates/ui_components/src/lib.rs b/crates/ui_components/src/lib.rs index 8859f993..2e8dc551 100644 --- a/crates/ui_components/src/lib.rs +++ b/crates/ui_components/src/lib.rs @@ -5,9 +5,9 @@ pub mod lightbox; pub mod switch; pub mod tooltip; -pub use keyboard_shortcut::KeyboardShortcut; use galaxy_core::ui::appearance::Appearance; use galaxyui_core::Element; +pub use keyboard_shortcut::KeyboardShortcut; /// A reusable UI component that can be rendered with configurable parameters. /// diff --git a/crates/ui_components/src/lightbox.rs b/crates/ui_components/src/lightbox.rs index 0b564a89..7054494a 100644 --- a/crates/ui_components/src/lightbox.rs +++ b/crates/ui_components/src/lightbox.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use pathfinder_geometry::vector::{Vector2F, vec2f}; use galaxy_core::ui::Icon; use galaxy_core::ui::appearance::Appearance; use galaxyui_core::assets::asset_cache::AssetSource; @@ -10,6 +9,7 @@ use galaxyui_core::elements::{ use galaxyui_core::keymap::Keystroke; use galaxyui_core::prelude::stack::*; use galaxyui_core::prelude::*; +use pathfinder_geometry::vector::{Vector2F, vec2f}; use crate::{Component, Options as _, button}; diff --git a/crates/vim/src/word_iterator.rs b/crates/vim/src/word_iterator.rs index 4503b985..cb8152a2 100644 --- a/crates/vim/src/word_iterator.rs +++ b/crates/vim/src/word_iterator.rs @@ -1,7 +1,8 @@ use std::iter::Peekable; use anyhow::Result; -use galaxyui_core::text::{words::is_default_word_boundary, TextBuffer}; +use galaxyui_core::text::words::is_default_word_boundary; +use galaxyui_core::text::TextBuffer; use itertools::{peek_nth, Either, PeekNth}; use string_offset::CharOffset; diff --git a/crates/voice_input/src/lib.rs b/crates/voice_input/src/lib.rs index 11732fd7..308d942b 100644 --- a/crates/voice_input/src/lib.rs +++ b/crates/voice_input/src/lib.rs @@ -6,14 +6,14 @@ use base64::Engine; use cpal::traits::{DeviceTrait, HostTrait}; use cpal::{Sample, StreamConfig}; use futures::channel::oneshot; +use galaxyui_core::event::KeyState; +use galaxyui_core::platform::MicrophoneAccessState; +use galaxyui_core::{Entity, ModelContext, SingletonEntity}; use parking_lot::Mutex; use rubato::{ Resampler, SincFixedIn, SincInterpolationParameters, SincInterpolationType, WindowFunction, }; use thiserror::Error; -use galaxyui_core::event::KeyState; -use galaxyui_core::platform::MicrophoneAccessState; -use galaxyui_core::{Entity, ModelContext, SingletonEntity}; const DEFAULT_CHUNK_SIZE: u32 = 512; // We only support mono for now. diff --git a/crates/warp_search_core/src/item.rs b/crates/warp_search_core/src/item.rs index 52e1891f..98dc1528 100644 --- a/crates/warp_search_core/src/item.rs +++ b/crates/warp_search_core/src/item.rs @@ -1,8 +1,8 @@ -use warp_core::ui::theme::Fill; -use warpui_core::{Action, AppContext, Element}; use ordered_float::OrderedFloat; use warp_core::ui::appearance::Appearance; +use warp_core::ui::theme::Fill; use warpui_core::fonts::FamilyId; +use warpui_core::{Action, AppContext, Element}; use super::result_renderer::ItemHighlightState; diff --git a/crates/warp_search_core/src/mixer.rs b/crates/warp_search_core/src/mixer.rs index 648a2123..6ef226fa 100644 --- a/crates/warp_search_core/src/mixer.rs +++ b/crates/warp_search_core/src/mixer.rs @@ -7,11 +7,11 @@ use std::time::Duration; use async_channel::Sender; use async_trait::async_trait; use futures_util::stream::AbortHandle; -use warpui_core::r#async::Timer; -use warpui_core::{Action, AppContext, Entity, ModelContext}; use itertools::Itertools; use warp_core::r#async::debounce; use warp_core::send_telemetry_from_ctx; +use warpui_core::r#async::Timer; +use warpui_core::{Action, AppContext, Entity, ModelContext}; use super::data_source::{Query, QueryFilter, QueryResult}; use crate::telemetry::TelemetryEvent; diff --git a/crates/warp_search_core/src/searcher.rs b/crates/warp_search_core/src/searcher.rs index ae570413..005276cd 100644 --- a/crates/warp_search_core/src/searcher.rs +++ b/crates/warp_search_core/src/searcher.rs @@ -8,7 +8,6 @@ use std::time::Duration; use anyhow::Context; use futures::FutureExt as _; -use warpui_core::r#async::{block_on, executor::Background, Timer}; use instant::Instant; use itertools::Itertools; use parking_lot::{Mutex, RwLock}; @@ -592,7 +591,7 @@ impl SearcherWriterWrapper { .iter() .filter(|(name, _)| self.id_field_names.contains(*name)) .collect(); - id_pairs.sort_by(|(a, _), (b, _)| a.cmp(b)); + id_pairs.sort_by_key(|(a, _)| *a); let mut hasher = Sha256::new(); // Add each field-value pair to the hasher in sorted order diff --git a/crates/warp_server_auth/Cargo.toml b/crates/warp_server_auth/Cargo.toml index 07e8d03c..e0212195 100644 --- a/crates/warp_server_auth/Cargo.toml +++ b/crates/warp_server_auth/Cargo.toml @@ -22,8 +22,8 @@ serde.workspace = true serde_json.workspace = true thiserror.workspace = true uuid.workspace = true -warp_core.workspace = true -warp_graphql.workspace = true -warp_managed_secrets.workspace = true -warpui_core.workspace = true -warpui_extras = { workspace = true, features = ["default"] } +galaxy_core.workspace = true +galaxy_graphql.workspace = true +galaxy_managed_secrets.workspace = true +galaxyui_core.workspace = true +galaxyui_extras = { workspace = true, features = ["default"] } diff --git a/crates/warp_server_auth/src/auth_state.rs b/crates/warp_server_auth/src/auth_state.rs index d42a0b1d..78ce2f28 100644 --- a/crates/warp_server_auth/src/auth_state.rs +++ b/crates/warp_server_auth/src/auth_state.rs @@ -4,12 +4,11 @@ use std::sync::atomic::{AtomicBool, Ordering}; use anyhow::anyhow; use chrono::{DateTime, Duration, Utc}; use galaxy_core::channel::{Channel, ChannelState}; +use galaxy_core::report_error; use galaxy_graphql::object_permissions::OwnerType; -use galaxyui::{AppContext, Entity, SingletonEntity}; +use galaxyui_core::{AppContext, Entity, SingletonEntity}; use parking_lot::RwLock; use uuid::Uuid; -use galaxy_core::report_error; -use galaxyui_core::{AppContext, Entity, SingletonEntity}; use super::anonymous_id::get_or_create_anonymous_id; use super::credentials::Credentials; @@ -118,7 +117,7 @@ impl AuthState { /// 3. WARP_USER_SECRET environment variable /// 4. Persisted user from secure storage #[cfg_attr(target_family = "wasm", allow(dead_code))] - pub fn initialize(ctx: &AppContext, _api_key: Option) -> Self { + pub fn initialize(ctx: &AppContext, api_key: Option) -> Self { let state = Self::new(ctx); if Self::should_use_test_user() { @@ -174,6 +173,16 @@ impl AuthState { } } + if state.user.read().is_none() { + let channel = ChannelState::channel(); + if channel == Channel::Oss || channel == Channel::Local || channel == Channel::Dev { + log::info!( + "No user found in secure storage on dev/oss/local channel; falling back to test user" + ); + state.set_user(Some(User::test())); + } + } + state } @@ -348,7 +357,7 @@ impl AuthState { /// during the transient state where credentials exist but user data hasn't loaded /// yet, the user is conservatively treated as lacking a full account. pub fn is_anonymous_or_logged_out(&self) -> bool { - false + self.user.read().is_none() || self.is_user_anonymous().unwrap_or(true) } /// Returns the cached access token, if any exists. This method *will not* check if the JWT is diff --git a/crates/warp_server_auth/src/user.rs b/crates/warp_server_auth/src/user.rs index b526dd15..78383f11 100644 --- a/crates/warp_server_auth/src/user.rs +++ b/crates/warp_server_auth/src/user.rs @@ -1,8 +1,8 @@ use anyhow::{Result, anyhow}; use chrono::{DateTime, FixedOffset, Local}; -use serde::{Deserialize, Serialize}; use galaxy_graphql::queries::get_user::FirebaseProfile; use galaxy_graphql::scalars::time::ServerTimestamp; +use serde::{Deserialize, Serialize}; use super::UserUid; pub use super::user_uid::{TEST_USER_EMAIL, TEST_USER_UID}; diff --git a/crates/warp_server_auth/src/user/persistence.rs b/crates/warp_server_auth/src/user/persistence.rs index c997f3f8..de5ec78c 100644 --- a/crates/warp_server_auth/src/user/persistence.rs +++ b/crates/warp_server_auth/src/user/persistence.rs @@ -1,15 +1,11 @@ use galaxy_graphql::scalars::time::ServerTimestamp; -use galaxyui::AppContext; +use galaxyui_core::AppContext; use galaxyui_extras::secure_storage; use serde::{Deserialize, Serialize}; -use galaxyui_core::AppContext; -use galaxyui_extras::secure_storage::{self, AppContextExt}; use super::{AnonymousUserType, FirebaseAuthTokens, PersonalObjectLimits, UserMetadata}; use crate::UserUid; -const USER_STORAGE_KEY: &str = "User"; - /// Helper function to set `true` as the default for a serde field on PersistedUser. fn default_as_true() -> bool { true diff --git a/crates/warp_tui/src/input/view.rs b/crates/warp_tui/src/input/view.rs index f07aac94..ec63e183 100644 --- a/crates/warp_tui/src/input/view.rs +++ b/crates/warp_tui/src/input/view.rs @@ -22,6 +22,7 @@ use std::ops::Range; use string_offset::CharOffset; use warp::editor::{CodeEditorModel, CodeEditorModelEvent}; +use warp_editor::content::buffer::{BufferEditAction, EditOrigin}; use warp_editor::model::{CoreEditorModel, PlainTextEditorModel}; use warp_editor::render::model::{ char_cell_display_width, char_cell_line_gap_position, char_cell_line_row_starts, ColumnUnit, diff --git a/crates/watcher/src/home_watcher.rs b/crates/watcher/src/home_watcher.rs index 8cab4c38..686b3f99 100644 --- a/crates/watcher/src/home_watcher.rs +++ b/crates/watcher/src/home_watcher.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; use std::time::Duration; -use notify_debouncer_full::notify::{RecursiveMode, WatchFilter}; use galaxyui_core::{Entity, ModelContext, ModelHandle, SingletonEntity}; +use notify_debouncer_full::notify::{RecursiveMode, WatchFilter}; use crate::{BulkFilesystemWatcher, BulkFilesystemWatcherEvent}; diff --git a/crates/watcher/src/lib.rs b/crates/watcher/src/lib.rs index 7deb307f..05ca223d 100644 --- a/crates/watcher/src/lib.rs +++ b/crates/watcher/src/lib.rs @@ -8,6 +8,7 @@ use std::time::Duration; pub mod home_watcher; use anyhow::Result; use futures::channel::oneshot; +use galaxyui_core::{Entity, ModelContext}; pub use home_watcher::{HomeDirectoryWatcher, HomeDirectoryWatcherEvent}; use notify_debouncer_full::notify::event::{ModifyKind, RenameMode}; use notify_debouncer_full::notify::{ @@ -17,7 +18,6 @@ use notify_debouncer_full::{ new_debouncer_opt, DebounceEventHandler, DebounceEventResult, DebouncedEvent, Debouncer, NoCache, }; -use galaxyui_core::{Entity, ModelContext}; #[derive(Debug)] enum BackgroundFileWatcherCommand { diff --git a/script/presubmit b/script/presubmit index 7f4c9551..5bc40c5a 100755 --- a/script/presubmit +++ b/script/presubmit @@ -22,13 +22,13 @@ echo "Checking for inline Rust test modules..." echo "Inline Rust test module check succeeded..." echo "Running clippy..." -# Exclude warp_completer because we run clippy on it with default features (rather than all features) below. +# Exclude galaxy_completer because we run clippy on it with default features (rather than all features) below. # # TODO(vorporeal): Re-enable the `all-features` flag once we've fixed things. -cargo clippy --workspace --exclude warp_completer --all-targets --tests -- -D warnings -# Run clippy on warp_completer with default, rather than all features enabled, because there is +cargo clippy --workspace --exclude galaxy_completer --all-targets --tests -- -D warnings +# Run clippy on galaxy_completer with default, rather than all features enabled, because there is # feature-gated logic for the WIP completions-on-js implementation. -cargo clippy -p warp_completer --all-targets --tests -- -D warnings +cargo clippy -p galaxy_completer --all-targets --tests -- -D warnings echo "clippy succeeded..." echo "Running clang-format..." @@ -57,9 +57,9 @@ fi echo "Running tests via nextest..." cargo nextest run --no-fail-fast --workspace --exclude command-signatures-v2 -# Run warp_completer tests with the "v2" (completions-on-js) flag enabled. We do this to ensure that +# Run galaxy_completer tests with the "v2" (completions-on-js) flag enabled. We do this to ensure that # the v2 completions implementation doesn't regress/rot while it's development is paused. -cargo nextest run -p warp_completer --features v2 +cargo nextest run -p galaxy_completer --features v2 echo "Running doc tests..." cargo test --doc echo "Tests succeeded..."