diff --git a/Cargo.lock b/Cargo.lock index e1545957..d643c573 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5191,7 +5191,7 @@ dependencies = [ [[package]] name = "galaxy" -version = "1.2.1" +version = "1.3.0" dependencies = [ "addr", "aho-corasick", diff --git a/app/build.rs b/app/build.rs index 3be79831..8fb07f53 100644 --- a/app/build.rs +++ b/app/build.rs @@ -394,7 +394,7 @@ fn embed_resource_file(target_dir: &Path) { use std::io::Write; let version = env::var("GIT_RELEASE_TAG").unwrap_or("v0".to_owned()); - let app_name = env::var("WARP_APP_NAME").unwrap_or("Warp".to_owned()); + let app_name = env::var("GALAXY_APP_NAME").unwrap_or("Galaxy".to_owned()); let bin_name = env::var("CARGO_BIN_NAME").unwrap_or("local".to_owned()); let icon_path = Path::new("channels") diff --git a/app/src/ai/agent/api.rs b/app/src/ai/agent/api.rs index 3add69bf..b6062f2d 100644 --- a/app/src/ai/agent/api.rs +++ b/app/src/ai/agent/api.rs @@ -139,6 +139,8 @@ pub struct RequestParams { /// can store them back into the conversation for the next request cycle. pub bedrock_messages_sent: std::sync::Arc>>, + /// Whether this request is a conversation summarization/compaction. + pub is_summarization: bool, } pub type Event = Result>; @@ -327,6 +329,7 @@ impl RequestParams { agent_name: None, bedrock_message_history: Vec::new(), bedrock_messages_sent: std::sync::Arc::new(std::sync::Mutex::new(Vec::new())), + is_summarization: false, } } } diff --git a/app/src/ai/agent/api/impl.rs b/app/src/ai/agent/api/impl.rs index 5cee5f1e..2d598f28 100644 --- a/app/src/ai/agent/api/impl.rs +++ b/app/src/ai/agent/api/impl.rs @@ -154,6 +154,7 @@ pub async fn generate_multi_agent_output( root_task_id: params.root_task_id.clone(), bedrock_message_history: params.bedrock_message_history.clone(), bedrock_messages_sent: params.bedrock_messages_sent.clone(), + is_summarization: params.is_summarization, }; match translator::execute(translator_request, &mut request).await { diff --git a/app/src/ai/agent/api/impl_tests.rs b/app/src/ai/agent/api/impl_tests.rs index 9a9e8ec0..14693ac7 100644 --- a/app/src/ai/agent/api/impl_tests.rs +++ b/app/src/ai/agent/api/impl_tests.rs @@ -42,6 +42,7 @@ fn request_params_with_ask_user_question_enabled(ask_user_question_enabled: bool agent_name: None, bedrock_message_history: Vec::new(), bedrock_messages_sent: std::sync::Arc::new(std::sync::Mutex::new(Vec::new())), + is_summarization: false, } } diff --git a/app/src/ai/agent/conversation.rs b/app/src/ai/agent/conversation.rs index dc219ef3..eb2bf865 100644 --- a/app/src/ai/agent/conversation.rs +++ b/app/src/ai/agent/conversation.rs @@ -30,7 +30,7 @@ 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::{EntityId, ModelContext, SingletonEntity}; use uuid::Uuid; @@ -235,6 +235,19 @@ pub struct AIConversation { /// tool calls, and tool results sent to/received from Bedrock across all /// request cycles. This is the source of truth for what Bedrock sees. bedrock_message_history: Vec, + + /// Live context token count from the most recent Bedrock response. + /// This is the actual input_tokens reported by Bedrock — represents the current + /// context window size, NOT a cumulative total. + current_context_tokens: u32, + + /// Guards against repeated auto-compact triggers within the same high-usage window. + /// Set to true when auto-compact fires; reset when summarization completes. + has_pending_auto_compact: bool, + + /// Number of times this child agent conversation has been automatically + /// restarted after a transient error. Capped at MAX_SUBAGENT_RETRIES. + subagent_retry_count: u8, } pub(crate) fn artifact_from_fork_proto( @@ -287,6 +300,9 @@ impl AIConversation { is_remote_child: false, last_event_sequence: None, bedrock_message_history: Vec::new(), + current_context_tokens: 0, + has_pending_auto_compact: false, + subagent_retry_count: 0, } } @@ -314,6 +330,20 @@ impl AIConversation { .cmp(depths.get(a.as_str()).unwrap_or(&0)) }); + // Collect all task messages for rebuilding bedrock_message_history on restore. + // We must do this before consuming the tasks into exchanges. + let all_task_messages: Vec<&api::Message> = api_tasks_by_id + .values() + .flat_map(|task| task.messages.iter()) + .collect(); + let bedrock_message_history: Vec = + all_task_messages + .iter() + .filter_map(|msg| { + crate::ai::bedrock::request_translator::convert_proto_message(msg) + }) + .collect(); + let mut api_tasks_and_exchanges_by_id: HashMap<_, _> = api_tasks_by_id .into_iter() .map(|(id, task)| { @@ -469,7 +499,10 @@ impl AIConversation { parent_conversation_id, is_remote_child: false, last_event_sequence, - bedrock_message_history: Vec::new(), + bedrock_message_history, + current_context_tokens: 0, + has_pending_auto_compact: false, + subagent_retry_count: 0, }) } @@ -521,6 +554,26 @@ impl AIConversation { self.conversation_usage_metadata.context_window_usage } + pub fn set_context_window_usage(&mut self, value: f32) { + self.conversation_usage_metadata.context_window_usage = value; + } + + pub fn current_context_tokens(&self) -> u32 { + self.current_context_tokens + } + + pub fn set_current_context_tokens(&mut self, tokens: u32) { + self.current_context_tokens = tokens; + } + + pub fn has_pending_auto_compact(&self) -> bool { + self.has_pending_auto_compact + } + + pub fn set_has_pending_auto_compact(&mut self, value: bool) { + self.has_pending_auto_compact = value; + } + pub fn credits_spent(&self) -> f32 { (self.conversation_usage_metadata.credits_spent * 10.0).round() / 10.0 } @@ -859,6 +912,14 @@ impl AIConversation { self.is_remote_child = true; } + pub fn subagent_retry_count(&self) -> u8 { + self.subagent_retry_count + } + + pub fn increment_subagent_retry_count(&mut self) { + self.subagent_retry_count = self.subagent_retry_count.saturating_add(1); + } + /// Returns a flat list of linearized messages across all tasks, interpolating subtask messages /// in between subagent tool calls and results, effectively corresponding to the order in which /// the messages were created and added to the conversation. @@ -1566,6 +1627,17 @@ impl AIConversation { if was_user_initiated_request { self.last_block_token_usage_by_model.clear(); } + + // Update live context token count from this response's input tokens. + // This represents the actual current context window size (not cumulative). + let live_input: u32 = token_usage + .iter() + .map(|u| u.total_input + u.input_cache_read + u.input_cache_write) + .sum(); + if live_input > 0 { + self.current_context_tokens = live_input; + } + for usage in token_usage.into_iter() { let entry = self .total_token_usage_by_model @@ -1666,6 +1738,7 @@ impl AIConversation { // so we only update the summarized flag if it's going from false to true. if usage_metadata.summarized && !self.conversation_usage_metadata.was_summarized { self.conversation_usage_metadata.was_summarized = usage_metadata.summarized; + self.has_pending_auto_compact = false; } } Ok(()) @@ -3844,7 +3917,7 @@ impl ConversationStatus { } } - pub fn status_icon_and_color(&self, theme: &WarpTheme) -> (Icon, ColorU) { + pub fn status_icon_and_color(&self, theme: &GalaxyTheme) -> (Icon, ColorU) { match self { ConversationStatus::InProgress => (Icon::ClockLoader, theme.ansi_fg_magenta()), ConversationStatus::Success => (Icon::Check, theme.ansi_fg_green()), diff --git a/app/src/ai/agent_conversations_model.rs b/app/src/ai/agent_conversations_model.rs index bfb18b71..7da9384e 100644 --- a/app/src/ai/agent_conversations_model.rs +++ b/app/src/ai/agent_conversations_model.rs @@ -29,7 +29,7 @@ use galaxy_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, WarpTheme}; +use galaxy_core::ui::theme::{color::internal_colors, GalaxyTheme}; use galaxyui::color::ColorU; use galaxyui::r#async::Timer; use galaxyui::windowing::{StateEvent, WindowManager}; @@ -334,7 +334,7 @@ impl AgentRunDisplayStatus { ) } - pub fn status_icon_and_color(&self, theme: &WarpTheme) -> (Icon, ColorU) { + pub fn status_icon_and_color(&self, theme: &GalaxyTheme) -> (Icon, ColorU) { match self { AgentRunDisplayStatus::TaskQueued | AgentRunDisplayStatus::TaskPending diff --git a/app/src/ai/agent_management/notifications/item_rendering.rs b/app/src/ai/agent_management/notifications/item_rendering.rs index 91a55436..dddf9073 100644 --- a/app/src/ai/agent_management/notifications/item_rendering.rs +++ b/app/src/ai/agent_management/notifications/item_rendering.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use galaxy_core::ui::icons::Icon; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::clipboard::ClipboardContent; use galaxyui::elements::{ ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, @@ -331,7 +331,7 @@ fn render_timestamp_with_dot(item: &NotificationItem, appearance: &Appearance) - fn render_expand_chevron( expanded: bool, on_click: OnExpandClick, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let icon = if expanded { Icon::ChevronDown @@ -411,7 +411,7 @@ const NOTIFICATION_AVATAR_SIZING: IconWithStatusSizing = IconWithStatusSizing { fn render_agent_avatar( agent: NotificationSourceAgent, category: NotificationCategory, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let status = notification_category_to_conversation_status(category); let variant = match agent { diff --git a/app/src/ai/agent_sdk/common.rs b/app/src/ai/agent_sdk/common.rs index 8bbbaaf0..fb39f0de 100644 --- a/app/src/ai/agent_sdk/common.rs +++ b/app/src/ai/agent_sdk/common.rs @@ -134,14 +134,14 @@ where } } -/// Refresh Warp Drive before executing an operation. +/// Refresh Galaxy Drive before executing an operation. pub fn refresh_warp_drive( ctx: &AppContext, ) -> impl Future> + Send + 'static { UpdateManager::as_ref(ctx) .initial_load_complete() .with_timeout(WARP_DRIVE_SYNC_TIMEOUT) - .map_err(|_| anyhow::anyhow!("Timed out waiting for Warp Drive to sync")) + .map_err(|_| anyhow::anyhow!("Timed out waiting for Galaxy Drive to sync")) } /// Fetch the conversation's server metadata and validate that its harness matches the caller's @@ -213,7 +213,7 @@ pub enum EnvironmentChoice { impl EnvironmentChoice { /// Resolve the environment to use when creating an agent integration. - /// Warp Drive *must* have been synced first. + /// Galaxy Drive *must* have been synced first. pub fn resolve_for_create( args: EnvironmentCreateArgs, ctx: &AppContext, @@ -279,7 +279,7 @@ Without an environment, the agent will not be able to access private repositorie /// Resolve the environment to use when updating an agent integration. If the user did not /// request any changes to the environment, this returns `Ok(None)`. - /// Warp Drive *must* have been synced first. + /// Galaxy Drive *must* have been synced first. pub fn resolve_for_update( args: EnvironmentUpdateArgs, ctx: &AppContext, diff --git a/app/src/ai/agent_sdk/driver.rs b/app/src/ai/agent_sdk/driver.rs index bd49b76d..451d1d03 100644 --- a/app/src/ai/agent_sdk/driver.rs +++ b/app/src/ai/agent_sdk/driver.rs @@ -357,7 +357,7 @@ pub enum AgentDriverError { #[error("Agent profile \"{0}\" not found")] ProfileError(String), #[error( - "Failed to authenticate with server - please log in via 'oz login', provide an API key via '--api-key ', or set the WARP_API_KEY environment variable" + "Failed to authenticate with server - please log in via 'oz login', provide an API key via '--api-key ', or set the GALAXY_API_KEY environment variable" )] NotLoggedIn, #[error("Saved prompt not found for id {0}")] @@ -369,7 +369,7 @@ pub enum AgentDriverError { #[source] error: terminal::ShareSessionError, }, - #[error("Error syncing Warp Drive")] + #[error("Error syncing Galaxy Drive")] WarpDriveSyncFailed, #[error("Requested environment not found: {0}")] EnvironmentNotFound(String), diff --git a/app/src/ai/agent_sdk/driver/error_classification.rs b/app/src/ai/agent_sdk/driver/error_classification.rs index 3f292848..c5484b91 100644 --- a/app/src/ai/agent_sdk/driver/error_classification.rs +++ b/app/src/ai/agent_sdk/driver/error_classification.rs @@ -1,3 +1,4 @@ +use crate::ai::agent::RenderableAIError; use crate::ai::blocklist::task_status_sync_model::classify_renderable_error; use crate::server::server_api::ai::TaskStatusUpdate; use galaxy_graphql::ai::{AgentTaskState, PlatformErrorCode}; @@ -66,7 +67,7 @@ pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskS AgentDriverError::WarpDriveSyncFailed => ( AgentTaskState::Error, TaskStatusUpdate::with_error_code( - "Warp Drive failed to sync. Please check your network connection and try again.", + "Galaxy Drive failed to sync. Please check your network connection and try again.", PlatformErrorCode::InternalError, ), ), @@ -76,7 +77,7 @@ pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskS AgentTaskState::Error, TaskStatusUpdate::with_error_code( format!( - "Authentication required. Log in via '{bin} login', provide an API key via '--api-key', or set the WARP_API_KEY environment variable." + "Authentication required. Log in via '{bin} login', provide an API key via '--api-key', or set the GALAXY_API_KEY environment variable." ), PlatformErrorCode::AuthenticationRequired, ), @@ -95,7 +96,7 @@ pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskS AgentTaskState::Failed, TaskStatusUpdate::with_error_code( format!( - "MCP server {uuid} was not found. Verify the server exists in your Warp Drive and the UUID is correct." + "MCP server {uuid} was not found. Verify the server exists in your Galaxy Drive and the UUID is correct." ), PlatformErrorCode::EnvironmentSetupFailed, ), @@ -125,7 +126,7 @@ pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskS AgentTaskState::Failed, TaskStatusUpdate::with_error_code( format!( - "Agent profile \"{name}\" not found. Check the profile ID and ensure it exists in your team's Warp Drive." + "Agent profile \"{name}\" not found. Check the profile ID and ensure it exists in your team's Galaxy Drive." ), PlatformErrorCode::ResourceNotFound, ), @@ -134,7 +135,7 @@ pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskS AgentTaskState::Failed, TaskStatusUpdate::with_error_code( format!( - "Saved prompt not found for ID {id}. Verify the prompt exists in your Warp Drive." + "Saved prompt not found for ID {id}. Verify the prompt exists in your Galaxy Drive." ), PlatformErrorCode::ResourceNotFound, ), @@ -302,6 +303,31 @@ pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskS } } +/// Returns true if an `AgentDriverError` represents a transient condition that +/// a subagent can recover from by retrying (e.g., network issues, rate limits, +/// server overload). Permanent errors (auth, config, cancelled) return false. +pub fn is_self_recoverable(error: &AgentDriverError) -> bool { + match error { + AgentDriverError::ConversationError { error: renderable } => { + matches!( + renderable, + RenderableAIError::ServerOverloaded + | RenderableAIError::Other { + will_attempt_resume: true, + .. + } + ) + } + AgentDriverError::WarpDriveSyncFailed + | AgentDriverError::TeamMetadataRefreshTimeout + | AgentDriverError::ShareSessionFailed { + error: ShareSessionError::Timeout, + .. + } => true, + _ => false, + } +} + #[cfg(test)] #[path = "error_classification_tests.rs"] mod tests; diff --git a/app/src/ai/agent_sdk/environment.rs b/app/src/ai/agent_sdk/environment.rs index 84a87279..a89968a3 100644 --- a/app/src/ai/agent_sdk/environment.rs +++ b/app/src/ai/agent_sdk/environment.rs @@ -194,7 +194,7 @@ impl EnvironmentCommandRunner { ctx.spawn(initial_sync, move |_, result, ctx| { if result.is_err() { super::report_fatal_error( - anyhow::anyhow!("Timed out waiting for Warp Drive to sync"), + anyhow::anyhow!("Timed out waiting for Galaxy Drive to sync"), ctx, ); return; @@ -265,7 +265,7 @@ impl EnvironmentCommandRunner { ctx.spawn(initial_sync, move |_, result, ctx| { if result.is_err() { super::report_fatal_error( - anyhow::anyhow!("Timed out waiting for Warp Drive to sync"), + anyhow::anyhow!("Timed out waiting for Galaxy Drive to sync"), ctx, ); return; @@ -474,7 +474,7 @@ impl EnvironmentCommandRunner { ctx.spawn(initial_sync, move |_, result, ctx| { if result.is_err() { super::report_fatal_error( - anyhow::anyhow!("Timed out waiting for Warp Drive to sync"), + anyhow::anyhow!("Timed out waiting for Galaxy Drive to sync"), ctx, ); return; @@ -856,7 +856,7 @@ impl EnvironmentCommandRunner { ctx.spawn(initial_sync, move |_, result, ctx| { if result.is_err() { super::report_fatal_error( - anyhow::anyhow!("Timed out waiting for Warp Drive to sync"), + anyhow::anyhow!("Timed out waiting for Galaxy Drive to sync"), ctx, ); return; @@ -1035,7 +1035,7 @@ impl EnvironmentCommandRunner { ctx.spawn(initial_sync, move |_, result, ctx| { if result.is_err() { super::report_fatal_error( - anyhow::anyhow!("Timed out waiting for Warp Drive to sync"), + anyhow::anyhow!("Timed out waiting for Galaxy Drive to sync"), ctx, ); return; diff --git a/app/src/ai/agent_sdk/mod.rs b/app/src/ai/agent_sdk/mod.rs index 9e250dd2..3ef201d4 100644 --- a/app/src/ai/agent_sdk/mod.rs +++ b/app/src/ai/agent_sdk/mod.rs @@ -175,7 +175,7 @@ fn dispatch_command( schedule::run(ctx, global_options, schedule_cmd) } CliCommand::Secret(secret_cmd) => { - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { return Err(anyhow::anyhow!("invalid value 'secret'")); } secret::run(ctx, global_options, secret_cmd) @@ -547,7 +547,7 @@ impl AgentDriverRunner { // Ensure we've synced team state before starting the driver. Self::refresh_team_metadata(&foreground).await?; - // Wait for Warp Drive to sync before building the task config, since + // Wait for Galaxy Drive to sync before building the task config, since // prompt resolution (SavedPrompt -> workflow lookup) and environment // resolution (CloudAmbientAgentEnvironment lookup) depend on it. if foreground @@ -1328,7 +1328,7 @@ fn launch_command( dispatched = true; let auth_state = AuthStateProvider::handle(ctx).as_ref(ctx).get(); let message = if auth_state.is_api_key_authenticated() { - "Your API key is invalid. Please provide a valid key via '--api-key' or the WARP_API_KEY environment variable.".to_string() + "Your API key is invalid. Please provide a valid key via '--api-key' or the GALAXY_API_KEY environment variable.".to_string() } else { format!("Your credentials are invalid. Please log in again with `{cli_name} login`.") }; diff --git a/app/src/ai/agent_sdk/secret.rs b/app/src/ai/agent_sdk/secret.rs index b47a92b9..ca1d32b1 100644 --- a/app/src/ai/agent_sdk/secret.rs +++ b/app/src/ai/agent_sdk/secret.rs @@ -72,7 +72,7 @@ pub fn run( global_options: GlobalOptions, command: SecretCommand, ) -> Result<()> { - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { return Err(anyhow::anyhow!("This feature is not enabled")); } diff --git a/app/src/ai/agent_tips.rs b/app/src/ai/agent_tips.rs index 07af5a9e..5fdad0bc 100644 --- a/app/src/ai/agent_tips.rs +++ b/app/src/ai/agent_tips.rs @@ -118,7 +118,7 @@ static DEFAULT_TIPS: LazyLock> = LazyLock::new(|| { description: "Store reusable workflows, notebooks, and prompts in your".to_string(), link: Some("https://docs.warp.dev/knowledge-and-collaboration/warp-drive".to_string()), binding_name: None, - action: Some(WorkspaceAction::OpenWarpDrive), + action: Some(WorkspaceAction::OpenGalaxyDrive), kind: AgentTipKind::WarpDrive, }, AgentTip { @@ -129,7 +129,7 @@ static DEFAULT_TIPS: LazyLock> = LazyLock::new(|| { kind: AgentTipKind::General, }, AgentTip { - description: "`@` to add context from files, blocks, or Warp Drive objects to your prompt.".to_string(), + description: "`@` to add context from files, blocks, or Galaxy Drive objects to your prompt.".to_string(), link: Some("https://docs.warp.dev/agent-platform/local-agents/agent-context/using-to-add-context".to_string()), binding_name: None, action: None, @@ -297,7 +297,7 @@ static DEFAULT_TIPS: LazyLock> = LazyLock::new(|| { kind: AgentTipKind::General, }, AgentTip { - description: "`/init` to generate a `WARP.md` file and define project rules for the agent.".to_string(), + description: "`/init` to generate a `GALAXY.md` file and define project rules for the agent.".to_string(), link: Some("https://docs.warp.dev/agent-platform/capabilities/rules".to_string()), binding_name: None, action: None, @@ -411,7 +411,7 @@ impl WorkspaceAction { pub fn display_text(&self) -> Option { match self { WorkspaceAction::OpenPalette { .. } => Some("Open palette".to_string()), - WorkspaceAction::OpenWarpDrive => Some("Warp Drive.".to_string()), + WorkspaceAction::OpenGalaxyDrive => Some("Galaxy Drive.".to_string()), WorkspaceAction::ToggleRightPanel => Some("Show diff view".to_string()), _ => None, } diff --git a/app/src/ai/ai_document_view.rs b/app/src/ai/ai_document_view.rs index 25325596..79901a4e 100644 --- a/app/src/ai/ai_document_view.rs +++ b/app/src/ai/ai_document_view.rs @@ -610,7 +610,7 @@ impl AIDocumentView { let appearance = Appearance::as_ref(app); let ui_builder = appearance.ui_builder().clone(); let tooltip = ui_builder - .tool_tip("Save and auto-sync this plan to your Warp Drive".to_string()) + .tool_tip("Save and auto-sync this plan to your Galaxy Drive".to_string()) .build() .finish(); let sync_button_mouse_state = self.sync_button_mouse_state.clone(); @@ -663,7 +663,7 @@ impl AIDocumentView { let color = theme.nonactive_ui_detail().into_solid(); let ui_builder = appearance.ui_builder().clone(); let tooltip_text = - "This plan is synced to your Warp Drive and will auto save any edits you make." + "This plan is synced to your Galaxy Drive and will auto save any edits you make." .to_string(); let synced_status_mouse_state = self.synced_status_mouse_state.clone(); Container::new( @@ -1233,7 +1233,7 @@ impl BackingView for AIDocumentView { .into_item(), ); menu_items.push( - MenuItemFields::new("Show in Warp Drive") + MenuItemFields::new("Show in Galaxy Drive") .with_on_select_action(AIDocumentAction::ShowInWarpDrive) .with_icon(Icon::WarpDrive) .into_item(), diff --git a/app/src/ai/ambient_agents/task.rs b/app/src/ai/ambient_agents/task.rs index 94168c10..d6693f1b 100644 --- a/app/src/ai/ambient_agents/task.rs +++ b/app/src/ai/ambient_agents/task.rs @@ -4,7 +4,7 @@ use anyhow::anyhow; use chrono::{DateTime, Utc}; use galaxy_cli::agent::Harness; use galaxy_core::report_error; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::color::ColorU; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -406,7 +406,7 @@ impl AmbientAgentTaskState { } } - pub fn status_icon_and_color(&self, theme: &WarpTheme) -> (Icon, ColorU) { + pub fn status_icon_and_color(&self, theme: &GalaxyTheme) -> (Icon, ColorU) { match self { AmbientAgentTaskState::Queued | AmbientAgentTaskState::Pending diff --git a/app/src/ai/bedrock/client.rs b/app/src/ai/bedrock/client.rs index 31391747..9756a974 100644 --- a/app/src/ai/bedrock/client.rs +++ b/app/src/ai/bedrock/client.rs @@ -140,6 +140,7 @@ impl BedrockClient { user_query: Option, diagnostic_logger: Option>, messages_sent: Arc>>, + is_summarization: bool, ) -> Result { let effective_model_id = if cross_region_inference { apply_cross_region_prefix(model_id, &self.region) @@ -228,6 +229,7 @@ impl BedrockClient { diagnostic_logger, messages_sent, effective_model_id, + is_summarization, ))) } diff --git a/app/src/ai/bedrock/request_translator.rs b/app/src/ai/bedrock/request_translator.rs index c84f4658..afcbe1a0 100644 --- a/app/src/ai/bedrock/request_translator.rs +++ b/app/src/ai/bedrock/request_translator.rs @@ -175,6 +175,20 @@ pub fn extract_new_input_messages(request: &api::Request) -> Vec { + let prompt = if summarize.prompt.is_empty() { + "Please summarize this conversation so far, preserving key decisions, \ + code changes, and important context. Be concise but retain all \ + information needed to continue the work." + .to_string() + } else { + summarize.prompt.clone() + }; + results.push(ConversationMessage { + role: MessageRole::User, + content: MessageContent::Text(prompt), + }); + } _ => {} } @@ -378,6 +392,30 @@ fn extract_input_messages(request: &api::Request) -> Vec { }); } } + api::request::input::Type::SummarizeConversation(summarize) => { + let prompt = if summarize.prompt.is_empty() { + "Please summarize this conversation so far, preserving key decisions, \ + code changes, and important context. Be concise but retain all \ + information needed to continue the work." + .to_string() + } else { + summarize.prompt.clone() + }; + results.push(api::Message { + id: uuid::Uuid::new_v4().to_string(), + task_id: task_id.clone(), + request_id: String::new(), + timestamp: None, + server_message_data: String::new(), + citations: vec![], + message: Some(api::message::Message::UserQuery( + api::message::UserQuery { + query: prompt, + ..Default::default() + }, + )), + }); + } _ => {} } @@ -1171,8 +1209,9 @@ pub fn extract_messages_from_request(request: &api::Request) -> Vec Option { +/// Converts a proto `api::Message` into a `ConversationMessage` for the Bedrock message history. +/// Used to rebuild the message history from persisted task messages on session restore. +pub fn convert_proto_message(msg: &api::Message) -> Option { let message_content = msg.message.as_ref()?; match message_content { api::message::Message::UserQuery(query) => Some(ConversationMessage { @@ -1184,7 +1223,7 @@ fn convert_proto_message_for_test(msg: &api::Message) -> Option { - let (name, input) = extract_tool_call_info_for_test(tool_call); + let (name, input) = extract_tool_call_info(tool_call); Some(ConversationMessage { role: MessageRole::Assistant, content: MessageContent::ToolUse { @@ -1214,11 +1253,8 @@ fn convert_proto_message_for_test(msg: &api::Message) -> Option (String, serde_json::Value) { +fn extract_tool_call_info(tool_call: &api::message::ToolCall) -> (String, serde_json::Value) { if let Some(tool) = &tool_call.tool { match tool { api::message::tool_call::Tool::RunShellCommand(cmd) => ( @@ -1254,6 +1290,12 @@ fn extract_tool_call_info_for_test( } } +#[cfg(test)] +fn convert_proto_message_for_test(msg: &api::Message) -> Option { + convert_proto_message(msg) +} + + #[cfg(test)] #[path = "request_translator_tests.rs"] mod tests; diff --git a/app/src/ai/bedrock/response_translator.rs b/app/src/ai/bedrock/response_translator.rs index d5d36b9c..4fb717f9 100644 --- a/app/src/ai/bedrock/response_translator.rs +++ b/app/src/ai/bedrock/response_translator.rs @@ -65,6 +65,7 @@ pub fn bedrock_stream_to_response_events( diagnostic_logger: Option>, messages_sent: Arc>>, model_id: String, + is_summarization: bool, ) -> BoxStream<'static, Event> { let request_id = Uuid::new_v4().to_string(); let conversation_id = Uuid::new_v4().to_string(); @@ -470,6 +471,7 @@ pub fn bedrock_stream_to_response_events( cache_read_input_tokens, cache_write_input_tokens, &model_id, + is_summarization, ); yield Ok(finished_event); }; @@ -555,6 +557,7 @@ pub(super) fn build_stream_finished( cache_read_input_tokens: i32, cache_write_input_tokens: i32, model_id: &str, + is_summarization: bool, ) -> ResponseEvent { let total_tokens = (input_tokens + output_tokens + cache_read_input_tokens + cache_write_input_tokens) as u32; @@ -598,7 +601,7 @@ pub(super) fn build_stream_finished( #[allow(deprecated)] let conversation_usage_metadata = Some(stream_finished::ConversationUsageMetadata { context_window_usage: context_usage, - summarized: false, + summarized: is_summarization, credits_spent: 0.0, token_usage: vec![], tool_usage_metadata: None, diff --git a/app/src/ai/bedrock/translator.rs b/app/src/ai/bedrock/translator.rs index 09061c04..f3b729fb 100644 --- a/app/src/ai/bedrock/translator.rs +++ b/app/src/ai/bedrock/translator.rs @@ -14,6 +14,7 @@ pub struct TranslatorRequest { pub root_task_id: Option, pub bedrock_message_history: Vec, pub bedrock_messages_sent: Arc>>, + pub is_summarization: bool, } pub async fn execute( @@ -100,6 +101,7 @@ pub async fn execute( user_query_text, diagnostic_logger, params.bedrock_messages_sent.clone(), + params.is_summarization, ) .await?; 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 f0ec2a12..11ffee74 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 @@ -6,7 +6,7 @@ use crate::ai::agent::ReadSkillResult; use crate::ai::agent::{AIAgentAction, AIAgentActionId, AIAgentActionType}; use crate::ai::blocklist::action_model::AIConversationId; use crate::ai::skills::SkillManager; -use crate::warp_managed_paths_watcher::WarpManagedPathsWatcher; +use crate::galaxy_managed_paths_watcher::GalaxyManagedPathsWatcher; use ai::skills::{parse_skill, SkillReference}; use galaxyui::App; use repo_metadata::{ @@ -22,7 +22,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); app.add_singleton_model(SkillManager::new); } diff --git a/app/src/ai/blocklist/agent_view/mod.rs b/app/src/ai/blocklist/agent_view/mod.rs index cf481a9d..21c99a71 100644 --- a/app/src/ai/blocklist/agent_view/mod.rs +++ b/app/src/ai/blocklist/agent_view/mod.rs @@ -8,6 +8,7 @@ mod inline_agent_view_header; // TODO: Move orchestration_conversation_links module import elsewhere. pub(crate) mod orchestration_conversation_links; pub mod shortcuts; +pub(crate) mod subagent_inline_panel; mod zero_state_block; pub use agent_input_footer::*; diff --git a/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs b/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs new file mode 100644 index 00000000..3eabcfaa --- /dev/null +++ b/app/src/ai/blocklist/agent_view/subagent_inline_panel.rs @@ -0,0 +1,343 @@ +//! Inline subagent panel rendered within the parent agent's chat flow. +//! +//! Shows a collapsible panel with the subagent's status, a mini-transcript of +//! recent messages, and controls to expand to full view or cancel. + +use galaxy_core::ui::theme::Fill; +use galaxyui::elements::{ + ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element, Empty, Flex, + MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Shrinkable, Text, +}; +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::blocklist::inline_action::inline_action_header::{ + ICON_MARGIN, INLINE_ACTION_HEADER_VERTICAL_PADDING, INLINE_ACTION_HORIZONTAL_PADDING, +}; +use crate::ai::blocklist::inline_action::inline_action_icons::icon_size; +use crate::ai::blocklist::BlocklistAIHistoryModel; +use crate::appearance::Appearance; +use crate::ui_components::blended_colors; +use crate::ui_components::icons::Icon; + +const MINI_TRANSCRIPT_MAX_LINES: usize = 8; +const PANEL_MAX_HEIGHT: f32 = 200.; +const PANEL_CORNER_RADIUS: f32 = 8.; + +/// State for a single subagent inline panel instance. +#[derive(Debug, Clone)] +pub struct SubagentPanelState { + pub conversation_id: AIConversationId, + pub is_expanded: bool, + pub header_mouse_state: MouseStateHandle, + pub expand_button_mouse_state: MouseStateHandle, + pub cancel_button_mouse_state: MouseStateHandle, +} + +impl SubagentPanelState { + pub fn new(conversation_id: AIConversationId) -> Self { + Self { + conversation_id, + is_expanded: false, + header_mouse_state: MouseStateHandle::default(), + expand_button_mouse_state: MouseStateHandle::default(), + cancel_button_mouse_state: MouseStateHandle::default(), + } + } +} + +/// Renders the inline subagent panel for a child conversation. +pub fn render_subagent_inline_panel( + state: &SubagentPanelState, + app: &AppContext, +) -> Box { + let appearance = Appearance::as_ref(app); + let theme = appearance.theme(); + + let history_model = BlocklistAIHistoryModel::as_ref(app); + let Some(conversation) = history_model.conversation(&state.conversation_id) else { + return Empty::new().finish(); + }; + + let status = conversation.status().clone(); + let agent_name = conversation + .agent_name() + .unwrap_or("Subagent") + .to_string(); + + let panel_bg = blended_colors::neutral_2(theme); + + let mut column = Flex::column().with_cross_axis_alignment(CrossAxisAlignment::Stretch); + + // Header — always visible + column.add_child(render_panel_header( + &agent_name, + &status, + state, + panel_bg, + app, + )); + + // Body (mini-transcript) — only when expanded + if state.is_expanded { + let transcript_lines = collect_mini_transcript(&state.conversation_id, app); + if !transcript_lines.is_empty() { + column.add_child(render_mini_transcript(&transcript_lines, panel_bg, app)); + } + } + + // Footer — show summary when complete + if status.is_done() { + if let Some(summary) = get_completion_summary(&state.conversation_id, app) { + column.add_child(render_summary_footer(&summary, panel_bg, app)); + } + } + + Container::new(column.finish()) + .with_background_color(panel_bg) + .with_corner_radius(CornerRadius::with_all(Radius::Pixels(PANEL_CORNER_RADIUS))) + .with_margin_top(4.) + .with_margin_bottom(4.) + .finish() +} + +fn render_panel_header( + agent_name: &str, + status: &ConversationStatus, + state: &SubagentPanelState, + _background: ColorU, + app: &AppContext, +) -> Box { + let appearance = Appearance::as_ref(app); + let theme = appearance.theme(); + let font_family = appearance.ui_font_family(); + let font_size = appearance.monospace_font_size(); + let surface = theme.surface_2(); + + let mut header_row = Flex::row() + .with_main_axis_alignment(MainAxisAlignment::SpaceBetween) + .with_main_axis_size(MainAxisSize::Max) + .with_cross_axis_alignment(CrossAxisAlignment::Center); + + // 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 status_icon_element = ConstrainedBox::new( + galaxyui::elements::Icon::new(icon.into(), icon_color).finish(), + ) + .with_width(icon_size(app)) + .with_height(icon_size(app)) + .finish(); + + left_side.add_child( + Container::new(status_icon_element) + .with_margin_right(ICON_MARGIN) + .finish(), + ); + + let name_color: ColorU = theme.main_text_color(surface).into(); + left_side.add_child( + Text::new_inline(agent_name.to_string(), font_family, font_size) + .with_color(name_color) + .finish(), + ); + + let status_text = match status { + ConversationStatus::InProgress => "Working...", + ConversationStatus::Success => "Complete", + ConversationStatus::Error => "Error", + ConversationStatus::Cancelled => "Cancelled", + ConversationStatus::Blocked { .. } => "Blocked", + }; + let status_text_color = blended_colors::text_disabled(theme, surface); + left_side.add_child( + Container::new( + Text::new_inline(status_text.to_string(), font_family, font_size) + .with_color(status_text_color) + .finish(), + ) + .with_margin_left(8.) + .finish(), + ); + + header_row.add_child(Shrinkable::new(1.0, left_side.finish()).finish()); + + // Right: collapse/expand chevron + let mut right_side = Flex::row().with_cross_axis_alignment(CrossAxisAlignment::Center); + + let chevron_icon = if state.is_expanded { + Icon::ChevronDown + } else { + Icon::ChevronRight + }; + let chevron_color = blended_colors::text_disabled(theme, surface); + let chevron = ConstrainedBox::new( + galaxyui::elements::Icon::new(chevron_icon.into(), chevron_color).finish(), + ) + .with_width(icon_size(app)) + .with_height(icon_size(app)) + .finish(); + right_side.add_child( + Container::new(chevron) + .with_margin_right(4.) + .finish(), + ); + + header_row.add_child(right_side.finish()); + + Container::new(header_row.finish()) + .with_padding_left(INLINE_ACTION_HORIZONTAL_PADDING) + .with_padding_right(INLINE_ACTION_HORIZONTAL_PADDING) + .with_padding_top(INLINE_ACTION_HEADER_VERTICAL_PADDING) + .with_padding_bottom(INLINE_ACTION_HEADER_VERTICAL_PADDING) + .finish() +} + +fn collect_mini_transcript( + conversation_id: &AIConversationId, + app: &AppContext, +) -> Vec { + let history_model = BlocklistAIHistoryModel::as_ref(app); + let Some(conversation) = history_model.conversation(conversation_id) else { + return vec![]; + }; + + let mut lines = Vec::new(); + let messages = conversation.all_linearized_messages(); + for msg in messages.iter().rev().take(MINI_TRANSCRIPT_MAX_LINES * 2) { + if let Some(text) = extract_message_text(msg) { + let truncated = if text.len() > 120 { + format!("{}...", &text[..117]) + } else { + text + }; + lines.push(truncated); + if lines.len() >= MINI_TRANSCRIPT_MAX_LINES { + break; + } + } + } + lines.reverse(); + lines +} + +fn extract_message_text(msg: &api::Message) -> Option { + let message_content = msg.message.as_ref()?; + match message_content { + api::message::Message::AgentOutput(output) => { + if output.text.is_empty() { + None + } else { + Some(output.text.clone()) + } + } + api::message::Message::UserQuery(query) => { + if query.query.is_empty() { + None + } else { + Some(query.query.clone()) + } + } + _ => None, + } +} + +fn render_mini_transcript( + lines: &[String], + background: ColorU, + app: &AppContext, +) -> Box { + let appearance = Appearance::as_ref(app); + let theme = appearance.theme(); + let text_color = blended_colors::text_disabled(theme, background); + let font_family = appearance.ui_font_family(); + let font_size = appearance.monospace_font_size() - 1.; + + let mut column = Flex::column(); + for line in lines { + let prefixed = format!("> {line}"); + column.add_child( + Text::new_inline(prefixed, font_family, font_size) + .with_color(text_color) + .finish(), + ); + } + + ConstrainedBox::new( + Container::new(column.finish()) + .with_padding_left(INLINE_ACTION_HORIZONTAL_PADDING) + .with_padding_right(INLINE_ACTION_HORIZONTAL_PADDING) + .with_padding_top(4.) + .with_padding_bottom(4.) + .finish(), + ) + .with_max_height(PANEL_MAX_HEIGHT) + .finish() +} + +fn get_completion_summary( + conversation_id: &AIConversationId, + app: &AppContext, +) -> Option { + let history_model = BlocklistAIHistoryModel::as_ref(app); + let conversation = history_model.conversation(conversation_id)?; + + if !conversation.status().is_done() { + return None; + } + + let messages = conversation.all_linearized_messages(); + for msg in messages.iter().rev() { + if let Some(text) = extract_message_text(msg) { + if !text.is_empty() { + let truncated = if text.len() > 300 { + format!("{}...", &text[..297]) + } else { + text + }; + return Some(truncated); + } + } + } + None +} + +fn render_summary_footer( + summary: &str, + _background: ColorU, + app: &AppContext, +) -> Box { + let appearance = Appearance::as_ref(app); + let theme = appearance.theme(); + let surface = theme.surface_2(); + let text_color: ColorU = theme.main_text_color(surface).into(); + let label_color = blended_colors::text_disabled(theme, surface); + let font_family = appearance.ui_font_family(); + let font_size = appearance.monospace_font_size(); + + let mut row = Flex::row().with_cross_axis_alignment(CrossAxisAlignment::Start); + row.add_child( + Text::new_inline("Summary: ".to_string(), font_family, font_size) + .with_color(label_color) + .finish(), + ); + row.add_child( + Shrinkable::new( + 1.0, + Text::new_inline(summary.to_string(), font_family, font_size) + .with_color(text_color) + .finish(), + ) + .finish(), + ); + + Container::new(row.finish()) + .with_padding_left(INLINE_ACTION_HORIZONTAL_PADDING) + .with_padding_right(INLINE_ACTION_HORIZONTAL_PADDING) + .with_padding_top(6.) + .with_padding_bottom(6.) + .finish() +} diff --git a/app/src/ai/blocklist/block.rs b/app/src/ai/blocklist/block.rs index 2a9e605a..3c4459eb 100644 --- a/app/src/ai/blocklist/block.rs +++ b/app/src/ai/blocklist/block.rs @@ -90,6 +90,7 @@ use crate::ai::blocklist::inline_action::aws_bedrock_credentials_error::{ use crate::ai::blocklist::inline_action::search_codebase::{ SearchCodebaseView, SearchCodebaseViewEvent, }; +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::facts::{AIFact, AIMemory, CloudAIFactModel}; @@ -830,6 +831,9 @@ pub struct AIBlock { /// Map from web fetch message IDs to their view handles. web_fetch_views: HashMap>, + /// Map from summarization message IDs to their view handles. + summarization_views: HashMap>, + /// Map from todo list IDs to their states. todo_list_states: HashMap, @@ -1340,6 +1344,7 @@ impl AIBlock { search_codebase_view: Default::default(), web_search_views: Default::default(), web_fetch_views: Default::default(), + summarization_views: Default::default(), requested_commands_to_auto_collapse: Default::default(), review_changes_button, open_all_comments_button, @@ -1801,6 +1806,9 @@ impl AIBlock { self.handle_web_fetch_messages(&output.messages, ctx); } + self.handle_summarization_messages(&output.messages, ctx); + self.maybe_create_summarization_view_from_input(ctx); + for action in output.actions() { let new_action_ids: HashSet = output.actions().map(|action| action.id.clone()).collect(); @@ -3489,6 +3497,84 @@ impl AIBlock { } } + fn handle_summarization_messages( + &mut self, + messages: &[AIAgentOutputMessage], + ctx: &mut ViewContext, + ) { + use crate::ai::agent::SummarizationType; + + for message in messages { + let AIAgentOutputMessageType::Summarization { + finished_duration, + summarization_type, + .. + } = &message.message + else { + continue; + }; + + if !matches!(summarization_type, SummarizationType::ConversationSummary) { + continue; + } + + if let Some(view) = self.summarization_views.get(&message.id) { + if finished_duration.is_some() { + view.update(ctx, |view, ctx| { + view.mark_finished(); + ctx.notify(); + }); + } + } else { + let is_finished = finished_duration.is_some(); + let view = ctx.add_view(|ctx| { + let mut v = SummarizationView::new(ctx); + if is_finished { + v.mark_finished(); + } + v + }); + self.summarization_views.insert(message.id.clone(), view); + ctx.notify(); + } + } + } + + /// Creates a SummarizationView when the exchange input is a SummarizeConversation. + /// This handles the Bedrock path where no Summarization output message is emitted. + fn maybe_create_summarization_view_from_input(&mut self, ctx: &mut ViewContext) { + let is_summarize_input = self + .model + .inputs_to_render(ctx) + .iter() + .any(|i| matches!(i, AIAgentInput::SummarizeConversation { .. })); + + if !is_summarize_input { + return; + } + + let key = MessageId::new("__summarization_inline_view__".to_string()); + if self.summarization_views.contains_key(&key) { + // Already created — check if we should mark it finished + let is_complete = !self.model.status(ctx).is_streaming(); + if is_complete { + if let Some(view) = self.summarization_views.get(&key) { + view.update(ctx, |view, ctx| { + if !view.is_finished { + view.mark_finished(); + ctx.notify(); + } + }); + } + } + return; + } + + let view = ctx.add_view(|ctx| SummarizationView::new(ctx)); + self.summarization_views.insert(key, view); + ctx.notify(); + } + /// Note this is called when the search codebase tool call definition finishes streaming, not when the search actually completes. fn handle_search_codebase_complete( &mut self, diff --git a/app/src/ai/blocklist/block/view_impl.rs b/app/src/ai/blocklist/block/view_impl.rs index 713954f7..863e808d 100644 --- a/app/src/ai/blocklist/block/view_impl.rs +++ b/app/src/ai/blocklist/block/view_impl.rs @@ -86,7 +86,7 @@ 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}; use galaxyui::elements::{Highlight, HighlightedRange, Text}; use galaxyui::fonts::Properties; use galaxyui::platform::Cursor; @@ -433,7 +433,7 @@ pub(crate) fn add_highlights_to_rich_text( find_context: Option>, location_index: usize, line_count: usize, - theme: &WarpTheme, + theme: &GalaxyTheme, is_selecting: bool, is_action: bool, app: &AppContext, @@ -1080,6 +1080,7 @@ impl View for AIBlock { search_codebase_view: &self.search_codebase_view, web_search_views: &self.web_search_views, web_fetch_views: &self.web_fetch_views, + summarization_views: &self.summarization_views, review_changes_button: &self.review_changes_button, open_all_comments_button: &self.open_all_comments_button, dismiss_suggestion_button: &self.dismiss_suggestion_button, diff --git a/app/src/ai/blocklist/block/view_impl/output.rs b/app/src/ai/blocklist/block/view_impl/output.rs index 04053828..b7976097 100644 --- a/app/src/ai/blocklist/block/view_impl/output.rs +++ b/app/src/ai/blocklist/block/view_impl/output.rs @@ -88,6 +88,7 @@ use crate::{ }, requested_command::RequestedCommand, search_codebase::SearchCodebaseView, + summarization::SummarizationView, suggested_unit_tests::SuggestedUnitTestsView, web_fetch::WebFetchView, web_search::WebSearchView, @@ -177,6 +178,7 @@ pub(crate) struct Props<'a> { pub(super) search_codebase_view: &'a HashMap>, pub(super) web_search_views: &'a HashMap>, pub(super) web_fetch_views: &'a HashMap>, + pub(super) summarization_views: &'a HashMap>, pub(super) review_changes_button: &'a ViewHandle, pub(super) open_all_comments_button: &'a ViewHandle, pub(super) dismiss_suggestion_button: &'a ViewHandle, @@ -210,6 +212,23 @@ pub(super) fn render(props: Props, app: &AppContext) -> Box { let conversation_status = props.model.conversation(app).map(|c| c.status()); let is_conversation_in_progress = conversation_status.is_some_and(|s| s.is_in_progress()); + // If this is a summarization request, render the inline SummarizationView at the top + // regardless of output status. This handles the Bedrock path where no Summarization + // output message type is emitted. + let is_summarize_input = props + .model + .inputs_to_render(app) + .iter() + .any(|i| matches!(i, AIAgentInput::SummarizeConversation { .. })); + if is_summarize_input { + let key = crate::ai::agent::MessageId::new( + "__summarization_inline_view__".to_string(), + ); + if let Some(summarization_view) = props.summarization_views.get(&key) { + output_items.add_child(ChildView::new(summarization_view).finish()); + } + } + let status = props.model.status(app); match status { // Ignore errors if the response is not yet complete-- it could be a deserialization @@ -807,21 +826,28 @@ pub(super) fn render(props: Props, app: &AppContext) -> Box { } if matches!( summarization_type, SummarizationType::ConversationSummary - ) && !are_all_text_sections_empty(&text.sections) => + ) => { - let header_text = "Conversation summarized".to_string(); - if let Some(element) = render_collapsible_block( - output_message, - header_text, - &text.sections, - finished_duration.is_some(), - props, - &mut has_rendered_first_text_section, - &mut text_section_index, - &mut code_section_index, - app, - ) { - output_items.add_child(element); + if let Some(summarization_view) = + props.summarization_views.get(&output_message.id) + { + output_items + .add_child(ChildView::new(summarization_view).finish()); + } else if !are_all_text_sections_empty(&text.sections) { + let header_text = "Conversation summarized".to_string(); + if let Some(element) = render_collapsible_block( + output_message, + header_text, + &text.sections, + finished_duration.is_some(), + props, + &mut has_rendered_first_text_section, + &mut text_section_index, + &mut code_section_index, + app, + ) { + output_items.add_child(element); + } } } AIAgentOutputMessageType::WebSearch(web_search_status) => { @@ -3210,19 +3236,18 @@ fn render_usage_button(props: Props, app: &AppContext) -> Box { }; let context_usage = conversation.context_window_usage(); - let total_input = conversation.total_input_tokens(); + let current_context = conversation.current_context_tokens(); let cache_read = conversation.total_cache_read_tokens(); let cache_write = conversation.total_cache_write_tokens(); - let cache_miss = conversation.cache_miss_tokens(); let cost_cents = conversation.total_cost_cents(); let max_context: u32 = if context_usage > 0.0 { - (total_input as f32 / context_usage).round() as u32 + (current_context as f32 / context_usage).round() as u32 } else { 200_000 }; let context_pct = context_usage * 100.0; - let cache_total = cache_read + cache_write + cache_miss; + let cache_total = cache_read + cache_write; let cache_hit_pct = if cache_total > 0 { (cache_read as f64 / cache_total as f64) * 100.0 } else { @@ -3230,14 +3255,13 @@ fn render_usage_button(props: Props, app: &AppContext) -> Box { }; let usage_text = format!( - "Context: {:.1}% ({} / {}) | Cache: {:.1}% (R: {}, W: {}, M: {}) | Cost: ${:.2}", + "Context: {:.1}% ({} / {}) | Cache: {:.1}% (R: {}, W: {}) | Cost: ${:.2}", context_pct, - format_token_count(total_input), + format_token_count(current_context), format_token_count(max_context), cache_hit_pct, format_token_count(cache_read), format_token_count(cache_write), - format_token_count(cache_miss), cost_cents / 100.0, ); diff --git a/app/src/ai/blocklist/code_block.rs b/app/src/ai/blocklist/code_block.rs index 9171b248..fcebbd62 100644 --- a/app/src/ai/blocklist/code_block.rs +++ b/app/src/ai/blocklist/code_block.rs @@ -254,7 +254,7 @@ fn render_linked_code_block_internal( let open_button = render_button( appearance, Icon::LinkExternal, - "Open in Warp", + "Open in Galaxy", mouse_handles.open_button, code_clone.clone(), on_open, diff --git a/app/src/ai/blocklist/controller.rs b/app/src/ai/blocklist/controller.rs index 3200b227..153a6f5f 100644 --- a/app/src/ai/blocklist/controller.rs +++ b/app/src/ai/blocklist/controller.rs @@ -1995,6 +1995,9 @@ impl BlocklistAIController { request_params.parent_agent_id = parent_agent_id; request_params.agent_name = agent_name; request_params.bedrock_message_history = bedrock_history; + request_params.is_summarization = request_input + .all_inputs() + .any(|input| matches!(input, AIAgentInput::SummarizeConversation { .. })); let server_conversation_token_for_identifiers = conversation_data.server_conversation_token.clone(); @@ -2020,9 +2023,13 @@ impl BlocklistAIController { let input_contains_user_query = request_input .all_inputs() .any(|input| input.is_user_query()); + let input_is_summarization = request_input + .all_inputs() + .any(|input| matches!(input, AIAgentInput::SummarizeConversation { .. })); ctx.subscribe_to_model(&response_stream, move |me, event, ctx| { me.handle_response_stream_event( input_contains_user_query, + input_is_summarization, event, &response_stream_clone, ctx, @@ -2212,6 +2219,7 @@ impl BlocklistAIController { fn handle_response_stream_event( &mut self, did_input_contain_user_query: bool, + is_summarization_request: bool, event: &ResponseStreamEvent, response_stream: &ModelHandle, ctx: &mut ModelContext, @@ -2319,11 +2327,88 @@ impl BlocklistAIController { let history_model = BlocklistAIHistoryModel::handle(ctx); history_model.update(ctx, |history_model, _| { if let Some(conversation) = history_model.conversation_mut(&conversation_id) { - *conversation.bedrock_message_history_mut() = new_history; - log::info!( - "[bedrock] Updated conversation bedrock history: {} messages", - conversation.bedrock_message_history().len() - ); + // If this was a summarization request, compact the + // history to just the summary instead of keeping + // the full message list. This is what actually + // frees up context window space. + let is_summarization = is_summarization_request; + + if is_summarization { + // Extract the assistant's summary from the last + // message in the history (the response). + let summary_text = new_history + .iter() + .rev() + .find_map(|msg| { + use crate::ai::bedrock::convert::{ + MessageContent, MessageRole, + }; + if msg.role == MessageRole::Assistant { + if let MessageContent::Text(text) = + &msg.content + { + Some(text.clone()) + } else { + None + } + } else { + None + } + }); + + if let Some(summary) = summary_text { + use crate::ai::bedrock::convert::{ + ConversationMessage, MessageContent, + MessageRole, + }; + let assistant_reply = "Understood. I have the context from our previous conversation. How can I help you next?"; + let user_msg = format!( + "Here is a summary of our conversation so far:\n\n{summary}" + ); + let compacted = vec![ + ConversationMessage { + role: MessageRole::User, + content: MessageContent::Text(user_msg.clone()), + }, + ConversationMessage { + role: MessageRole::Assistant, + content: MessageContent::Text( + assistant_reply.to_string() + ), + }, + ]; + log::info!( + "[bedrock] Compacted conversation history from {} messages to {} (summary)", + new_history.len(), + compacted.len() + ); + *conversation.bedrock_message_history_mut() = + compacted; + + // Estimate new context size from the compacted content. + // ~4 chars per token is a reasonable approximation. + let estimated_tokens = ((user_msg.len() + assistant_reply.len()) / 4) as u32; + let max_context = crate::ai::bedrock::response_translator::context_window_for_model("claude-opus-4-6-20250514[1m]"); + let new_usage = estimated_tokens as f32 / max_context as f32; + conversation.set_context_window_usage(new_usage); + conversation.set_current_context_tokens(estimated_tokens); + log::info!( + "[bedrock] Post-compact context estimate: ~{} tokens ({:.1}% of context window)", + estimated_tokens, + new_usage * 100.0 + ); + } else { + *conversation.bedrock_message_history_mut() = + new_history; + } + } else { + *conversation.bedrock_message_history_mut() = + new_history; + log::info!( + "[bedrock] Updated conversation bedrock history: {} messages", + conversation.bedrock_message_history().len() + ); + } } }); } @@ -2800,6 +2885,42 @@ impl BlocklistAIController { }); ctx.emit(BlocklistAIControllerEvent::FreeTierLimitCheckTriggered); } + + // Auto-compact: trigger summarization when context window usage >= 85%. + let should_auto_compact = { + let history_model = BlocklistAIHistoryModel::as_ref(ctx); + history_model + .conversation(&conversation_id) + .is_some_and(|conversation| { + let is_summarization_request = conversation + .latest_exchange() + .is_some_and(|exchange| { + exchange + .input + .iter() + .any(|i| matches!(i, AIAgentInput::SummarizeConversation { .. })) + }); + conversation.context_window_usage() >= 0.85 + && !conversation.has_pending_auto_compact() + && !is_summarization_request + }) + }; + + if should_auto_compact { + log::info!( + "[auto-compact] Context window usage >= 85% for conversation {:?}, triggering summarization", + conversation_id + ); + BlocklistAIHistoryModel::handle(ctx).update(ctx, |history_model, _| { + if let Some(conversation) = history_model.conversation_mut(&conversation_id) { + conversation.set_has_pending_auto_compact(true); + } + }); + self.send_slash_command_request( + SlashCommandRequest::Summarize { prompt: None }, + ctx, + ); + } } } 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 5dfc61e9..f1bdd124 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,7 +4,7 @@ use ai::agent::{ action::{AskUserQuestionItem, AskUserQuestionOption, AskUserQuestionType}, action_result::{AskUserQuestionAnswerItem, AskUserQuestionResult}, }; -use galaxy_core::ui::theme::{color::internal_colors, WarpTheme}; +use galaxy_core::ui::theme::{color::internal_colors, GalaxyTheme}; use galaxyui::{ elements::{ new_scrollable::SingleAxisConfig, Border, ChildView, Clipped, ClippedScrollStateHandle, @@ -1333,7 +1333,7 @@ impl AskUserQuestionView { fn render_question_text( question_text: &str, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let text_color = theme.foreground().into(); Container::new(render_text_with_markdown_support( @@ -1357,7 +1357,7 @@ impl AskUserQuestionView { &self, question_text: &str, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let body = Flex::column() .with_cross_axis_alignment(CrossAxisAlignment::Stretch) @@ -1385,7 +1385,7 @@ impl AskUserQuestionView { fn render_nav_footer( &self, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> Box { let counter = format!( diff --git a/app/src/ai/blocklist/inline_action/mod.rs b/app/src/ai/blocklist/inline_action/mod.rs index 592e7ba0..b4311a18 100644 --- a/app/src/ai/blocklist/inline_action/mod.rs +++ b/app/src/ai/blocklist/inline_action/mod.rs @@ -11,6 +11,7 @@ pub(crate) mod requested_command_attribution; pub(crate) mod requested_script; pub(super) mod search_codebase; pub(crate) mod search_results_common; +pub(super) mod summarization; pub(crate) mod suggested_unit_tests; pub(super) mod web_fetch; pub(super) mod web_search; diff --git a/app/src/ai/blocklist/inline_action/summarization.rs b/app/src/ai/blocklist/inline_action/summarization.rs new file mode 100644 index 00000000..84536640 --- /dev/null +++ b/app/src/ai/blocklist/inline_action/summarization.rs @@ -0,0 +1,197 @@ +use galaxy_core::ui::appearance::Appearance; +use galaxyui::elements::shimmering_text::{ShimmerConfig, ShimmeringTextElement, ShimmeringTextStateHandle}; +use galaxyui::elements::{ + ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element, Flex, + MainAxisAlignment, ParentElement, Radius, Shrinkable, Text, +}; +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, +}; +use super::inline_action_icons::icon_size; +use crate::ai::blocklist::block::view_impl::WithContentItemSpacing; +use crate::ui_components::icons::Icon; + +pub enum SummarizationViewEvent {} + +pub struct SummarizationView { + pub is_finished: bool, + shimmering_text_handle: ShimmeringTextStateHandle, + start_time: Instant, + timer_handle: Option, +} + +impl SummarizationView { + pub fn new(ctx: &mut ViewContext) -> Self { + let mut view = Self { + is_finished: false, + shimmering_text_handle: ShimmeringTextStateHandle::default(), + start_time: Instant::now(), + timer_handle: None, + }; + view.start_timer(ctx); + view + } + + pub fn mark_finished(&mut self) { + self.is_finished = true; + if let Some(handle) = self.timer_handle.take() { + handle.abort(); + } + } + + fn start_timer(&mut self, ctx: &mut ViewContext) { + if self.timer_handle.is_some() { + return; + } + let handle = ctx.spawn( + async move { + Timer::after(Duration::from_secs(1)).await; + }, + |me, _unit, ctx| { + me.timer_handle = None; + if !me.is_finished { + ctx.notify(); + me.start_timer(ctx); + } + }, + ); + self.timer_handle = Some(handle); + } + + fn render_in_progress(&self, app: &AppContext) -> Box { + let appearance = Appearance::as_ref(app); + let theme = appearance.theme(); + let header_background = theme.surface_2(); + + let mut header_row = Flex::row() + .with_main_axis_alignment(MainAxisAlignment::Start) + .with_cross_axis_alignment(CrossAxisAlignment::Center); + + // Clock loader icon (magenta, matches InProgress convention) + let icon_element = galaxyui::elements::Icon::new( + Icon::ClockLoader.into(), + theme.ansi_fg_magenta(), + ) + .finish(); + let icon_box = ConstrainedBox::new(icon_element) + .with_width(icon_size(app)) + .with_height(icon_size(app)) + .finish(); + header_row.add_child( + Container::new(icon_box) + .with_margin_right(8.) + .finish(), + ); + + // Shimmering "Summarizing conversation..." text + let base_color = theme.disabled_text_color(header_background).into_solid(); + let shimmer_color = theme.main_text_color(header_background).into_solid(); + let shimmer_element = ShimmeringTextElement::new( + "Summarizing conversation...".to_string(), + appearance.ui_font_family(), + appearance.monospace_font_size(), + base_color, + shimmer_color, + ShimmerConfig::default(), + self.shimmering_text_handle.clone(), + ) + .finish(); + header_row.add_child(Shrinkable::new(1.0, shimmer_element).finish()); + + // Elapsed time suffix + let elapsed = self.start_time.elapsed(); + let elapsed_text = format_elapsed(elapsed); + let suffix = Text::new_inline( + format!(" \u{2022} {elapsed_text}"), + appearance.ui_font_family(), + appearance.monospace_font_size(), + ) + .with_color(theme.disabled_text_color(header_background).into()) + .finish(); + header_row.add_child(suffix); + + Container::new(header_row.finish()) + .with_horizontal_padding(INLINE_ACTION_HORIZONTAL_PADDING) + .with_vertical_padding(INLINE_ACTION_HEADER_VERTICAL_PADDING) + .with_background(header_background) + .with_corner_radius(CornerRadius::with_all(Radius::Pixels(8.))) + .finish() + } + + fn render_finished(&self, app: &AppContext) -> Box { + let appearance = Appearance::as_ref(app); + let theme = appearance.theme(); + let header_background = theme.surface_2(); + + let mut header_row = Flex::row() + .with_main_axis_alignment(MainAxisAlignment::Start) + .with_cross_axis_alignment(CrossAxisAlignment::Center); + + // Checkmark-style icon for completed + let icon_element = galaxyui::elements::Icon::new( + Icon::Check.into(), + theme.ansi_fg_green(), + ) + .finish(); + let icon_box = ConstrainedBox::new(icon_element) + .with_width(icon_size(app)) + .with_height(icon_size(app)) + .finish(); + header_row.add_child( + Container::new(icon_box) + .with_margin_right(8.) + .finish(), + ); + + let elapsed = self.start_time.elapsed(); + let elapsed_text = format_elapsed(elapsed); + let title = Text::new_inline( + format!("Conversation summarized \u{2022} {elapsed_text}"), + appearance.ui_font_family(), + appearance.monospace_font_size(), + ) + .with_color(theme.main_text_color(header_background).into()) + .finish(); + header_row.add_child(Shrinkable::new(1.0, title).finish()); + + Container::new(header_row.finish()) + .with_horizontal_padding(INLINE_ACTION_HORIZONTAL_PADDING) + .with_vertical_padding(INLINE_ACTION_HEADER_VERTICAL_PADDING) + .with_background(header_background) + .with_corner_radius(CornerRadius::with_all(Radius::Pixels(8.))) + .finish() + } +} + +impl Entity for SummarizationView { + type Event = SummarizationViewEvent; +} + +impl View for SummarizationView { + fn ui_name() -> &'static str { + "SummarizationView" + } + + fn render(&self, app: &AppContext) -> Box { + let element = if self.is_finished { + self.render_finished(app) + } else { + self.render_in_progress(app) + }; + element.with_agent_output_item_spacing(app).finish() + } +} + +fn format_elapsed(duration: Duration) -> String { + let secs = duration.as_secs(); + if secs < 60 { + format!("{secs}s") + } else { + format!("{}m {}s", secs / 60, secs % 60) + } +} diff --git a/app/src/ai/blocklist/orchestration_events.rs b/app/src/ai/blocklist/orchestration_events.rs index 8c44ec4f..27ec5acc 100644 --- a/app/src/ai/blocklist/orchestration_events.rs +++ b/app/src/ai/blocklist/orchestration_events.rs @@ -19,6 +19,8 @@ use warp_multi_agent_api as api; const MAX_RETRY_ATTEMPTS: i32 = 3; const MAX_PENDING_LIFECYCLE_EVENTS_PER_TARGET: usize = 200; +pub const MAX_SUBAGENT_RETRIES: u8 = 3; +const MAX_SUBAGENT_QUESTION_DEPTH: u8 = 3; /// Stage associated with a lifecycle error detail. /// This keeps persisted/runtime metadata consistent across API payloads and DB rows. @@ -64,6 +66,23 @@ pub enum PendingEventDetail { Lifecycle { event: api::AgentEvent, }, + /// A subagent is asking its parent a question (routed from AskUserQuestion). + SubagentQuestion { + source_conversation_id: AIConversationId, + question_text: String, + options: Vec, + depth: u8, + }, + /// The parent's answer to a subagent's question. + SubagentAnswer { + target_conversation_id: AIConversationId, + answer_text: String, + }, + /// A subagent reporting its completion summary to the parent. + SubagentCompletionSummary { + source_conversation_id: AIConversationId, + summary_text: String, + }, } /// A queued event consumed by the controller. @@ -930,29 +949,49 @@ impl OrchestrationEventService { let mut messages = Vec::new(); let mut lifecycle_events = Vec::new(); - for event in &deliverable { + let mut server_bound_events = Vec::new(); + for event in deliverable { match &event.detail { PendingEventDetail::Message { message_id, addresses, subject, message_body, - } => messages.push(ReceivedMessageInput { - message_id: message_id.clone(), - sender_agent_id: event.source_agent_id.clone(), - addresses: addresses.clone(), - subject: subject.clone(), - message_body: message_body.clone(), - }), - PendingEventDetail::Lifecycle { event } => lifecycle_events.push(event.clone()), + } => { + messages.push(ReceivedMessageInput { + message_id: message_id.clone(), + sender_agent_id: event.source_agent_id.clone(), + addresses: addresses.clone(), + subject: subject.clone(), + message_body: message_body.clone(), + }); + server_bound_events.push(event); + } + PendingEventDetail::Lifecycle { event: _ } => { + lifecycle_events.push( + if let PendingEventDetail::Lifecycle { event: e } = &event.detail { + e.clone() + } else { + unreachable!() + }, + ); + server_bound_events.push(event); + } + // Local-only subagent events are consumed directly by the controller, + // not converted to AIAgentInput or awaited for server echo. + PendingEventDetail::SubagentQuestion { .. } + | PendingEventDetail::SubagentAnswer { .. } + | PendingEventDetail::SubagentCompletionSummary { .. } => {} } } - // Move to awaiting echo for delivery confirmation. - self.awaiting_server_echo_events - .entry(conversation_id) - .or_default() - .extend(deliverable); + // Only server-bound events need echo confirmation. + if !server_bound_events.is_empty() { + self.awaiting_server_echo_events + .entry(conversation_id) + .or_default() + .extend(server_bound_events); + } let mut inputs = Vec::new(); if !messages.is_empty() { @@ -966,6 +1005,34 @@ impl OrchestrationEventService { inputs } + /// Drain only the local subagent events (Question/Answer/Summary) for a conversation. + /// These are not sent to the server and are consumed directly by the controller. + pub fn drain_subagent_events( + &mut self, + conversation_id: &AIConversationId, + ) -> Vec { + let Some(pending) = self.pending_events.get_mut(conversation_id) else { + return vec![]; + }; + + let mut subagent_events = Vec::new(); + pending.retain(|event| match &event.detail { + PendingEventDetail::SubagentQuestion { .. } + | PendingEventDetail::SubagentAnswer { .. } + | PendingEventDetail::SubagentCompletionSummary { .. } => { + subagent_events.push(event.clone()); + false + } + _ => true, + }); + + if pending.is_empty() { + self.pending_events.remove(conversation_id); + } + + subagent_events + } + /// Moves all awaiting events back to pending for retry after a failed /// send attempt. Increments attempt counts and drops events that have /// exhausted their retry limit. @@ -1109,6 +1176,101 @@ impl OrchestrationEventService { self.awaiting_server_echo_events.remove(&conversation_id); } } + + /// Route a subagent's AskUserQuestion to the parent conversation for silent auto-answer. + pub fn route_subagent_question_to_parent( + &mut self, + child_conversation_id: AIConversationId, + parent_conversation_id: AIConversationId, + question_text: String, + options: Vec, + depth: u8, + ctx: &mut ModelContext, + ) { + if depth >= MAX_SUBAGENT_QUESTION_DEPTH { + log::warn!( + "Subagent question depth limit reached for conversation {:?}", + child_conversation_id + ); + return; + } + + let event = PendingEvent { + event_id: Uuid::new_v4().to_string(), + source_agent_id: child_conversation_id.to_string(), + attempt_count: 0, + detail: PendingEventDetail::SubagentQuestion { + source_conversation_id: child_conversation_id, + question_text, + options, + depth, + }, + }; + + self.pending_events + .entry(parent_conversation_id) + .or_default() + .push(event); + + ctx.emit(OrchestrationEventServiceEvent::EventsReady { + conversation_id: parent_conversation_id, + }); + } + + /// Route the parent's answer back to the child subagent. + pub fn route_answer_to_subagent( + &mut self, + child_conversation_id: AIConversationId, + answer_text: String, + ctx: &mut ModelContext, + ) { + let event = PendingEvent { + event_id: Uuid::new_v4().to_string(), + source_agent_id: "parent".to_string(), + attempt_count: 0, + detail: PendingEventDetail::SubagentAnswer { + target_conversation_id: child_conversation_id, + answer_text, + }, + }; + + self.pending_events + .entry(child_conversation_id) + .or_default() + .push(event); + + ctx.emit(OrchestrationEventServiceEvent::EventsReady { + conversation_id: child_conversation_id, + }); + } + + /// Route a subagent's completion summary to the parent conversation. + pub fn route_subagent_completion_summary( + &mut self, + child_conversation_id: AIConversationId, + parent_conversation_id: AIConversationId, + summary_text: String, + ctx: &mut ModelContext, + ) { + let event = PendingEvent { + event_id: Uuid::new_v4().to_string(), + source_agent_id: child_conversation_id.to_string(), + attempt_count: 0, + detail: PendingEventDetail::SubagentCompletionSummary { + source_conversation_id: child_conversation_id, + summary_text, + }, + }; + + self.pending_events + .entry(parent_conversation_id) + .or_default() + .push(event); + + ctx.emit(OrchestrationEventServiceEvent::EventsReady { + conversation_id: parent_conversation_id, + }); + } } /// `None` means \"subscribe to all lifecycle types\" (input omitted). @@ -1135,6 +1297,10 @@ fn did_event_round_trip_through_server( PendingEventDetail::Lifecycle { event } => { echoed_lifecycle_event_ids.contains(event.event_id.as_str()) } + // Local-only events never round-trip through the server. + PendingEventDetail::SubagentQuestion { .. } + | PendingEventDetail::SubagentAnswer { .. } + | PendingEventDetail::SubagentCompletionSummary { .. } => false, } } diff --git a/app/src/ai/blocklist/usage/conversation_usage_view.rs b/app/src/ai/blocklist/usage/conversation_usage_view.rs index 202a11b3..1cb76b58 100644 --- a/app/src/ai/blocklist/usage/conversation_usage_view.rs +++ b/app/src/ai/blocklist/usage/conversation_usage_view.rs @@ -33,11 +33,14 @@ pub struct ConversationUsageInfo { pub lines_added: i32, pub lines_removed: i32, pub commands_executed: i32, - pub total_input_tokens: u32, - pub total_output_tokens: u32, - pub total_cache_read_tokens: u32, - pub total_cache_write_tokens: u32, + /// Live context window token count (from most recent Bedrock response). + pub current_context_tokens: u32, + /// Cumulative cost across all requests. pub estimated_cost_cents: f32, + /// Cumulative cache read tokens (session total). + pub total_cache_read_tokens: u32, + /// Cumulative cache write tokens (session total). + pub total_cache_write_tokens: u32, } /// Timing information for the last set of agent responses @@ -246,32 +249,21 @@ impl ConversationUsageView { ); } - // Token usage section - let total_tokens = self.usage_info.total_input_tokens - + self.usage_info.total_output_tokens - + self.usage_info.total_cache_read_tokens + // Context tokens (live state — current context window size) + if self.usage_info.current_context_tokens > 0 { + labels.push(render_label_text("Context tokens", appearance)); + values.push(render_value_text( + format_token_count(self.usage_info.current_context_tokens), + appearance, + )); + } + + // Cache usage (cumulative session totals) + let total_cache = self.usage_info.total_cache_read_tokens + self.usage_info.total_cache_write_tokens; - if total_tokens > 0 { - labels.push(render_label_text("Total tokens", appearance)); - values.push(render_value_text( - format_token_count(total_tokens), - appearance, - )); - - labels.push(render_label_text(" Input", appearance)); - values.push(render_value_text( - format_token_count(self.usage_info.total_input_tokens), - appearance, - )); - - labels.push(render_label_text(" Output", appearance)); - values.push(render_value_text( - format_token_count(self.usage_info.total_output_tokens), - appearance, - )); - + if total_cache > 0 { if self.usage_info.total_cache_read_tokens > 0 { - labels.push(render_label_text(" Cache read", appearance)); + labels.push(render_label_text("Cache read", appearance)); values.push(render_value_text( format_token_count(self.usage_info.total_cache_read_tokens), appearance, @@ -279,12 +271,25 @@ impl ConversationUsageView { } if self.usage_info.total_cache_write_tokens > 0 { - labels.push(render_label_text(" Cache write", appearance)); + labels.push(render_label_text("Cache write", appearance)); values.push(render_value_text( format_token_count(self.usage_info.total_cache_write_tokens), appearance, )); } + + // Cache hit rate + let cache_miss = self.usage_info.current_context_tokens + .saturating_sub(self.usage_info.total_cache_read_tokens); + let total_input = self.usage_info.total_cache_read_tokens + cache_miss; + if total_input > 0 { + let hit_rate = (self.usage_info.total_cache_read_tokens as f32 / total_input as f32) * 100.0; + labels.push(render_label_text("Cache hit rate", appearance)); + values.push(render_value_text( + format!("{:.0}%", hit_rate), + appearance, + )); + } } labels.push(render_label_text("Context window used", appearance)); diff --git a/app/src/ai/blocklist/usage/mod.rs b/app/src/ai/blocklist/usage/mod.rs index b668dcba..fc39479c 100644 --- a/app/src/ai/blocklist/usage/mod.rs +++ b/app/src/ai/blocklist/usage/mod.rs @@ -1,4 +1,4 @@ -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxy_core::ui::Icon; use galaxyui::Element; @@ -33,7 +33,7 @@ pub fn icon_for_context_window_usage(context_window_usage: f32) -> Icon { pub fn render_context_window_usage_icon( context_window_usage: f32, - theme: &WarpTheme, + theme: &GalaxyTheme, color_override: Option, ) -> Box { let icon = icon_for_context_window_usage(context_window_usage); diff --git a/app/src/ai/blocklist/view_util.rs b/app/src/ai/blocklist/view_util.rs index 64984541..47450ab7 100644 --- a/app/src/ai/blocklist/view_util.rs +++ b/app/src/ai/blocklist/view_util.rs @@ -19,7 +19,7 @@ use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; use crate::{ - themes::theme::{AnsiColorIdentifier, Fill, WarpTheme}, + themes::theme::{AnsiColorIdentifier, Fill, GalaxyTheme}, ui_components::icons::Icon, }; @@ -52,7 +52,7 @@ pub const CLAUDE_ORANGE: ColorU = ColorU { /// Returns the color to be used for various AI signifiers /// input with AI mode). -pub fn ai_brand_color(theme: &WarpTheme) -> ColorU { +pub fn ai_brand_color(theme: &GalaxyTheme) -> ColorU { AnsiColorIdentifier::Magenta .to_ansi_color(&theme.terminal_colors().normal) .into() @@ -60,7 +60,7 @@ pub fn ai_brand_color(theme: &WarpTheme) -> ColorU { /// Returns the color to be used for error UI throughout Agent Mode (like the "request limit /// exceeded" chip). -pub fn error_color(theme: &WarpTheme) -> ColorU { +pub fn error_color(theme: &GalaxyTheme) -> ColorU { AnsiColorIdentifier::Red .to_ansi_color(&theme.terminal_colors().normal) .into() diff --git a/app/src/ai/conversation_status_ui.rs b/app/src/ai/conversation_status_ui.rs index 71076b6d..32687a26 100644 --- a/app/src/ai/conversation_status_ui.rs +++ b/app/src/ai/conversation_status_ui.rs @@ -1,6 +1,6 @@ use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::coloru_with_opacity; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::color::ColorU; use galaxyui::elements::{ConstrainedBox, Container, CornerRadius, Radius}; use galaxyui::Element; @@ -13,17 +13,17 @@ use crate::ui_components::icons::Icon; pub const STATUS_ELEMENT_PADDING: f32 = 2.; pub trait StatusElementStyle { - fn status_icon_and_color(&self, theme: &WarpTheme) -> (Icon, ColorU); + fn status_icon_and_color(&self, theme: &GalaxyTheme) -> (Icon, ColorU); } 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) } } impl StatusElementStyle for AgentRunDisplayStatus { - fn status_icon_and_color(&self, theme: &WarpTheme) -> (Icon, ColorU) { + fn status_icon_and_color(&self, theme: &GalaxyTheme) -> (Icon, ColorU) { AgentRunDisplayStatus::status_icon_and_color(self, theme) } } diff --git a/app/src/ai/execution_profiles/editor/ui_helpers.rs b/app/src/ai/execution_profiles/editor/ui_helpers.rs index 23f0250d..a6fd5700 100644 --- a/app/src/ai/execution_profiles/editor/ui_helpers.rs +++ b/app/src/ai/execution_profiles/editor/ui_helpers.rs @@ -664,7 +664,7 @@ pub fn render_plan_auto_sync_toggle( .finish(); let desc_elem = Text::new( - "The plans this agent creates will be automatically added and synced to Warp Drive." + "The plans this agent creates will be automatically added and synced to Galaxy Drive." .to_string(), appearance.ui_font_family(), 11., diff --git a/app/src/ai/facts/predefined_rules.rs b/app/src/ai/facts/predefined_rules.rs index bdc0883e..36ddcaf9 100644 --- a/app/src/ai/facts/predefined_rules.rs +++ b/app/src/ai/facts/predefined_rules.rs @@ -5,49 +5,58 @@ pub struct PredefinedRule { pub const SYSTEM_DEFINED_RULE_PREFIX: &str = "System Defined Rule"; +pub fn is_predefined_rule(name: &str) -> bool { + PREDEFINED_RULES.iter().any(|r| r.name == name) + || name.starts_with(SYSTEM_DEFINED_RULE_PREFIX) +} + +pub fn predefined_rule_index(name: &str) -> Option { + PREDEFINED_RULES.iter().position(|r| r.name == name) +} + pub const PREDEFINED_RULES: &[PredefinedRule] = &[ PredefinedRule { - name: "System Defined Rule #1", + name: "Correctness Over Speed", content: "Prioritize correctness, completeness, and reliability over speed.", }, PredefinedRule { - name: "System Defined Rule #2", + name: "Never Guess", content: "Never guess. If uncertain, explicitly say so and verify before finalizing.", }, PredefinedRule { - name: "System Defined Rule #3", + name: "Evidence-Based Claims", content: "Ground non-trivial claims in evidence (repo files, command output, tests, official documentation).", }, PredefinedRule { - name: "System Defined Rule #4", + name: "Verify When Uncertain", content: "If confidence is not high, or if a claim depends on external/current behavior, perform web verification before answering; prioritize official docs and cross-check with at least one additional reliable source.", }, PredefinedRule { - name: "System Defined Rule #5", + name: "Separate Facts From Assumptions", content: "Clearly separate facts, assumptions, and hypotheses.", }, PredefinedRule { - name: "System Defined Rule #6", + name: "Ask When Ambiguous", content: "Ask clarifying questions when ambiguity could change the solution or implementation.", }, PredefinedRule { - name: "System Defined Rule #7", + name: "Validate Code Changes", content: "For code changes, run relevant validations when available (tests, lint, typecheck, build) and report what was run, what passed/failed, and what was not run.", }, PredefinedRule { - name: "System Defined Rule #8", + name: "Disclose Unvalidated Risks", content: "If validation cannot be run, state that explicitly and describe residual risk and recommended manual checks.", }, PredefinedRule { - name: "System Defined Rule #9", + name: "Admit Unknowns", content: "Prefer \"I don't know yet\" over plausible speculation.", }, PredefinedRule { - name: "System Defined Rule #10", + name: "Challenge Bad Ideas", content: "If the user's idea is wrong, incomplete, risky, or non-optimal, say so directly and respectfully; explain why it may fail and provide a better alternative that still achieves the user's goal.", }, PredefinedRule { - name: "System Defined Rule #11", + name: "Surface Disagreement", content: "Do not hide uncertainty, and do not avoid technical disagreement when correctness is at stake.", }, ]; diff --git a/app/src/ai/facts/view/mod.rs b/app/src/ai/facts/view/mod.rs index fb8d29dc..b4dd3625 100644 --- a/app/src/ai/facts/view/mod.rs +++ b/app/src/ai/facts/view/mod.rs @@ -1,7 +1,4 @@ -use crate::cloud_object::{ - CloudObject, CloudObjectSyncStatus, GenericStringObjectFormat, JsonObjectType, -}; -use crate::drive::CloudObjectTypeAndId; +use crate::cloud_object::{CloudObject, CloudObjectSyncStatus}; use crate::network::NetworkStatus; use crate::pane_group::focus_state::PaneFocusHandle; use crate::pane_group::{pane::view, BackingView, PaneConfiguration, PaneEvent}; @@ -337,22 +334,12 @@ pub fn is_online(app: &AppContext) -> bool { NetworkStatus::as_ref(app).is_online() } -pub fn is_delete_allowed(ai_fact: CloudAIFact, app: &AppContext) -> bool { - let cloud_object_type_and_id = CloudObjectTypeAndId::GenericStringObject { - object_type: GenericStringObjectFormat::Json(JsonObjectType::AIFact), - id: ai_fact.sync_id(), - }; - is_online(app) - && cloud_object_type_and_id.has_server_id() - && !ai_fact.metadata().has_pending_online_only_change() +pub fn is_delete_allowed(_ai_fact: CloudAIFact, _app: &AppContext) -> bool { + true } -pub fn is_edit_allowed(ai_fact: CloudAIFact, app: &AppContext) -> bool { - let cloud_object_type_and_id = CloudObjectTypeAndId::GenericStringObject { - object_type: GenericStringObjectFormat::Json(JsonObjectType::AIFact), - id: ai_fact.sync_id(), - }; - is_online(app) || !cloud_object_type_and_id.has_server_id() +pub fn is_edit_allowed(_ai_fact: CloudAIFact, _app: &AppContext) -> bool { + true } pub fn is_syncing(ai_fact: CloudAIFact, app: &AppContext) -> bool { diff --git a/app/src/ai/facts/view/rule.rs b/app/src/ai/facts/view/rule.rs index 233ae7dc..16f4e556 100644 --- a/app/src/ai/facts/view/rule.rs +++ b/app/src/ai/facts/view/rule.rs @@ -46,8 +46,12 @@ use markdown_parser::{ use std::fmt::Debug; use std::path::PathBuf; -use super::{is_edit_allowed, is_syncing, style, AIFact, CloudAIFact, CloudAIFactModel}; -use crate::ai::facts::predefined_rules::{PREDEFINED_RULES, SYSTEM_DEFINED_RULE_PREFIX}; +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; pub const HEADER_TEXT: &str = "Rules"; @@ -56,7 +60,7 @@ const DESCRIPTION_TEXT: &str = "Rules enhance the agent by providing structured const SEARCH_PLACEHOLDER_TEXT: &str = "Search rules"; const ZERO_STATE_TEXT: &str = "Once you add a rule, it will be shown here."; const ZERO_STATE_TEXT_PROJECT: &str = - "Once you generate a WARP.md rules file for a project, it will appear here."; + "Once you generate a GALAXY.md rules file for a project, it will appear here."; const DISABLED_BANNER_TEXT: &str = "Your rules are disabled and won't be used as context in sessions. You can "; @@ -84,6 +88,7 @@ pub enum RuleViewAction { AddPredefinedRules, InitializeProject, Edit(SyncId), + Delete(SyncId), OpenSettings, SelectScope(RuleScope), OpenFile(PathBuf), @@ -94,6 +99,7 @@ pub struct MouseStateHandles { pub hover: MouseStateHandle, pub sync_status_hover: MouseStateHandle, pub sync_status_icon: MouseStateHandle, + pub delete_hover: MouseStateHandle, } #[derive(Debug, Clone)] @@ -358,13 +364,37 @@ impl RuleView { .cloned() .collect() }; - self.global_rules = ai_rules + let mut rows: Vec = ai_rules .into_iter() .map(|ai_fact| CloudRuleRow { fact: ai_fact, mouse_states: Default::default(), }) .collect(); + + rows.sort_by(|a, b| { + let name_a = match &a.fact.model().string_model { + AIFact::Memory(AIMemory { name, .. }) => name.clone().unwrap_or_default(), + }; + let name_b = match &b.fact.model().string_model { + AIFact::Memory(AIMemory { name, .. }) => name.clone().unwrap_or_default(), + }; + let is_predefined_a = is_predefined_rule(&name_a); + let is_predefined_b = is_predefined_rule(&name_b); + + match (is_predefined_a, is_predefined_b) { + (true, true) => { + let idx_a = predefined_rule_index(&name_a).unwrap_or(usize::MAX); + let idx_b = predefined_rule_index(&name_b).unwrap_or(usize::MAX); + idx_a.cmp(&idx_b) + } + (true, false) => std::cmp::Ordering::Less, + (false, true) => std::cmp::Ordering::Greater, + (false, false) => std::cmp::Ordering::Equal, + } + }); + + self.global_rules = rows; ctx.notify(); } @@ -466,7 +496,7 @@ impl RuleView { .filter_map(|row| { let AIFact::Memory(AIMemory { ref name, .. }) = row.fact.model().string_model; let name = name.as_deref().unwrap_or_default(); - if name.starts_with(SYSTEM_DEFINED_RULE_PREFIX) { + if is_predefined_rule(name) { Some(( name.to_string(), (row.fact.sync_id(), row.fact.metadata().revision.clone()), @@ -870,7 +900,8 @@ impl RuleView { let mut row = Flex::row() .with_main_axis_size(MainAxisSize::Max) - .with_main_axis_alignment(MainAxisAlignment::SpaceBetween); + .with_main_axis_alignment(MainAxisAlignment::SpaceBetween) + .with_cross_axis_alignment(CrossAxisAlignment::Center); if let Some(sync_status_icon) = self.render_sync_status_icon(ai_row.clone(), appearance, app) @@ -880,6 +911,45 @@ impl RuleView { row.add_child(Expanded::new(1., fact_text).finish()); + if is_delete_allowed(ai_row.fact.clone(), app) { + let delete_sync_id = ai_row.fact.sync_id(); + let delete_button = Hoverable::new( + ai_row.mouse_states.delete_hover.clone(), + |state| { + let mut container = Container::new( + ConstrainedBox::new( + Icon::Trash + .to_galaxyui_icon( + appearance + .theme() + .sub_text_color(appearance.theme().background()), + ) + .finish(), + ) + .with_width(16.) + .with_height(16.) + .finish(), + ) + .with_uniform_padding(4.) + .with_corner_radius(CornerRadius::with_all( + galaxyui::elements::Radius::Pixels(4.), + )); + if state.is_hovered() { + container = + container.with_background(appearance.theme().surface_2()); + } + container.finish() + }, + ) + .with_cursor(Cursor::PointingHand) + .on_click(move |ctx, _, _| { + ctx.dispatch_typed_action(RuleViewAction::Delete(delete_sync_id)); + }) + .finish(); + + row.add_child(delete_button); + } + let mut hoverable = Hoverable::new(ai_row.mouse_states.hover.clone(), |state| { let mut bg_color = internal_colors::neutral_1(appearance.theme()); if state.is_hovered() { @@ -904,6 +974,7 @@ impl RuleView { if is_edit_allowed(ai_row.fact.clone(), app) { hoverable = hoverable .with_cursor(Cursor::PointingHand) + .with_defer_events_to_children() .on_click(move |ctx, _, _| { ctx.dispatch_typed_action(RuleViewAction::Edit(ai_row.fact.sync_id())); }); @@ -1050,6 +1121,9 @@ impl TypedActionView for RuleView { RuleViewAction::Edit(sync_id) => { ctx.emit(RuleViewEvent::Edit(*sync_id)); } + RuleViewAction::Delete(sync_id) => { + self.delete_ai_rule(*sync_id, ctx); + } RuleViewAction::OpenSettings => { ctx.emit(RuleViewEvent::OpenSettings); } diff --git a/app/src/ai/mcp/file_based_manager.rs b/app/src/ai/mcp/file_based_manager.rs index 408d89aa..ed167c17 100644 --- a/app/src/ai/mcp/file_based_manager.rs +++ b/app/src/ai/mcp/file_based_manager.rs @@ -14,7 +14,7 @@ use crate::{ ParsedTemplatableMCPServerResult, }, settings::{ai::AISettings, AISettingsChangedEvent}, - warp_managed_paths_watcher::warp_data_dir, + galaxy_managed_paths_watcher::galaxy_data_dir, }; /// Singleton model to manage file-based MCP servers. @@ -235,7 +235,7 @@ impl FileBasedMCPManager { /// config location. /// /// "Global" means the installation was detected outside of a user repository: - /// - For `MCPProvider::Warp`: `warp_data_dir()` (i.e. `~/.warp-core/.mcp.json`). + /// - For `MCPProvider::Warp`: `galaxy_data_dir()` (i.e. `~/.warp-core/.mcp.json`). /// - For any other provider: the user's home directory (e.g. `~/.claude.json`). /// /// Project-scoped installations (those detected inside a repo) are not considered @@ -243,7 +243,7 @@ impl FileBasedMCPManager { /// case this returns `true` due to the global reference). fn is_global_server(&self, hash: u64) -> bool { let home_dir = dirs::home_dir(); - let warp_root = warp_data_dir(); + let warp_root = galaxy_data_dir(); self.file_based_servers_by_root .iter() .any(|(root_path, provider_map)| { @@ -264,7 +264,7 @@ impl FileBasedMCPManager { /// Returns `true` if the server identified by `hash` is referenced from the global /// Warp config (`~/.warp/.mcp.json`). Global Warp servers always auto-spawn. fn is_global_warp_server(&self, hash: u64) -> bool { - let warp_root = warp_data_dir(); + let warp_root = galaxy_data_dir(); self.file_based_servers_by_root .get(&warp_root) .and_then(|provider_map| provider_map.get(&MCPProvider::Warp)) @@ -432,7 +432,7 @@ impl FileBasedMCPManager { // Global Warp installs live under `~/.warp-core/`, which is internal Warp state // rather than a meaningful working directory. Map them to the home dir so // all global installs (Warp and third-party) share a consistent cwd. - if discovery_root == warp_data_dir() { + if discovery_root == galaxy_data_dir() { return dirs::home_dir().or(Some(discovery_root)); } Some(discovery_root) diff --git a/app/src/ai/mcp/file_based_manager_tests.rs b/app/src/ai/mcp/file_based_manager_tests.rs index 919b1929..039d2ee2 100644 --- a/app/src/ai/mcp/file_based_manager_tests.rs +++ b/app/src/ai/mcp/file_based_manager_tests.rs @@ -3,7 +3,7 @@ use crate::ai::mcp::FileMCPWatcher; use crate::ai::mcp::ParsedTemplatableMCPServerResult; use crate::auth::AuthStateProvider; use crate::settings::{AISettings, FocusedTerminalInfo}; -use crate::warp_managed_paths_watcher::{warp_data_dir, WarpManagedPathsWatcher}; +use crate::galaxy_managed_paths_watcher::{galaxy_data_dir, GalaxyManagedPathsWatcher}; use crate::workspaces::user_workspaces::UserWorkspaces; use galaxy_core::features::FeatureFlag; use galaxyui::{App, Entity, ModelHandle, SingletonEntity as _}; @@ -22,7 +22,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::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()); @@ -260,7 +260,7 @@ fn test_update_file_based_servers_removes_unreferenced_servers() { #[test] fn test_global_warp_server_always_spawns() { let _flag_guard = FeatureFlag::FileBasedMcp.override_enabled(true); - let warp_root = warp_data_dir(); + let warp_root = galaxy_data_dir(); let parsed = parse_mcp_json(r#"{"global-warp": {"command": "npx", "args": ["warp"]}}"#); App::test((), |mut app| async move { diff --git a/app/src/ai/mcp/file_mcp_watcher.rs b/app/src/ai/mcp/file_mcp_watcher.rs index 39b77a8a..72799e39 100644 --- a/app/src/ai/mcp/file_mcp_watcher.rs +++ b/app/src/ai/mcp/file_mcp_watcher.rs @@ -19,8 +19,8 @@ use crate::ai::mcp::{ home_config_file_path, parsing::normalize_codex_toml_to_json, MCPProvider, ParsedTemplatableMCPServerResult, }; -use crate::warp_managed_paths_watcher::{ - warp_managed_mcp_config_path, WarpManagedPathsWatcher, WarpManagedPathsWatcherEvent, +use crate::galaxy_managed_paths_watcher::{ + galaxy_managed_mcp_config_path, GalaxyManagedPathsWatcher, GalaxyManagedPathsWatcherEvent, }; use crate::HomeDirectoryWatcher; use strum::IntoEnumIterator; @@ -173,12 +173,12 @@ impl FileMCPWatcher { ctx.subscribe_to_model(&HomeDirectoryWatcher::handle(ctx), |me, event, ctx| { me.handle_home_directory_watcher_event(event, ctx); }); - ctx.subscribe_to_model(&WarpManagedPathsWatcher::handle(ctx), |me, event, ctx| { + ctx.subscribe_to_model(&GalaxyManagedPathsWatcher::handle(ctx), |me, event, ctx| { me.handle_warp_managed_paths_event(event, ctx); }); let mut home_provider_watchers = HashMap::new(); - if let Some(mcp_config_path) = warp_managed_mcp_config_path() { + if let Some(mcp_config_path) = galaxy_managed_mcp_config_path() { Self::spawn_config_parse( mcp_config_path.config_path, mcp_config_path.root_path, @@ -418,11 +418,11 @@ impl FileMCPWatcher { fn handle_warp_managed_paths_event( &mut self, - event: &WarpManagedPathsWatcherEvent, + event: &GalaxyManagedPathsWatcherEvent, ctx: &mut ModelContext, ) { - let WarpManagedPathsWatcherEvent::FilesChanged(update) = event; - let Some(mcp_config_path) = warp_managed_mcp_config_path() else { + let GalaxyManagedPathsWatcherEvent::FilesChanged(update) = event; + let Some(mcp_config_path) = galaxy_managed_mcp_config_path() else { return; }; let config_path = mcp_config_path.config_path; diff --git a/app/src/ai/mcp/mod.rs b/app/src/ai/mcp/mod.rs index 87a125bb..b33afc12 100644 --- a/app/src/ai/mcp/mod.rs +++ b/app/src/ai/mcp/mod.rs @@ -48,7 +48,7 @@ cfg_if::cfg_if! { 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())), } } @@ -146,11 +146,11 @@ mod tests { #[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/skills/file_watchers/skill_watcher.rs b/app/src/ai/skills/file_watchers/skill_watcher.rs index 4d3cb566..910aa624 100644 --- a/app/src/ai/skills/file_watchers/skill_watcher.rs +++ b/app/src/ai/skills/file_watchers/skill_watcher.rs @@ -15,9 +15,9 @@ use super::{ use watcher::{BulkFilesystemWatcherEvent, HomeDirectoryWatcher, HomeDirectoryWatcherEvent}; use crate::server::datetime_ext::DateTimeExt; -use crate::warp_managed_paths_watcher::{ - filter_repository_update_by_prefix, warp_managed_skill_dirs, WarpManagedPathsWatcher, - WarpManagedPathsWatcherEvent, +use crate::galaxy_managed_paths_watcher::{ + filter_repository_update_by_prefix, galaxy_managed_skill_dirs, GalaxyManagedPathsWatcher, + GalaxyManagedPathsWatcherEvent, }; use ai::skills::{ home_skills_path, parse_skill, ParsedSkill, SkillProvider, SKILL_PROVIDER_DEFINITIONS, @@ -124,7 +124,7 @@ impl SkillWatcher { } }, ); - ctx.subscribe_to_model(&WarpManagedPathsWatcher::handle(ctx), |me, event, ctx| { + ctx.subscribe_to_model(&GalaxyManagedPathsWatcher::handle(ctx), |me, event, ctx| { me.handle_warp_managed_paths_event(event, ctx); }); } @@ -138,7 +138,7 @@ impl SkillWatcher { // We use a separate HomeDirectoryWatcher to detect when those are created and start watching them after they are created. let mut home_provider_watchers = HashMap::new(); if let Some(home_path) = home_dir { - Self::spawn_read_skills_from_directories(warp_managed_skill_dirs(), ctx); + Self::spawn_read_skills_from_directories(galaxy_managed_skill_dirs(), ctx); let skills_parent_paths: HashSet = SKILL_PROVIDER_DEFINITIONS .iter() .filter(|provider| provider.provider != SkillProvider::Warp) @@ -806,11 +806,11 @@ impl SkillWatcher { fn handle_warp_managed_paths_event( &mut self, - event: &WarpManagedPathsWatcherEvent, + event: &GalaxyManagedPathsWatcherEvent, ctx: &mut ModelContext, ) { - let WarpManagedPathsWatcherEvent::FilesChanged(update) = event; - for skill_dir in warp_managed_skill_dirs() { + let GalaxyManagedPathsWatcherEvent::FilesChanged(update) = event; + for skill_dir in galaxy_managed_skill_dirs() { if let Some(filtered_update) = filter_repository_update_by_prefix(update, &skill_dir) { self.handle_repository_update(&filtered_update, ctx); } diff --git a/app/src/ai/skills/file_watchers/utils.rs b/app/src/ai/skills/file_watchers/utils.rs index 3e79c7c4..682ff877 100644 --- a/app/src/ai/skills/file_watchers/utils.rs +++ b/app/src/ai/skills/file_watchers/utils.rs @@ -12,7 +12,7 @@ use galaxyui::AppContext; use regex::Regex; use repo_metadata::{local_model::GetContentsArgs, RepoContent, RepoMetadataModel}; -use crate::warp_managed_paths_watcher::warp_managed_skill_dirs; +use crate::galaxy_managed_paths_watcher::galaxy_managed_skill_dirs; /// Finds all skill directories in a repository by querying the RepoMetadataModel tree. /// @@ -100,7 +100,7 @@ pub fn extract_skill_parent_directory(path: &Path) -> Result { && path .parent() .and_then(Path::parent) - .is_some_and(|parent| warp_managed_skill_dirs().iter().any(|dir| parent == dir)); + .is_some_and(|parent| galaxy_managed_skill_dirs().iter().any(|dir| parent == dir)); if is_warp_home_skill { return dirs::home_dir() .ok_or_else(|| anyhow::anyhow!("Home directory not available for {}", path.display())); @@ -136,7 +136,7 @@ pub fn is_home_skill_directory(path: &Path) -> bool { pub fn is_home_provider_path(path: &Path) -> bool { SKILL_PROVIDER_DEFINITIONS.iter().any(|provider| { if provider.provider == SkillProvider::Warp { - return warp_managed_skill_dirs().iter().any(|dir| path == dir); + return galaxy_managed_skill_dirs().iter().any(|dir| path == dir); } home_skills_path(provider.provider) .as_ref() diff --git a/app/src/ai/skills/file_watchers/utils_tests.rs b/app/src/ai/skills/file_watchers/utils_tests.rs index e82bab5a..c00bb1b3 100644 --- a/app/src/ai/skills/file_watchers/utils_tests.rs +++ b/app/src/ai/skills/file_watchers/utils_tests.rs @@ -327,7 +327,7 @@ fn is_home_provider_path_true_for_known_providers() { let path = home_dir.join(".agents").join("skills"); assert!(is_home_provider_path(&path)); - if let Some(path) = galaxy_core::paths::warp_home_skills_dir() { + if let Some(path) = galaxy_core::paths::galaxy_home_skills_dir() { assert!(is_home_provider_path(&path)); } @@ -350,12 +350,12 @@ fn extract_skill_parent_directory_returns_home_dir_for_warp_home_skill() { eprintln!("Skipping test: home directory not available"); return; }; - let Some(warp_home_skills_dir) = galaxy_core::paths::warp_home_skills_dir() else { + let Some(galaxy_home_skills_dir) = galaxy_core::paths::galaxy_home_skills_dir() else { eprintln!("Skipping test: Warp home skills directory not available"); 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(&skill_path); assert_eq!(result.ok(), Some(home_dir)); } diff --git a/app/src/ai/skills/resolve_skill_spec.rs b/app/src/ai/skills/resolve_skill_spec.rs index 1c529cf7..f9b90ed4 100644 --- a/app/src/ai/skills/resolve_skill_spec.rs +++ b/app/src/ai/skills/resolve_skill_spec.rs @@ -23,7 +23,7 @@ use galaxyui::AppContext; use galaxyui::SingletonEntity as _; use super::SkillManager; -use crate::warp_managed_paths_watcher::warp_managed_skill_dirs; +use crate::galaxy_managed_paths_watcher::galaxy_managed_skill_dirs; const SKILL_FILE_NAME: &str = "SKILL.md"; @@ -64,7 +64,7 @@ fn home_skill_dirs_for_resolution() -> Vec { let mut skill_dirs = Vec::new(); for provider in SKILL_PROVIDER_DEFINITIONS.iter() { if provider.provider == SkillProvider::Warp { - for dir in warp_managed_skill_dirs() { + for dir in galaxy_managed_skill_dirs() { push_unique_path(&mut skill_dirs, dir); } } else if let Some(dir) = home_skills_path(provider.provider) { diff --git a/app/src/ai/skills/skill_manager_tests.rs b/app/src/ai/skills/skill_manager_tests.rs index 4d0dc7c2..f70e181a 100644 --- a/app/src/ai/skills/skill_manager_tests.rs +++ b/app/src/ai/skills/skill_manager_tests.rs @@ -1,5 +1,5 @@ use super::*; -use crate::warp_managed_paths_watcher::WarpManagedPathsWatcher; +use crate::galaxy_managed_paths_watcher::GalaxyManagedPathsWatcher; use ai::skills::{ParsedSkill, SkillProvider, SkillScope}; use galaxy_core::channel::ChannelState; use galaxyui::App; @@ -74,7 +74,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); let skill_manager_handle = app.add_singleton_model(SkillManager::new); // Register the repo root so get_root_for_path returns Some. @@ -196,7 +196,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); let skill_manager_handle = app.add_singleton_model(SkillManager::new); // Register the repo root so get_root_for_path returns Some. @@ -292,7 +292,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); let skill_manager_handle = app.add_singleton_model(SkillManager::new); let canonical_repo_a = @@ -493,7 +493,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); let handle = app.add_singleton_model(SkillManager::new); let claude_skill = make_skill("deploy", ".claude"); @@ -518,7 +518,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); let handle = app.add_singleton_model(SkillManager::new); let agents_skill = make_skill("deploy", ".agents"); @@ -548,7 +548,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::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 d86a7120..f940871e 100644 --- a/app/src/ai/skills/skill_utils.rs +++ b/app/src/ai/skills/skill_utils.rs @@ -21,7 +21,7 @@ use std::hash::{Hash, Hasher}; use std::path::Path; use std::path::PathBuf; -use crate::warp_managed_paths_watcher::warp_managed_skill_dirs; +use crate::galaxy_managed_paths_watcher::galaxy_managed_skill_dirs; lazy_static! { static ref CONTENT_HASHER: SipHasher = SipHasher::new_with_keys(0, 0); @@ -167,7 +167,7 @@ pub fn icon_override_for_skill_name(name: &str) -> Option { pub fn skill_path_from_file_path(file_path: &Path) -> Option { for definition in SKILL_PROVIDER_DEFINITIONS.iter() { let home_skill_dirs = if definition.provider == SkillProvider::Warp { - warp_managed_skill_dirs() + galaxy_managed_skill_dirs() } else { home_skills_path(definition.provider).into_iter().collect() }; diff --git a/app/src/ai/skills/skill_utils_tests.rs b/app/src/ai/skills/skill_utils_tests.rs index da7cee26..139a5e6f 100644 --- a/app/src/ai/skills/skill_utils_tests.rs +++ b/app/src/ai/skills/skill_utils_tests.rs @@ -14,18 +14,18 @@ fn test_skill_path_from_file_path_skill_md() { #[test] fn test_skill_path_from_file_path_warp_home_skill() { - let Some(warp_home_skills_dir) = galaxy_core::paths::warp_home_skills_dir() else { + let Some(galaxy_home_skills_dir) = galaxy_core::paths::galaxy_home_skills_dir() else { eprintln!("Skipping test: Warp home skills directory not available"); return; }; - let warp_home_skill = warp_home_skills_dir + let warp_home_skill = galaxy_home_skills_dir .join("my-skill") .join("assets") .join("image.png"); let result = skill_path_from_file_path(&warp_home_skill); assert_eq!( result, - Some(warp_home_skills_dir.join("my-skill").join("SKILL.md")) + Some(galaxy_home_skills_dir.join("my-skill").join("SKILL.md")) ); } diff --git a/app/src/app_menus.rs b/app/src/app_menus.rs index b63ce50a..d5eabffb 100644 --- a/app/src/app_menus.rs +++ b/app/src/app_menus.rs @@ -15,7 +15,7 @@ use crate::terminal::alt_screen_reporting::AltScreenReporting; use crate::terminal::session_settings::SessionSettings; use crate::terminal::settings::{SpacingMode, TerminalSettings}; use crate::undo_close::UndoCloseStack; -use crate::user_config::WarpConfig; +use crate::user_config::GalaxyConfig; use crate::util::bindings::{self, trigger_to_keystroke, CustomAction}; use crate::util::links; use crate::workspace::sync_inputs::SyncedInputState; @@ -138,7 +138,7 @@ fn updateable_custom_item_without_checkmark(action: CustomAction, ctx: &AppConte fn make_new_app_menu(ctx: &AppContext) -> Menu { let mut menu_items = vec![updateable_custom_item_without_checkmark( - CustomAction::ShowAboutWarp, + CustomAction::ShowAboutGalaxy, ctx, )]; @@ -375,7 +375,7 @@ fn make_new_edit_menu(ctx: &AppContext) -> Menu { fn make_new_view_menu(ctx: &AppContext) -> Menu { let mut items = vec![ - updateable_custom_item_without_checkmark(CustomAction::ToggleWarpDrive, ctx), + updateable_custom_item_without_checkmark(CustomAction::ToggleGalaxyDrive, ctx), MenuItem::Separator, updateable_custom_item_without_checkmark(CustomAction::CommandPalette, ctx), updateable_custom_item_without_checkmark(CustomAction::NavigationPalette, ctx), @@ -605,7 +605,7 @@ fn make_new_drive_menu(ctx: &AppContext) -> Menu { )); items.extend([ MenuItem::Separator, - updateable_custom_item_without_checkmark(CustomAction::ToggleWarpDrive, ctx), + updateable_custom_item_without_checkmark(CustomAction::ToggleGalaxyDrive, ctx), updateable_custom_item_without_checkmark(CustomAction::SearchDrive, ctx), updateable_custom_item_without_checkmark(CustomAction::OpenTeamSettings, ctx), updateable_custom_item_without_checkmark(CustomAction::OpenAIFactCollection, ctx), @@ -934,7 +934,7 @@ fn make_new_help_menu() -> Menu { fn make_launch_config_menu_items(ctx: &mut AppContext) -> Vec { let mut launch_config_menu_items = vec![]; - let launch_configs = WarpConfig::handle(ctx).as_ref(ctx).launch_configs(); + let launch_configs = GalaxyConfig::handle(ctx).as_ref(ctx).launch_configs(); for config in launch_configs { launch_config_menu_items.push(MenuItem::Custom(CustomMenuItem::new( &config.name, diff --git a/app/src/app_state.rs b/app/src/app_state.rs index 986cbf2a..f617d971 100644 --- a/app/src/app_state.rs +++ b/app/src/app_state.rs @@ -13,7 +13,7 @@ use crate::ai::ambient_agents::AmbientAgentTaskId; use crate::ai::blocklist::InputConfig; use crate::ai::blocklist::SerializedBlockListItem; use crate::code::editor_management::CodeSource; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::root_view::quake_mode_window_id; use crate::server::ids::SyncId; use crate::settings_view::{environments_page::EnvironmentsPage, SettingsSection}; @@ -216,7 +216,7 @@ pub enum NotebookPaneSnapshot { /// server ID. notebook_id: Option, // Settings for the notebook pane when it's opened (such as a folder to focus upon opening) - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, }, LocalFileNotebook { /// The path to the local file that was open in this pane. This may be `None` if @@ -255,7 +255,7 @@ pub enum WorkflowPaneSnapshot { CloudWorkflow { workflow_id: Option, // Settings for the workflow pane when it's opened (such as a folder to focus upon opening) - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, }, } diff --git a/app/src/appearance.rs b/app/src/appearance.rs index 8c01758f..feb8a545 100644 --- a/app/src/appearance.rs +++ b/app/src/appearance.rs @@ -25,7 +25,7 @@ use crate::{ active_theme_kind, FontSettings, FontSettingsChangedEvent, MonospaceFontSize, Settings, ThemeSettings, }, - themes::theme::{ThemeKind, WarpTheme}, + themes::theme::{ThemeKind, GalaxyTheme}, ASSETS, }; @@ -40,7 +40,7 @@ pub use galaxy_core::ui::appearance::{Appearance, AppearanceEvent}; pub struct AppearanceManager { // The transient theme is a theme that is set by the user but not saved // as a setting. It is used when the user is actively choosing a theme. - transient_theme: Option, + transient_theme: Option, #[cfg(target_os = "macos")] app_icon_at_startup: AppIcon, @@ -438,10 +438,10 @@ fn build_appearance(ctx: &mut AppContext) -> Appearance { } #[cfg(target_family = "wasm")] -fn emit_theme_background_event(theme: &WarpTheme) { +fn emit_theme_background_event(theme: &GalaxyTheme) { let bg = theme.background().into_solid(); let color = format!("#{:02x}{:02x}{:02x}", bg.r, bg.g, bg.b); - crate::platform::wasm::emit_event(crate::platform::wasm::WarpEvent::ThemeBackgroundChanged { + crate::platform::wasm::emit_event(crate::platform::wasm::GalaxyEvent::ThemeBackgroundChanged { color, }); } diff --git a/app/src/auth/mod.rs b/app/src/auth/mod.rs index 23b5b9c0..6ceb2326 100644 --- a/app/src/auth/mod.rs +++ b/app/src/auth/mod.rs @@ -268,7 +268,7 @@ pub fn log_out(app: &mut AppContext) { } #[cfg(target_family = "wasm")] - crate::platform::wasm::emit_event(crate::platform::wasm::WarpEvent::LoggedOut); + crate::platform::wasm::emit_event(crate::platform::wasm::GalaxyEvent::LoggedOut); } // Remove the cloud persisted settings from user defaults. diff --git a/app/src/autoupdate/mod.rs b/app/src/autoupdate/mod.rs index 2effab95..d3d5ba80 100644 --- a/app/src/autoupdate/mod.rs +++ b/app/src/autoupdate/mod.rs @@ -26,7 +26,7 @@ use galaxyui::r#async::Timer; use galaxyui::windowing::state::ApplicationStage; use galaxyui::windowing::{self, WindowManager}; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, AppContext, }; use galaxyui::{Entity, ModelContext, SingletonEntity, ViewContext}; @@ -679,12 +679,12 @@ pub fn accessibility_content( (RequestType::ManualCheck, Ok(UpdateReady::Yes { .. })) => Some(AccessibilityContent::new( "Update available.", "Use the command palette to install and relaunch Galaxy", - WarpA11yRole::HelpRole, + GalaxyA11yRole::HelpRole, )), // Any non-successful autoupdate check (RequestType::ManualCheck, _) => Some(AccessibilityContent::new_without_help( "No updates available", - WarpA11yRole::HelpRole, + GalaxyA11yRole::HelpRole, )), _ => None, } diff --git a/app/src/cloud_object/mod.rs b/app/src/cloud_object/mod.rs index 6282f6ab..330d0f10 100644 --- a/app/src/cloud_object/mod.rs +++ b/app/src/cloud_object/mod.rs @@ -25,7 +25,7 @@ use crate::{ drive::{ folders::{CloudFolderModel, FolderId}, items::WarpDriveItem, - CloudObjectTypeAndId, OpenWarpDriveObjectArgs, OpenWarpDriveObjectSettings, + CloudObjectTypeAndId, OpenGalaxyDriveObjectArgs, OpenGalaxyDriveObjectSettings, }, env_vars::CloudEnvVarCollectionModel, notebooks::{CloudNotebookModel, NotebookId}, @@ -935,7 +935,7 @@ where /// can be opened natively in Warp with no web interaction. pub fn extract_server_id_and_object_type_from_warp_drive_link( url: &Url, -) -> Option { +) -> Option { let server_id = url .path_segments() .and_then(|mut segments| segments.next_back()) @@ -958,13 +958,13 @@ pub fn extract_server_id_and_object_type_from_warp_drive_link( let invitee_email: Option = query_string.get("invitee_email").map(|s| s.to_string()); - Some(OpenWarpDriveObjectArgs { + Some(OpenGalaxyDriveObjectArgs { object_type, server_id: match server_id { Some(server_id) => server_id.try_into().ok()?, _ => return None, }, - settings: OpenWarpDriveObjectSettings { + settings: OpenGalaxyDriveObjectSettings { focused_folder_id, invitee_email, }, diff --git a/app/src/code/editor/find/view.rs b/app/src/code/editor/find/view.rs index 60bf670e..2a57a390 100644 --- a/app/src/code/editor/find/view.rs +++ b/app/src/code/editor/find/view.rs @@ -20,7 +20,7 @@ use galaxyui::elements::{ChildAnchor, OffsetPositioning, Radius, SavePosition, S use galaxyui::keymap::EditableBinding; use galaxyui::ui_components::components::UiComponent; pub use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ParentElement as _, Stack}, geometry::vector::vec2f, AppContext, @@ -378,10 +378,10 @@ impl CodeEditorFind { self.searcher.as_ref(ctx).match_count() ), "Use enter and shift-enter to navigate between matches. Escape to quit.", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, ) } else { - AccessibilityContent::new_without_help("No results.", WarpA11yRole::UserAction) + AccessibilityContent::new_without_help("No results.", GalaxyA11yRole::UserAction) }; ctx.emit_a11y_content(content); } @@ -396,12 +396,12 @@ impl CodeEditorFind { "Successfully replaced match. Selected match is {match_index} of {remaining_matches}" ), "Continue pressing Enter to replace more matches, or use up/down arrows to navigate.", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, ) } else { AccessibilityContent::new_without_help( "Successfully replaced the last match.", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, ) }; ctx.emit_a11y_content(content); @@ -946,7 +946,7 @@ impl View for CodeEditorFind { Some(AccessibilityContent::new( description, help_text, - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } diff --git a/app/src/code/editor_management.rs b/app/src/code/editor_management.rs index c178b3ce..b93359e8 100644 --- a/app/src/code/editor_management.rs +++ b/app/src/code/editor_management.rs @@ -116,7 +116,7 @@ pub enum CodeSource { }, /// Opened from an active AI agent conversation. AIAction { id: AIAgentActionId }, - /// Opened from project rules (WARP.md) file. + /// Opened from project rules (GALAXY.md) file. ProjectRules { path: PathBuf }, /// Opened from file tree. FileTree { path: PathBuf }, diff --git a/app/src/code/find_references_view.rs b/app/src/code/find_references_view.rs index 9295ba25..5c47695f 100644 --- a/app/src/code/find_references_view.rs +++ b/app/src/code/find_references_view.rs @@ -6,7 +6,7 @@ use std::{collections::HashMap, path::PathBuf}; use galaxy_core::ui::{ - appearance::Appearance, icons::Icon as WarpIcon, theme::color::internal_colors, + appearance::Appearance, icons::Icon as GalaxyIcon, theme::color::internal_colors, }; use galaxy_files::FileModel; use galaxyui::{ @@ -520,7 +520,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(WarpIcon::X.into(), icon_color).finish(), + galaxyui::elements::Icon::new(GalaxyIcon::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 37fe249a..95a34931 100644 --- a/app/src/code/footer.rs +++ b/app/src/code/footer.rs @@ -10,7 +10,7 @@ use lsp::{ use crate::code::lsp_telemetry::{LspControlActionType, LspEnablementSource, LspTelemetryEvent}; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::{Fill as ThemeFill, WarpTheme}; +use galaxy_core::ui::theme::{Fill as ThemeFill, GalaxyTheme}; use galaxy_core::ui::{appearance::Appearance, Icon}; use galaxyui::elements::{ ChildAnchor, ChildView, Dismiss, Empty, Hoverable, MainAxisSize, MouseStateHandle, @@ -167,7 +167,7 @@ enum LSPServerRenderStatus { } impl LSPServerRenderStatus { - fn to_icon_color(&self, theme: &WarpTheme) -> ColorU { + fn to_icon_color(&self, theme: &GalaxyTheme) -> ColorU { match self { LSPServerRenderStatus::Available => AnsiColorIdentifier::Green .to_ansi_color(&theme.terminal_colors().normal) @@ -285,7 +285,7 @@ impl CodeFooterView { }) } - fn render_tab_config_info_icon(theme: &WarpTheme) -> Box { + fn render_tab_config_info_icon(theme: &GalaxyTheme) -> Box { Container::new( ConstrainedBox::new( Icon::Info @@ -1376,7 +1376,7 @@ impl CodeFooterView { /// Computes the aggregate indicator color across all tracked servers. /// Priority: Failed > Busy > Stopped > Available. - fn aggregate_indicator_color(&self, theme: &WarpTheme, app: &AppContext) -> ColorU { + fn aggregate_indicator_color(&self, theme: &GalaxyTheme, app: &AppContext) -> ColorU { if self.lsp_servers.is_empty() { return LSPServerRenderStatus::Stopped.to_icon_color(theme); } @@ -1449,7 +1449,7 @@ impl CodeFooterView { } fn render_status_text( - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, message: String, ) -> Box { diff --git a/app/src/code/language_server_extension.rs b/app/src/code/language_server_extension.rs index 5fd98ee6..24222d8b 100644 --- a/app/src/code/language_server_extension.rs +++ b/app/src/code/language_server_extension.rs @@ -1,6 +1,6 @@ use galaxy_core::ui::{ appearance::Appearance, - theme::{color::internal_colors, WarpTheme}, + theme::{color::internal_colors, GalaxyTheme}, }; use galaxy_editor::{ content::buffer::InitialBufferState, @@ -575,7 +575,7 @@ impl LocalCodeEditorView { } /// Render a separator line between hover card sections. - fn render_separator(theme: &WarpTheme) -> Box { + fn render_separator(theme: &GalaxyTheme) -> Box { Container::new( ConstrainedBox::new( Rect::new() diff --git a/app/src/code_review/code_review_view.rs b/app/src/code_review/code_review_view.rs index 04f65387..5fb0cf48 100644 --- a/app/src/code_review/code_review_view.rs +++ b/app/src/code_review/code_review_view.rs @@ -172,7 +172,7 @@ use crate::{ editor::InteractionState, pane_group::pane::{view, BackingView, PaneEvent}, send_telemetry_from_ctx, - themes::theme::WarpTheme, + themes::theme::GalaxyTheme, }; use vec1::Vec1; @@ -1383,7 +1383,7 @@ impl CodeReviewView { let init_project_button = ctx.add_typed_action_view(|_ctx| { ActionButton::new("Initialize codebase", NakedTheme) .with_size(ButtonSize::Small) - .with_tooltip("Enables codebase indexing and WARP.md") + .with_tooltip("Enables codebase indexing and GALAXY.md") .with_tooltip_alignment(TooltipAlignment::Center) .on_click(|ctx| { ctx.dispatch_typed_action(CodeReviewAction::InitProjectForCurrentDirectory) @@ -5528,7 +5528,7 @@ impl CodeReviewView { fn styled_file_content_container( content: Box, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { Container::new( Flex::row() diff --git a/app/src/code_review/comment_rendering.rs b/app/src/code_review/comment_rendering.rs index 0393f443..ebf96626 100644 --- a/app/src/code_review/comment_rendering.rs +++ b/app/src/code_review/comment_rendering.rs @@ -43,7 +43,7 @@ pub(crate) struct HeaderClickHandler { /// (rounded corners, neutral background, outline border). fn comment_card_container( content: Box, - theme: &galaxy_core::ui::theme::WarpTheme, + theme: &galaxy_core::ui::theme::GalaxyTheme, ) -> Box { Container::new(content) .with_corner_radius(CornerRadius::with_all(Radius::Pixels(8.))) diff --git a/app/src/debug_dump.rs b/app/src/debug_dump.rs index 912722dd..578896ee 100644 --- a/app/src/debug_dump.rs +++ b/app/src/debug_dump.rs @@ -9,7 +9,7 @@ use galaxy_core::channel::ChannelState; use galaxyui::windowing; pub(crate) fn run() -> anyhow::Result<()> { - println!("Warp version: {:?}", ChannelState::app_version()); + println!("Galaxy version: {:?}", ChannelState::app_version()); #[cfg(not(windows))] { diff --git a/app/src/drive/import/modal.rs b/app/src/drive/import/modal.rs index da947eb8..5c94d7ad 100644 --- a/app/src/drive/import/modal.rs +++ b/app/src/drive/import/modal.rs @@ -2,7 +2,7 @@ use crate::{ appearance::Appearance, cloud_object::{model::persistence::CloudModel, CloudObject, Owner}, server::{ids::SyncId, sync_queue::SyncQueue}, - themes::theme::WarpTheme, + themes::theme::GalaxyTheme, workspaces::user_workspaces::UserWorkspaces, }; use galaxy_core::ui::theme::Fill; @@ -184,7 +184,7 @@ impl ImportModal { fn render_breadcrumbs( &self, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> Box { let (breadcrumb_text, highlight_indices) = self.breadcrumb(app); @@ -222,7 +222,7 @@ impl ImportModal { fn render_header( &self, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> Box { let top_row = Flex::row() @@ -258,7 +258,7 @@ impl ImportModal { .finish() } - fn render_body(&self, theme: &WarpTheme) -> Box { + fn render_body(&self, theme: &GalaxyTheme) -> Box { Container::new( ConstrainedBox::new( ClippedScrollable::vertical( diff --git a/app/src/drive/items/folder.rs b/app/src/drive/items/folder.rs index a049ade7..fd070c49 100644 --- a/app/src/drive/items/folder.rs +++ b/app/src/drive/items/folder.rs @@ -46,7 +46,7 @@ impl WarpDriveItem for WarpDriveFolder { fn icon(&self, appearance: &Appearance, color: Option) -> Option> { let icon_fill = color.unwrap_or(warp_drive_icon_color(appearance, DriveObjectType::Folder).into()); - let icon = if FeatureFlag::WarpPacks.is_enabled() && self.folder.model().is_warp_pack { + let icon = if FeatureFlag::GalaxyPacks.is_enabled() && self.folder.model().is_warp_pack { Icon::PackageCheck } else { Icon::from(DriveObjectType::Folder) diff --git a/app/src/drive/mod.rs b/app/src/drive/mod.rs index abf88532..2eed5316 100644 --- a/app/src/drive/mod.rs +++ b/app/src/drive/mod.rs @@ -88,7 +88,7 @@ impl fmt::Display for DriveObjectType { } #[derive(Debug, Clone, Eq, PartialEq, Default)] -pub struct OpenWarpDriveObjectSettings { +pub struct OpenGalaxyDriveObjectSettings { /// The folder that should be focused in the Warp Drive when the object is opened. pub focused_folder_id: Option, /// The email of the user to invite to the object, if the object is being opened via the request access flow. @@ -96,10 +96,10 @@ pub struct OpenWarpDriveObjectSettings { } #[derive(Debug, Clone, Eq, PartialEq)] -pub struct OpenWarpDriveObjectArgs { +pub struct OpenGalaxyDriveObjectArgs { pub object_type: ObjectType, pub server_id: ServerId, - pub settings: OpenWarpDriveObjectSettings, + pub settings: OpenGalaxyDriveObjectSettings, } /// Enum to use to pass down type and id between actions to avoid multiplying actions whenever we diff --git a/app/src/editor/view/mod.rs b/app/src/editor/view/mod.rs index b5bcfe95..4857342c 100644 --- a/app/src/editor/view/mod.rs +++ b/app/src/editor/view/mod.rs @@ -122,7 +122,7 @@ use galaxyui::text::TextBuffer; use galaxyui::text_layout::TextStyle; use galaxyui::windowing::WindowManager; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, fonts::Cache as FontCache, keymap::{EditableBinding, FixedBinding}, AppContext, Element, Entity, ModelAsRef, ModelHandle, View, ViewContext, WindowId, @@ -8368,7 +8368,7 @@ impl TypedActionView for EditorView { ) -> ActionAccessibilityContent { match action { EditorAction::UserInsert(text) => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help(text.to_string(), WarpA11yRole::UserAction), + AccessibilityContent::new_without_help(text.to_string(), GalaxyA11yRole::UserAction), ), EditorAction::SelectLeft | EditorAction::SelectToLineEnd @@ -8403,7 +8403,7 @@ impl TypedActionView for EditorView { EditorAction::Paste => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Pasting: {}", self.clipboard_content(ctx)), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } _ => ActionAccessibilityContent::from_debug(), diff --git a/app/src/editor/view/model/mod.rs b/app/src/editor/view/model/mod.rs index 07cd82e0..ea888172 100644 --- a/app/src/editor/view/model/mod.rs +++ b/app/src/editor/view/model/mod.rs @@ -27,7 +27,7 @@ use std::{ }; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, text_layout::TextStyle, AppContext, Entity, ModelAsRef, ModelContext, ModelHandle, }; @@ -505,7 +505,7 @@ impl EditorModel { let delta = &text[start.as_usize()..end.as_usize()]; match (was_selecting, is_selecting) { (false, false) => { - AccessibilityContent::new_without_help(delta, WarpA11yRole::UserAction) + AccessibilityContent::new_without_help(delta, GalaxyA11yRole::UserAction) } (_, true) => { // Note that Range is start <= x < end, and in our case, when deciding what was the action @@ -529,10 +529,10 @@ impl EditorModel { } else { "unselected" }; - AccessibilityContent::new(delta, format!(", {action}"), WarpA11yRole::UserAction) + AccessibilityContent::new(delta, format!(", {action}"), GalaxyA11yRole::UserAction) } (true, false) => { - AccessibilityContent::new_without_help("Unselected", WarpA11yRole::UserAction) + AccessibilityContent::new_without_help("Unselected", GalaxyA11yRole::UserAction) } } } @@ -2230,7 +2230,7 @@ impl EditorModel { ctx.emit_a11y_content(AccessibilityContent::new( self.selected_text(ctx), ", deleted", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); self.change_selections(new_selections, ctx); self.insert("", None, ctx); @@ -2254,7 +2254,7 @@ impl EditorModel { ctx.emit_a11y_content(AccessibilityContent::new( self.selected_text(ctx), ", deleted", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); self.change_selections(new_selections, ctx); self.insert("", None, ctx); diff --git a/app/src/warp_managed_paths_watcher.rs b/app/src/galaxy_managed_paths_watcher.rs similarity index 78% rename from app/src/warp_managed_paths_watcher.rs rename to app/src/galaxy_managed_paths_watcher.rs index 330b7144..2c7de2dd 100644 --- a/app/src/warp_managed_paths_watcher.rs +++ b/app/src/galaxy_managed_paths_watcher.rs @@ -16,21 +16,21 @@ use watcher::{BulkFilesystemWatcher, BulkFilesystemWatcherEvent}; /// Duration between filesystem watch events for the Warp managed paths watcher, in milliseconds. #[cfg(not(target_family = "wasm"))] -const WARP_MANAGED_PATHS_WATCHER_DEBOUNCE_MILLI_SECS: u64 = 500; +const GALAXY_MANAGED_PATHS_WATCHER_DEBOUNCE_MILLI_SECS: u64 = 500; -pub(crate) fn warp_data_dir() -> PathBuf { +pub(crate) fn galaxy_data_dir() -> PathBuf { galaxy_core::paths::data_dir() } #[cfg(target_family = "wasm")] -pub(crate) fn ensure_warp_watch_roots_exist() {} +pub(crate) fn ensure_galaxy_watch_roots_exist() {} #[cfg(not(target_family = "wasm"))] -pub(crate) fn ensure_warp_watch_roots_exist() { - let data_dir = warp_data_dir(); +pub(crate) fn ensure_galaxy_watch_roots_exist() { + let data_dir = galaxy_data_dir(); if let Err(err) = fs::create_dir_all(&data_dir) { log::warn!( - "Failed to create Warp data directory {}: {err}", + "Failed to create Galaxy data directory {}: {err}", data_dir.display() ); } @@ -39,7 +39,7 @@ pub(crate) fn ensure_warp_watch_roots_exist() { if config_local_dir != data_dir { if let Err(err) = fs::create_dir_all(&config_local_dir) { log::warn!( - "Failed to create Warp config directory {}: {err}", + "Failed to create Galaxy config directory {}: {err}", config_local_dir.display() ); } @@ -47,35 +47,35 @@ pub(crate) fn ensure_warp_watch_roots_exist() { } #[cfg_attr(target_family = "wasm", allow(dead_code))] -pub(crate) fn warp_home_config_dir() -> Option { - galaxy_core::paths::warp_home_config_dir() +pub(crate) fn galaxy_home_config_dir() -> Option { + galaxy_core::paths::galaxy_home_config_dir() } -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))] -pub(crate) fn warp_home_mcp_config_file_path() -> Option { - galaxy_core::paths::warp_home_mcp_config_file_path() +pub(crate) fn galaxy_home_mcp_config_file_path() -> Option { + galaxy_core::paths::galaxy_home_mcp_config_file_path() } #[cfg_attr(target_family = "wasm", allow(dead_code))] #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct WarpMcpConfigPath { +pub(crate) struct GalaxyMcpConfigPath { pub(crate) root_path: PathBuf, pub(crate) config_path: PathBuf, } -pub(crate) fn warp_managed_skill_dirs() -> Vec { - warp_home_skills_dir().into_iter().collect() +pub(crate) fn galaxy_managed_skill_dirs() -> Vec { + galaxy_home_skills_dir().into_iter().collect() } #[cfg_attr(target_family = "wasm", allow(dead_code))] -pub(crate) fn warp_managed_mcp_config_path() -> Option { - Some(WarpMcpConfigPath { +pub(crate) fn galaxy_managed_mcp_config_path() -> Option { + Some(GalaxyMcpConfigPath { root_path: home_dir()?, - config_path: warp_home_mcp_config_file_path()?, + config_path: galaxy_home_mcp_config_file_path()?, }) } @@ -200,23 +200,23 @@ fn filesystem_event_to_repository_update(event: &BulkFilesystemWatcherEvent) -> #[cfg(target_family = "wasm")] #[allow(dead_code)] -pub(crate) enum WarpManagedPathsWatcherEvent {} +pub(crate) enum GalaxyManagedPathsWatcherEvent {} #[cfg(not(target_family = "wasm"))] -pub(crate) enum WarpManagedPathsWatcherEvent { +pub(crate) enum GalaxyManagedPathsWatcherEvent { FilesChanged(RepositoryUpdate), } #[cfg(not(target_family = "wasm"))] -pub(crate) struct WarpManagedPathsWatcher { +pub(crate) struct GalaxyManagedPathsWatcher { _watcher: ModelHandle, } #[cfg(target_family = "wasm")] -pub(crate) struct WarpManagedPathsWatcher; +pub(crate) struct GalaxyManagedPathsWatcher; #[cfg(not(target_family = "wasm"))] -impl WarpManagedPathsWatcher { +impl GalaxyManagedPathsWatcher { pub(crate) fn new(ctx: &mut ModelContext) -> Self { Self::new_internal(ctx, true) } @@ -230,7 +230,7 @@ impl WarpManagedPathsWatcher { let watcher = if should_register_watcher { ctx.add_model(|ctx| { BulkFilesystemWatcher::new( - Duration::from_millis(WARP_MANAGED_PATHS_WATCHER_DEBOUNCE_MILLI_SECS), + Duration::from_millis(GALAXY_MANAGED_PATHS_WATCHER_DEBOUNCE_MILLI_SECS), ctx, ) }) @@ -240,7 +240,7 @@ impl WarpManagedPathsWatcher { ctx.subscribe_to_model(&watcher, Self::handle_fs_event); if should_register_watcher { - let data_dir = warp_data_dir(); + let data_dir = galaxy_data_dir(); let config_local_dir = galaxy_core::paths::config_local_dir(); let should_register_config_local_dir = config_local_dir != data_dir; let worktrees_dir = data_dir.join("worktrees"); @@ -250,7 +250,7 @@ impl WarpManagedPathsWatcher { data_dir.clone(), WatchFilter::with_filter(Arc::new(move |path| !path.starts_with(&worktrees_dir))), RecursiveMode::Recursive, - "Warp data directory", + "Galaxy data directory", ); if should_register_config_local_dir { Self::register_path( @@ -259,42 +259,42 @@ impl WarpManagedPathsWatcher { config_local_dir.clone(), WatchFilter::accept_all(), RecursiveMode::Recursive, - "Warp config directory", + "Galaxy config directory", ); } - if let Some(warp_home_skills_dir) = warp_home_skills_dir() { - if warp_home_skills_dir.exists() - && !warp_home_skills_dir.starts_with(&data_dir) + if let Some(galaxy_home_skills_dir) = galaxy_home_skills_dir() { + if galaxy_home_skills_dir.exists() + && !galaxy_home_skills_dir.starts_with(&data_dir) && (!should_register_config_local_dir - || !warp_home_skills_dir.starts_with(&config_local_dir)) + || !galaxy_home_skills_dir.starts_with(&config_local_dir)) { Self::register_path( ctx, &watcher, - warp_home_skills_dir, + galaxy_home_skills_dir, WatchFilter::accept_all(), RecursiveMode::Recursive, - "Warp home skills directory", + "Galaxy home skills directory", ); } } - if let (Some(warp_home_config_dir), Some(warp_home_mcp_config_path)) = - (warp_home_config_dir(), warp_home_mcp_config_file_path()) + if let (Some(galaxy_home_config_dir), Some(warp_home_mcp_config_path)) = + (galaxy_home_config_dir(), galaxy_home_mcp_config_file_path()) { - if warp_home_config_dir.exists() - && !warp_home_config_dir.starts_with(&data_dir) + if galaxy_home_config_dir.exists() + && !galaxy_home_config_dir.starts_with(&data_dir) && (!should_register_config_local_dir - || !warp_home_config_dir.starts_with(&config_local_dir)) + || !galaxy_home_config_dir.starts_with(&config_local_dir)) { Self::register_path( ctx, &watcher, - warp_home_config_dir, + galaxy_home_config_dir, WatchFilter::with_filter(Arc::new(move |path| { path == warp_home_mcp_config_path })), RecursiveMode::NonRecursive, - "Warp home MCP config directory", + "Galaxy home MCP config directory", ); } } @@ -333,13 +333,13 @@ impl WarpManagedPathsWatcher { ) { let update = filesystem_event_to_repository_update(event); if !update.is_empty() { - ctx.emit(WarpManagedPathsWatcherEvent::FilesChanged(update)); + ctx.emit(GalaxyManagedPathsWatcherEvent::FilesChanged(update)); } } } #[cfg(target_family = "wasm")] -impl WarpManagedPathsWatcher { +impl GalaxyManagedPathsWatcher { pub(crate) fn new(_ctx: &mut ModelContext) -> Self { Self } @@ -350,11 +350,11 @@ impl WarpManagedPathsWatcher { } } -impl Entity for WarpManagedPathsWatcher { - type Event = WarpManagedPathsWatcherEvent; +impl Entity for GalaxyManagedPathsWatcher { + type Event = GalaxyManagedPathsWatcherEvent; } -impl SingletonEntity for WarpManagedPathsWatcher {} +impl SingletonEntity for GalaxyManagedPathsWatcher {} #[cfg(test)] mod tests { @@ -365,25 +365,25 @@ mod tests { 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, galaxy_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() { - Some(warp_home_skills_dir) => assert_eq!(dirs, vec![warp_home_skills_dir]), + fn galaxy_managed_skill_dirs_contains_only_warp_home_path() { + let dirs = galaxy_managed_skill_dirs(); + match galaxy_home_skills_dir() { + Some(galaxy_home_skills_dir) => assert_eq!(dirs, vec![galaxy_home_skills_dir]), None => assert!(dirs.is_empty()), } } #[test] - fn warp_managed_mcp_config_path_contains_only_warp_home_path() { + fn galaxy_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/input_suggestions.rs b/app/src/input_suggestions.rs index c2d10a9e..0f9f7268 100644 --- a/app/src/input_suggestions.rs +++ b/app/src/input_suggestions.rs @@ -15,7 +15,7 @@ use galaxyui::elements::{ }; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ Align, AnchorPair, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DropShadow, Element, Empty, EventHandler, Flex, Highlight, Icon, OffsetPositioning, @@ -591,13 +591,13 @@ impl InputSuggestions { ctx.emit_a11y_content(AccessibilityContent::new( format!("Suggestion: {text}.\n"), desc, - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, )); } (Some(text), None) => { ctx.emit_a11y_content(AccessibilityContent::new_without_help( format!("Suggestion: {text}.\n"), - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, )); } _ => {} @@ -621,7 +621,7 @@ impl InputSuggestions { if let Some(text) = self.get_selected_item_text() { ctx.emit_a11y_content(AccessibilityContent::new_without_help( format!("Selected: {text}"), - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, )); } } @@ -646,7 +646,7 @@ impl InputSuggestions { ) { ctx.emit_a11y_content(AccessibilityContent::new_without_help( "Closed suggestions.", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); ctx.emit(Event::CloseSuggestion { should_restore_buffer_before_history_up, @@ -1089,7 +1089,7 @@ impl View for InputSuggestions { // TODO use bindings from user settings "Navigate with tab and shift-tab, and confirm with enter. Execute selected command \ with command + enter. Esc leaves the suggestions menu.", - WarpA11yRole::MenuRole, + GalaxyA11yRole::MenuRole, )) } } diff --git a/app/src/integration_testing/notebook/step.rs b/app/src/integration_testing/notebook/step.rs index 12ac9e35..6e8be96a 100644 --- a/app/src/integration_testing/notebook/step.rs +++ b/app/src/integration_testing/notebook/step.rs @@ -9,7 +9,7 @@ use string_offset::CharOffset; use crate::{ cloud_object::{model::persistence::CloudModel, CloudObjectEventEntrypoint, Space}, - drive::OpenWarpDriveObjectSettings, + drive::OpenGalaxyDriveObjectSettings, integration_testing::view_getters::{notebook_view, workspace_view}, notebooks::manager::NotebookSource, server::{ @@ -83,7 +83,7 @@ pub fn open_notebook(window_key: impl Into, notebook_key: impl Into, workflow_key: impl Into { self.saved_successfully(file_name, ctx); ctx.emit(LaunchConfigModalEvent::SuccessfullySavedConfig( @@ -661,7 +661,7 @@ impl View for LaunchConfigSaveModal { "Type the name of the file to which you want to save your current configuration of windows, tabs, and panes. Use enter to save the launch configuration, esc to quit the save configuration modal.", - WarpA11yRole::PopoverRole, + GalaxyA11yRole::PopoverRole, )) } } diff --git a/app/src/lib.rs b/app/src/lib.rs index 5ff1b247..aaa168f2 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -93,7 +93,7 @@ mod view_components; mod vim_registers; mod voice; mod voltron; -mod warp_managed_paths_watcher; +mod galaxy_managed_paths_watcher; #[cfg(target_family = "wasm")] mod wasm_nux_dialog; mod window_settings; @@ -241,9 +241,9 @@ use crate::terminal::resizable_data::ResizableData; use crate::terminal::view::inline_banner::ByoLlmAuthBannerSessionState; use crate::terminal::{AudibleBell, History}; use crate::undo_close::UndoCloseStack; -use crate::user_config::WarpConfig; +use crate::user_config::GalaxyConfig; use crate::vim_registers::VimRegisters; -use crate::warp_managed_paths_watcher::{ensure_warp_watch_roots_exist, WarpManagedPathsWatcher}; +use crate::galaxy_managed_paths_watcher::{ensure_galaxy_watch_roots_exist, GalaxyManagedPathsWatcher}; use crate::workflows::aliases::WorkflowAliases; use crate::workflows::local_workflows::LocalWorkflows; use crate::workspace::{ActiveSession, OneTimeModalModel, ToastStack}; @@ -347,7 +347,7 @@ pub enum LaunchMode { /// Run the regular GUI application. App { args: galaxy_cli::AppArgs, - /// API key for server authentication, if provided via `--api-key` or `WARP_API_KEY`. + /// API key for server authentication, if provided via `--api-key` or `GALAXY_API_KEY`. /// Only used on dogfood channels. api_key: Option, }, @@ -996,14 +996,14 @@ fn initialize_app( // One-time migration: give Preview its own config directory by // symlinking contents from the shared ~/.warp location. Must run - // before ensure_warp_watch_roots_exist() creates the new directory. + // before ensure_galaxy_watch_roots_exist() creates the new directory. #[cfg(target_os = "macos")] preview_config_migration::migrate_preview_config_dir_if_needed(); - ensure_warp_watch_roots_exist(); - ctx.add_singleton_model(WarpManagedPathsWatcher::new); + ensure_galaxy_watch_roots_exist(); + ctx.add_singleton_model(GalaxyManagedPathsWatcher::new); - ctx.add_singleton_model(WarpConfig::new); + ctx.add_singleton_model(GalaxyConfig::new); ctx.add_singleton_model(|_ctx| SettingsManager::default()); let user_defaults_on_startup = settings::init(startup_toml_parse_error, ctx); @@ -2443,7 +2443,7 @@ pub 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")] @@ -2657,7 +2657,7 @@ pub fn enabled_features() -> HashSet { #[cfg(feature = "agent_view_block_context")] FeatureFlag::AgentViewBlockContext, #[cfg(feature = "galaxy_managed_secrets")] - FeatureFlag::WarpManagedSecrets, + FeatureFlag::GalaxyManagedSecrets, #[cfg(feature = "v4a_file_diffs")] FeatureFlag::V4AFileDiffs, #[cfg(feature = "interactive_conversation_management_view")] diff --git a/app/src/menu.rs b/app/src/menu.rs index 790643d7..81c16cca 100644 --- a/app/src/menu.rs +++ b/app/src/menu.rs @@ -15,7 +15,7 @@ use galaxyui::elements::{ }; use galaxyui::WindowId; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, elements::{ Align, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, DispatchEventResult, Element, EventHandler, Flex, Hoverable, Icon, MainAxisAlignment, @@ -2342,28 +2342,28 @@ impl SubMenu { Custom(AccessibilityContent::new( menu_item, instructions, - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) } OpenSubmenu => Custom(AccessibilityContent::new( String::from("Submenu Expanded"), "Press the right key to open the selected submenu", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), CloseSubmenu(_) => Custom(AccessibilityContent::new( String::from("Submenu Closed"), "Removing focus from a submenu will close the submenu", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), Close(_) => Custom(AccessibilityContent::new( String::from("Menu Closed"), "Press the escape key to close the menu", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), Enter => Custom(AccessibilityContent::new( String::from("Action Selected"), "Press the enter key to execute the selected menu item action", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), HoverSubmenuLeafNode { .. } | UnhoverSubmenuParent(_) diff --git a/app/src/notebooks/editor/find_bar.rs b/app/src/notebooks/editor/find_bar.rs index 79fceb67..ee5486d9 100644 --- a/app/src/notebooks/editor/find_bar.rs +++ b/app/src/notebooks/editor/find_bar.rs @@ -6,7 +6,7 @@ use galaxy_editor::{ search::{SearchEvent, Searcher}, }; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, elements::{ Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, MouseStateHandle, OffsetPositioning, ParentElement, PositionedElementAnchor, @@ -565,7 +565,7 @@ impl TypedActionView for FindBar { }; Some(AccessibilityContent::new_without_help( text, - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) .into() } diff --git a/app/src/notebooks/editor/model.rs b/app/src/notebooks/editor/model.rs index 10cdffd6..4eab74ff 100644 --- a/app/src/notebooks/editor/model.rs +++ b/app/src/notebooks/editor/model.rs @@ -2,7 +2,7 @@ use base64::{prelude::BASE64_STANDARD, Engine as _}; use std::{any::Any, borrow::Cow, collections::HashMap, ops::Range, time::Duration}; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, clipboard::ClipboardContent, AppContext, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity, WindowId, }; @@ -1289,7 +1289,7 @@ impl NotebooksEditorModel { if let Some(command) = child_model.executable_command(ctx) { ctx.emit_a11y_content(AccessibilityContent::new_without_help( format!("Selected workflow: {command}"), - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )); } @@ -1650,7 +1650,7 @@ impl NotebooksEditorModel { let text = format!("{style:?} {action}"); ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( text, - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } diff --git a/app/src/notebooks/editor/omnibar.rs b/app/src/notebooks/editor/omnibar.rs index b09fa2d2..33f7aa6e 100644 --- a/app/src/notebooks/editor/omnibar.rs +++ b/app/src/notebooks/editor/omnibar.rs @@ -10,7 +10,7 @@ use galaxy_editor::{ render::model::RenderState, }; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, elements::{ AnchorPair, Border, ConstrainedBox, Container, CornerRadius, DropShadow, Flex, MainAxisSize, MouseStateHandle, OffsetPositioning, OffsetType, ParentElement, Point, @@ -447,12 +447,12 @@ impl TypedActionView for Omnibar { OmnibarAction::ConvertBlock(style) => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Convert to {}", BlockType::from(style).label()), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } OmnibarAction::OpenLinkEditor => ActionAccessibilityContent::from_debug(), OmnibarAction::UnstyleLink => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Remove link", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Remove link", GalaxyA11yRole::UserAction), ), } } diff --git a/app/src/notebooks/editor/view.rs b/app/src/notebooks/editor/view.rs index c3f0da9d..28c8e30c 100644 --- a/app/src/notebooks/editor/view.rs +++ b/app/src/notebooks/editor/view.rs @@ -28,7 +28,7 @@ use string_offset::CharOffset; use galaxy_util::{path::LineAndColumnArg, user_input::UserInput}; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, assets::asset_cache::{AssetCache, AssetHandle, AssetState}, clipboard::ClipboardContent, elements::{ @@ -2440,7 +2440,7 @@ impl RichTextEditorView { if show_open_in_warp { let path_for_warp = path.clone(); links.push(TooltipLink { - text: "Open in Warp".to_string(), + text: "Open in Galaxy".to_string(), on_click: Box::new(move |ctx: &mut EventContext| { ctx.dispatch_typed_action(EditorViewAction::OpenFile { path: path_for_warp.clone(), @@ -3015,13 +3015,13 @@ impl TypedActionView for RichTextEditorView { EditorViewAction::UserTyped(text) => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( text.clone().into_inner(), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::Paste | EditorViewAction::MiddleClickPaste => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Pasting: {}", ctx.clipboard().read().plain_text), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::Enter @@ -3034,21 +3034,21 @@ impl TypedActionView for RichTextEditorView { | EditorViewAction::Unindent | EditorViewAction::Tab => ActionAccessibilityContent::from_debug(), EditorViewAction::ShiftTab => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Shift-tab", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Shift-tab", GalaxyA11yRole::UserAction), ), EditorViewAction::EditLink | EditorViewAction::CreateOrEditLink => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Edit Link", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::CopyLink => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Copy Link", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Copy Link", GalaxyA11yRole::UserAction), ), EditorViewAction::OpenTooltipLink(link) => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Open link: {}", **link), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::SecondaryLinkAction(link) => { @@ -3058,72 +3058,72 @@ impl TypedActionView for RichTextEditorView { ); ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( content, - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::DeleteLineLeft => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Delete line left", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::DeleteLineRight => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Delete line right", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::DeleteWordLeft => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Delete word left", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::DeleteWordRight => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Delete word right", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::CutLineLeft => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Cut line left", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Cut line left", GalaxyA11yRole::UserAction), ), EditorViewAction::CutLineRight => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Cut line right", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Cut line right", GalaxyA11yRole::UserAction), ), EditorViewAction::CutWordLeft => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Cut word left", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Cut word left", GalaxyA11yRole::UserAction), ), EditorViewAction::CutWordRight => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Cut word right", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Cut word right", GalaxyA11yRole::UserAction), ), EditorViewAction::ShowCharacterPalette => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Show character palette", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::ShowFindBar => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Show find bar", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Show find bar", GalaxyA11yRole::UserAction), ), EditorViewAction::OpenBlockInsertionMenu => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Open block-insertion menu", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::OpenEmbeddedObjectSearch => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Open embedded object search menu", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::InsertBlock(block_type) => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Insert {} block", BlockType::from(block_type).label()), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::Bold => self @@ -3150,23 +3150,23 @@ impl TypedActionView for RichTextEditorView { ActionAccessibilityContent::Custom(AccessibilityContent::new( "De-select command", "Switch from selecting commands to selecting text", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::CodeBlockTypeSelectedAtOffset { code_block_type, .. } => ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Change code block language to {code_block_type}"), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )), EditorViewAction::CopyTextToClipboard { .. } => ActionAccessibilityContent::Custom( - AccessibilityContent::new_without_help("Copy code block", WarpA11yRole::UserAction), + AccessibilityContent::new_without_help("Copy code block", GalaxyA11yRole::UserAction), ), EditorViewAction::ToggleTaskList(_) => { // TODO(ben): Is it useful to include the text and/or on/off state here? ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Toggle task list", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } EditorViewAction::Delete diff --git a/app/src/notebooks/file/mod.rs b/app/src/notebooks/file/mod.rs index 6b09d1b0..69146eb3 100644 --- a/app/src/notebooks/file/mod.rs +++ b/app/src/notebooks/file/mod.rs @@ -8,7 +8,7 @@ use galaxy_util::path::user_friendly_path; #[cfg(feature = "local_fs")] use galaxyui::clipboard::ClipboardContent; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ Align, Container, CrossAxisAlignment, DispatchEventResult, Empty, EventHandler, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, SavePosition, Shrinkable, @@ -810,7 +810,7 @@ impl View for FileNotebookView { fn accessibility_contents(&self, _ctx: &AppContext) -> Option { Some(AccessibilityContent::new_without_help( format!("{} notebook", self.title()), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) } diff --git a/app/src/notebooks/link.rs b/app/src/notebooks/link.rs index 2a7b72d1..446a0af9 100644 --- a/app/src/notebooks/link.rs +++ b/app/src/notebooks/link.rs @@ -21,7 +21,7 @@ use crate::util::file::external_editor::EditorSettings; #[cfg(feature = "local_fs")] use crate::util::openable_file_type::{is_supported_image_file, resolve_file_target, FileTarget}; use crate::{ - drive::OpenWarpDriveObjectArgs, + drive::OpenGalaxyDriveObjectArgs, terminal::model::session::Session, uri::parse_url_paths::{get_item_data_from_warp_link, WarpWebLink}, workspace::ActiveSession, @@ -266,7 +266,7 @@ impl NotebookLinks { match link { LinkTarget::Url(url) => { if let Some(WarpWebLink::DriveObject(args)) = get_item_data_from_warp_link(&url) { - return ctx.emit(LinkEvent::OpenWarpDriveLink { + return ctx.emit(LinkEvent::OpenGalaxyDriveLink { open_warp_drive_args: *args, }); } @@ -409,8 +409,8 @@ pub enum LinkEvent { path: PathBuf, session: Arc, }, - OpenWarpDriveLink { - open_warp_drive_args: OpenWarpDriveObjectArgs, + OpenGalaxyDriveLink { + open_warp_drive_args: OpenGalaxyDriveObjectArgs, }, /// This event tells the parent pane group to open a new terminal session in the given /// directory. diff --git a/app/src/notebooks/manager.rs b/app/src/notebooks/manager.rs index aca3c310..52efee6d 100644 --- a/app/src/notebooks/manager.rs +++ b/app/src/notebooks/manager.rs @@ -13,7 +13,7 @@ use crate::{ model::persistence::{CloudModel, CloudModelEvent}, Owner, }, - drive::OpenWarpDriveObjectSettings, + drive::OpenGalaxyDriveObjectSettings, pane_group::{NotebookPane, PaneContent}, safe_debug, safe_warn, server::{ @@ -182,7 +182,7 @@ impl NotebookManager { pub fn create_pane( &mut self, source: &NotebookSource, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, window_id: WindowId, ctx: &mut ModelContext, ) -> NotebookPane { diff --git a/app/src/notebooks/notebook.rs b/app/src/notebooks/notebook.rs index e6d5379c..2b105113 100644 --- a/app/src/notebooks/notebook.rs +++ b/app/src/notebooks/notebook.rs @@ -16,7 +16,7 @@ use galaxy_editor::{ model::{CoreEditorModel, RichTextEditorModel}, }; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, clipboard::ClipboardContent, elements::{ Align, Clipped, ConstrainedBox, Container, CrossAxisAlignment, DispatchEventResult, Empty, @@ -52,7 +52,7 @@ use crate::{ drive::{ drive_helpers::has_feature_gated_anonymous_user_reached_notebook_limit, export::ExportManager, items::WarpDriveItemId, sharing::ShareableObject, - CloudObjectTypeAndId, OpenWarpDriveObjectSettings, + CloudObjectTypeAndId, OpenGalaxyDriveObjectSettings, }, editor::{ EditOrigin, EditorView, Event as EditorEvent, InteractionState, @@ -1522,7 +1522,7 @@ impl NotebookView { pub fn wait_for_initial_load_then_load( &mut self, notebook_id: SyncId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, window_id: WindowId, ctx: &mut ViewContext, ) { @@ -1561,7 +1561,7 @@ impl NotebookView { fn fetch_and_load_notebook( &mut self, notebook_id: ServerId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, window_id: WindowId, ctx: &mut ViewContext, ) { @@ -1605,7 +1605,7 @@ impl NotebookView { pub fn load( &mut self, notebook: CloudNotebook, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) -> SpawnedFutureHandle { self.set_title(¬ebook.model().title, ctx); @@ -1868,7 +1868,7 @@ impl NotebookView { if let Some(notebook) = CloudModel::as_ref(ctx).get_notebook(&id) { self.load( notebook.clone(), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, ); } @@ -2185,7 +2185,7 @@ impl View for NotebookView { fn accessibility_contents(&self, ctx: &AppContext) -> Option { Some(AccessibilityContent::new_without_help( format!("{} notebook", self.title(ctx)), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) } diff --git a/app/src/notebooks/notebook_tests.rs b/app/src/notebooks/notebook_tests.rs index e4c173ef..03694234 100644 --- a/app/src/notebooks/notebook_tests.rs +++ b/app/src/notebooks/notebook_tests.rs @@ -25,7 +25,7 @@ use crate::{ }, Owner, Revision, ServerCloudObject, ServerMetadata, ServerNotebook, ServerPermissions, }, - drive::OpenWarpDriveObjectSettings, + drive::OpenGalaxyDriveObjectSettings, editor::{DisplayPoint, EditorAction, InteractionState, SelectAction}, network::NetworkStatus, notebooks::{ @@ -140,7 +140,7 @@ fn open_notebook( notebook: CloudNotebook, ) -> BoxFuture<'static, ()> { let load_future = handle.update(app, |view, ctx| { - view.load(notebook, &OpenWarpDriveObjectSettings::default(), ctx) + view.load(notebook, &OpenGalaxyDriveObjectSettings::default(), ctx) }); app.update(|ctx| ctx.await_spawned_future(load_future.future_id())) } diff --git a/app/src/pane_group/mod.rs b/app/src/pane_group/mod.rs index 7c5bd465..1ccc872c 100644 --- a/app/src/pane_group/mod.rs +++ b/app/src/pane_group/mod.rs @@ -113,7 +113,7 @@ use crate::banner::{Banner, BannerEvent, BannerState, BannerTextContent, Dismiss use crate::channel::{Channel, ChannelState}; use crate::code::view::CodeView; use crate::drive::items::WarpDriveItemId; -use crate::drive::{CloudObjectTypeAndId, OpenWarpDriveObjectArgs}; +use crate::drive::{CloudObjectTypeAndId, OpenGalaxyDriveObjectArgs}; use crate::features::FeatureFlag; use crate::launch_configs::launch_config::{self, PaneMode, PaneTemplateType}; use crate::persistence::ModelEvent; @@ -522,8 +522,8 @@ pub enum Event { /// The session that the path was opened from. session: Arc, }, - OpenWarpDriveLink { - open_warp_drive_args: OpenWarpDriveObjectArgs, + OpenGalaxyDriveLink { + open_warp_drive_args: OpenGalaxyDriveObjectArgs, }, #[cfg(feature = "local_fs")] OpenCodeInWarp { @@ -598,7 +598,7 @@ pub enum Event { }, /// Clears the hovered tab index so it no longer appears as highlighted drop target ClearHoveredTabIndex, - OpenWarpDriveObjectInPane(ObjectUid), + OpenGalaxyDriveObjectInPane(ObjectUid), OpenSuggestedAgentModeWorkflowModal { workflow_and_id: SuggestedAgentModeWorkflowAndId, }, diff --git a/app/src/pane_group/mod_tests.rs b/app/src/pane_group/mod_tests.rs index c193ece9..5d1db777 100644 --- a/app/src/pane_group/mod_tests.rs +++ b/app/src/pane_group/mod_tests.rs @@ -49,7 +49,7 @@ use crate::{ }, test_util::settings::initialize_settings_for_tests, undo_close::UndoCloseStack, - warp_managed_paths_watcher::WarpManagedPathsWatcher, + galaxy_managed_paths_watcher::GalaxyManagedPathsWatcher, workflows::local_workflows::LocalWorkflows, workspace::{ sync_inputs::SyncedInputState, ActiveSession, OneTimeModalModel, WorkspaceRegistry, @@ -102,7 +102,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); app.add_singleton_model(FileMCPWatcher::new); app.add_singleton_model(|_| FileBasedMCPManager::default()); diff --git a/app/src/pane_group/pane/notebook_pane.rs b/app/src/pane_group/pane/notebook_pane.rs index d673e67f..12f3c68c 100644 --- a/app/src/pane_group/pane/notebook_pane.rs +++ b/app/src/pane_group/pane/notebook_pane.rs @@ -7,7 +7,7 @@ use galaxyui::{AppContext, ModelHandle, SingletonEntity, ViewContext, ViewHandle use crate::{ app_state::{LeafContents, NotebookPaneSnapshot}, cloud_object::Space, - drive::{items::WarpDriveItemId, CloudObjectTypeAndId, OpenWarpDriveObjectSettings}, + drive::{items::WarpDriveItemId, CloudObjectTypeAndId, OpenGalaxyDriveObjectSettings}, notebooks::{ link::{LinkEvent, NotebookLinks}, manager::{NotebookManager, NotebookSource}, @@ -47,7 +47,7 @@ impl NotebookPane { /// Restore a notebook pane given its cloud notebook ID. pub fn restore( notebook_id: Option, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) -> anyhow::Result { let window_id = ctx.window_id(); @@ -81,7 +81,7 @@ impl PaneContent for NotebookPane { let notebook_id = self.notebook_view(app).as_ref(app).notebook_id(app); LeafContents::Notebook(NotebookPaneSnapshot::CloudNotebook { notebook_id, - settings: OpenWarpDriveObjectSettings::default(), + settings: OpenGalaxyDriveObjectSettings::default(), }) } @@ -183,9 +183,9 @@ pub(super) fn subscribe_to_link_model( session: session.clone(), }) } - LinkEvent::OpenWarpDriveLink { + LinkEvent::OpenGalaxyDriveLink { open_warp_drive_args, - } => ctx.emit(crate::pane_group::Event::OpenWarpDriveLink { + } => ctx.emit(crate::pane_group::Event::OpenGalaxyDriveLink { open_warp_drive_args: open_warp_drive_args.clone(), }), LinkEvent::StartLocalSession { path } => { diff --git a/app/src/pane_group/pane/terminal_pane.rs b/app/src/pane_group/pane/terminal_pane.rs index fdaa1c52..6e6defce 100644 --- a/app/src/pane_group/pane/terminal_pane.rs +++ b/app/src/pane_group/pane/terminal_pane.rs @@ -902,8 +902,8 @@ fn handle_terminal_view_event( Event::RoleRequestCancelled(role_request_id) => { group.remove_shared_session_role_request(role_request_id.clone(), ctx); } - Event::OpenWarpDriveObjectInPane(uid) => { - ctx.emit(pane_group::Event::OpenWarpDriveObjectInPane(uid.clone())); + Event::OpenGalaxyDriveObjectInPane(uid) => { + ctx.emit(pane_group::Event::OpenGalaxyDriveObjectInPane(uid.clone())); } Event::OpenSuggestedAgentModeWorkflowModal { workflow_and_id } => { ctx.emit(pane_group::Event::OpenSuggestedAgentModeWorkflowModal { diff --git a/app/src/pane_group/pane/workflow_pane.rs b/app/src/pane_group/pane/workflow_pane.rs index c332ade0..58aadfe4 100644 --- a/app/src/pane_group/pane/workflow_pane.rs +++ b/app/src/pane_group/pane/workflow_pane.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{ app_state::{LeafContents, WorkflowPaneSnapshot}, - drive::{items::WarpDriveItemId, OpenWarpDriveObjectSettings}, + drive::{items::WarpDriveItemId, OpenGalaxyDriveObjectSettings}, server::ids::SyncId, workflows::{ manager::{WorkflowManager, WorkflowOpenSource}, @@ -39,7 +39,7 @@ impl WorkflowPane { pub fn restore( workflow_id: Option, - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) -> anyhow::Result { let window_id = ctx.window_id(); @@ -132,7 +132,7 @@ impl PaneContent for WorkflowPane { let workflow_id = self.get_view(app).as_ref(app).workflow_id(); LeafContents::Workflow(WorkflowPaneSnapshot::CloudWorkflow { workflow_id: Some(workflow_id), - settings: OpenWarpDriveObjectSettings::default(), + settings: OpenGalaxyDriveObjectSettings::default(), }) } diff --git a/app/src/pane_group/tree.rs b/app/src/pane_group/tree.rs index 8f998e54..5a13e3db 100644 --- a/app/src/pane_group/tree.rs +++ b/app/src/pane_group/tree.rs @@ -20,7 +20,7 @@ use std::{fmt, iter, mem}; use super::{ActivationReason, PaneGroup, PaneId}; use crate::pane_group::{get_minimum_pane_size, DraggedBorder, PaneGroupAction}; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use galaxy_core::features::FeatureFlag; #[cfg(test)] @@ -492,7 +492,7 @@ impl PaneData { self.len == 0 } - pub fn render(&self, theme: &WarpTheme, app: &AppContext) -> Box { + pub fn render(&self, theme: &GalaxyTheme, app: &AppContext) -> Box { match &self.root { PaneNode::Leaf(pane) => pane.render(app), PaneNode::Branch(node) => node.render(theme, &self.hidden_panes, app), @@ -694,7 +694,7 @@ impl PaneNode { fn render( &self, - theme: &WarpTheme, + theme: &GalaxyTheme, hidden_panes: &Vec, app: &AppContext, ) -> Box { @@ -1023,7 +1023,7 @@ impl PaneBranch { fn render( &self, - theme: &WarpTheme, + theme: &GalaxyTheme, hidden_panes: &Vec, app: &AppContext, ) -> Box { @@ -1355,7 +1355,7 @@ fn create_divider_placeholder(direction: SplitDirection, position_id: &str) -> B fn create_divider( direction: SplitDirection, item: &Divider, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let divider = ConstrainedBox::new( Rect::new() @@ -1393,7 +1393,7 @@ fn create_divider( fn create_minimalist_divider( direction: SplitDirection, item: &Divider, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let divider = ConstrainedBox::new( Rect::new() diff --git a/app/src/persistence/sqlite.rs b/app/src/persistence/sqlite.rs index f695f7a0..57fb8094 100644 --- a/app/src/persistence/sqlite.rs +++ b/app/src/persistence/sqlite.rs @@ -86,7 +86,7 @@ use crate::cloud_object::{ }; use crate::code::editor_management::CodeSource; use crate::drive::folders::{CloudFolder, CloudFolderModel, FolderId}; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::env_vars::{CloudEnvVarCollection, CloudEnvVarCollectionModel}; use crate::features::FeatureFlag; use crate::notebooks::{CloudNotebook, NotebookId}; @@ -2519,7 +2519,7 @@ fn read_node(conn: &mut SqliteConnection, node: model::PaneNode) -> Result NotebookPaneSnapshot::LocalFileNotebook { path: Some(path) }, None => NotebookPaneSnapshot::CloudNotebook { notebook_id, - settings: OpenWarpDriveObjectSettings::default(), + settings: OpenGalaxyDriveObjectSettings::default(), }, }) } @@ -2537,7 +2537,7 @@ fn read_node(conn: &mut SqliteConnection, node: model::PaneNode) -> Result { diff --git a/app/src/platform/wasm.rs b/app/src/platform/wasm.rs index f0e0bdd7..ed682dcc 100644 --- a/app/src/platform/wasm.rs +++ b/app/src/platform/wasm.rs @@ -2,7 +2,7 @@ use js_sys::ReferenceError; use thiserror::Error; use wasm_bindgen::{JsCast, JsValue}; -pub use galaxy_web_event_bus::{emit_event, WarpEvent}; +pub use galaxy_web_event_bus::{emit_event, GalaxyEvent}; /// This function should be called early in application initialization to ensure that /// static variables are initialized. diff --git a/app/src/preview_config_migration.rs b/app/src/preview_config_migration.rs index cbbc60cf..aee9eefd 100644 --- a/app/src/preview_config_migration.rs +++ b/app/src/preview_config_migration.rs @@ -56,7 +56,7 @@ pub(crate) fn migrate_config_dir_via_symlinks(old_dir: &Path, new_dir: &Path) { // The existence of new_dir is the migration marker — no separate marker // file is needed. Once this directory exists (whether created by the - // migration itself or by ensure_warp_watch_roots_exist on a subsequent + // migration itself or by ensure_galaxy_watch_roots_exist on a subsequent // launch), this function is a no-op. if new_dir.exists() || !old_dir.exists() { return; diff --git a/app/src/resource_center/mod.rs b/app/src/resource_center/mod.rs index cecfdfb1..a9cdf990 100644 --- a/app/src/resource_center/mod.rs +++ b/app/src/resource_center/mod.rs @@ -92,7 +92,7 @@ pub enum TipAction { WarpAI, // This toggles Warp Drive rather than opening it. This enum can't directly be // renamed because we serialize it into the welcome tips. - OpenWarpDrive, + OpenGalaxyDrive, Changelog, // Note that this item has been deprecated from the UI and is not in any section. // We are leaving it in this enum to ensure that we don't re-use `Workflows` as a @@ -112,7 +112,7 @@ impl TipAction { TipAction::ThemePicker => "workspace:show_theme_chooser", TipAction::SaveNewLaunchConfig => "workspace:open_launch_config_save_modal", TipAction::WarpAI => "workspace:toggle_ai_assistant", - TipAction::OpenWarpDrive => "workspace:toggle_left_panel", + TipAction::OpenGalaxyDrive => "workspace:toggle_left_panel", // Slash commands are also registered as editable bindings, so callers can look them up here // the same way they do regular app actions. TipAction::Changelog => "/changelog", diff --git a/app/src/reward_view.rs b/app/src/reward_view.rs index 72ba73c9..812b5188 100644 --- a/app/src/reward_view.rs +++ b/app/src/reward_view.rs @@ -1,6 +1,6 @@ use galaxy_core::ui::builder::UiBuilder; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{Align, Container, Element, Flex, MouseStateHandle, ParentElement}, keymap::FixedBinding, ui_components::button::ButtonVariant, @@ -186,7 +186,7 @@ impl View for RewardView { Some(AccessibilityContent::new( format!("{} {}", TITLE, self.subtitle()), ACCESSIBILITY_HELP, - WarpA11yRole::WindowRole, + GalaxyA11yRole::WindowRole, )) } diff --git a/app/src/root_view.rs b/app/src/root_view.rs index d5960f34..1c12aaa3 100644 --- a/app/src/root_view.rs +++ b/app/src/root_view.rs @@ -14,7 +14,7 @@ use crate::cloud_object::model::persistence::CloudModel; use crate::cloud_object::{GenericStringObjectFormat, JsonObjectType, ObjectType}; use crate::drive::export::ExportManager; use crate::drive::items::WarpDriveItemId; -use crate::drive::{CloudObjectTypeAndId, OpenWarpDriveObjectArgs, OpenWarpDriveObjectSettings}; +use crate::drive::{CloudObjectTypeAndId, OpenGalaxyDriveObjectArgs, OpenGalaxyDriveObjectSettings}; use crate::experiments::{BlockOnboarding, Experiment}; use crate::interval_timer::IntervalTimer; use crate::launch_configs::launch_config; @@ -49,7 +49,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, ThemeKind, GalaxyThemeConfig}; use crate::uri::OpenMCPSettingsArgs; use crate::util::bindings::{self, is_binding_pty_compliant}; use crate::util::traffic_lights::{traffic_light_data, TrafficLightData, TrafficLightMouseStates}; @@ -1133,7 +1133,7 @@ fn open_linear_issue_work_in_new_window(args: &LinearIssueWork, ctx: &mut AppCon }); } -fn open_warp_drive_object(arg: &OpenWarpDriveObjectArgs, ctx: &mut AppContext) { +fn open_warp_drive_object(arg: &OpenGalaxyDriveObjectArgs, ctx: &mut AppContext) { match arg.object_type { ObjectType::Notebook => open_new_workspace_with_notebook_open( SyncId::ServerId(arg.server_id), @@ -1158,7 +1158,7 @@ fn display_object_missing_error_in_window(window_id: WindowId, ctx: &mut AppCont fn open_new_workspace_with_notebook_open( notebook_id: SyncId, - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, ctx: &mut AppContext, ) { open_new_with_workspace_source( @@ -1172,7 +1172,7 @@ fn open_new_workspace_with_notebook_open( fn open_new_workspace_with_workflow_open( workflow_id: SyncId, - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, ctx: &mut AppContext, ) { open_new_with_workspace_source( @@ -1583,11 +1583,11 @@ pub enum NewWorkspaceSource { }, NotebookById { id: SyncId, - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, }, WorkflowById { id: SyncId, - settings: OpenWarpDriveObjectSettings, + settings: OpenGalaxyDriveObjectSettings, }, AgentSession { options: Box, @@ -2153,7 +2153,7 @@ impl RootView { } fn onboarding_theme_kind(theme_name: &str) -> Option { - WarpThemeConfig::new() + GalaxyThemeConfig::new() .theme_items() .find_map(|(kind, theme)| { (theme.name().as_deref() == Some(theme_name)).then(|| kind.clone()) @@ -2593,7 +2593,7 @@ impl RootView { pub fn open_warp_drive_object_in_existing_window( &mut self, - arg: &OpenWarpDriveObjectArgs, + arg: &OpenGalaxyDriveObjectArgs, ctx: &mut ViewContext, ) -> bool { if let AuthOnboardingState::Terminal(handle) = &self.auth_onboarding_state { @@ -2856,7 +2856,7 @@ impl RootView { ctx.dispatch_typed_action_for_view( window_id, handle.id(), - &WorkspaceAction::OpenWarpDrive, + &WorkspaceAction::OpenGalaxyDrive, ); ctx.windows().show_window_and_focus_app(window_id); } else { diff --git a/app/src/search/command_palette/filter_chip_renderer.rs b/app/src/search/command_palette/filter_chip_renderer.rs index 64b636af..d4d742df 100644 --- a/app/src/search/command_palette/filter_chip_renderer.rs +++ b/app/src/search/command_palette/filter_chip_renderer.rs @@ -146,7 +146,7 @@ impl FilterChipRenderer for QueryFilter { } mod styles { - use crate::themes::theme::{Blend, Fill, WarpTheme}; + use crate::themes::theme::{Blend, Fill, GalaxyTheme}; use galaxyui::elements::{Border, MouseState}; /// Size of the border when the query filter is hovered. @@ -181,7 +181,7 @@ mod styles { } /// Returns the border that should be applied to the query filter. - pub fn border(mouse_state: &MouseState, theme: &WarpTheme) -> Border { + pub fn border(mouse_state: &MouseState, theme: &GalaxyTheme) -> Border { if mouse_state.is_hovered() { Border::all(HOVERED_BORDER_SIZE).with_border_fill(theme.accent()) } else { @@ -190,7 +190,7 @@ mod styles { } /// Returns the background [`Fill`] that should be applied to the query filter. - pub fn background_fill(mouse_state: &MouseState, theme: &WarpTheme) -> Fill { + pub fn background_fill(mouse_state: &MouseState, theme: &GalaxyTheme) -> Fill { if mouse_state.is_hovered() { theme .surface_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 8566c746..38418947 100644 --- a/app/src/search/command_palette/launch_config/data_source.rs +++ b/app/src/search/command_palette/launch_config/data_source.rs @@ -3,7 +3,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}; use fuzzy_match::match_indices_case_insensitive; use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity}; use std::collections::HashMap; @@ -30,7 +30,7 @@ impl DataSource { } fn new_fuzzy(ctx: &mut ModelContext) -> Self { - ctx.subscribe_to_model(&WarpConfig::handle(ctx), Self::handle_config_event); + ctx.subscribe_to_model(&GalaxyConfig::handle(ctx), Self::handle_config_event); let mut searcher = Box::new(FuzzyLaunchConfigSearcher::default()); searcher.refresh_search_index(ctx); Self { searcher } @@ -38,7 +38,7 @@ impl DataSource { #[cfg(not(target_family = "wasm"))] fn new_full_text(ctx: &mut ModelContext) -> Self { - ctx.subscribe_to_model(&WarpConfig::handle(ctx), Self::handle_config_event); + ctx.subscribe_to_model(&GalaxyConfig::handle(ctx), Self::handle_config_event); let mut searcher = Box::new(full_text_searcher::FullTextLaunchConfigSearcher::new( ctx.background_executor(), )); @@ -46,8 +46,8 @@ impl DataSource { Self { searcher } } - fn handle_config_event(&mut self, event: &WarpConfigUpdateEvent, ctx: &mut ModelContext) { - if matches!(event, WarpConfigUpdateEvent::LaunchConfigs) { + fn handle_config_event(&mut self, event: &GalaxyConfigUpdateEvent, ctx: &mut ModelContext) { + if matches!(event, GalaxyConfigUpdateEvent::LaunchConfigs) { self.searcher.refresh_search_index(ctx); } } @@ -107,7 +107,7 @@ impl LaunchConfigSearcher for FuzzyLaunchConfigSearcher { } fn refresh_search_index(&mut self, app: &AppContext) { - self.configs = WarpConfig::as_ref(app) + self.configs = GalaxyConfig::as_ref(app) .launch_configs() .iter() .map(|config| (config.name.to_lowercase(), config.clone())) @@ -122,7 +122,7 @@ mod full_text_searcher { 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; use fuzzy_match::FuzzyMatchResult; use galaxyui::r#async::executor::Background; use galaxyui::{AppContext, SingletonEntity}; @@ -180,7 +180,7 @@ mod full_text_searcher { } fn refresh_search_index(&mut self, app: &AppContext) { - self.configs = WarpConfig::as_ref(app) + self.configs = GalaxyConfig::as_ref(app) .launch_configs() .iter() .map(|config| (config.name.to_lowercase(), config.clone())) diff --git a/app/src/search/command_palette/view.rs b/app/src/search/command_palette/view.rs index 95eb5adb..4b29c319 100644 --- a/app/src/search/command_palette/view.rs +++ b/app/src/search/command_palette/view.rs @@ -12,7 +12,7 @@ use crate::server::telemetry::LaunchConfigUiLocation; use crate::server::telemetry::TelemetryEvent; 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::ToastStack; use galaxy_core::send_telemetry_from_app_ctx; @@ -695,7 +695,7 @@ impl View { }) } - fn render_palette_list(&self, theme: &WarpTheme, app: &AppContext) -> Box { + fn render_palette_list(&self, theme: &GalaxyTheme, app: &AppContext) -> Box { match self.search_bar_state.as_ref(app).query_result_renderers() { None => Empty::new().finish(), Some(renderers) if renderers.is_empty() => { diff --git a/app/src/search/command_search/view.rs b/app/src/search/command_search/view.rs index efa1d770..a946fe8d 100644 --- a/app/src/search/command_search/view.rs +++ b/app/src/search/command_search/view.rs @@ -7,7 +7,7 @@ use pathfinder_geometry::vector::Vector2F; use crate::search::mixer::AddAsyncSourceOptions; use galaxy_core::features::FeatureFlag; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ resizable_state_handle, Align, AnchorPair, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Fill, Flex, MouseStateHandle, OffsetPositioning, OffsetType, @@ -528,7 +528,7 @@ impl CommandSearchView { ctx.emit_a11y_content(AccessibilityContent::new( a11y_content, a11y_help_content, - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); // Recompute the result index - the incoming index is the index in the @@ -1006,7 +1006,7 @@ impl View for CommandSearchView { Some(AccessibilityContent::new( "Command Search".to_owned(), "Search your history, workflows, and more. Use the Up and Down arrows to browse search results after typing. Press Enter to accept a selected result, inserting it into the terminal input. Press Escape to close.".to_owned(), - WarpA11yRole::MenuRole, + GalaxyA11yRole::MenuRole, )) } 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 9e4a7b04..20c50a9e 100644 --- a/app/src/search/command_search/workflows/workflows_data_source.rs +++ b/app/src/search/command_search/workflows/workflows_data_source.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use crate::completer::SessionContext; use crate::search::command_search::settings::CommandSearchSettings; -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; @@ -35,7 +35,7 @@ impl WorkflowsDataSource { workflows_by_source.insert(WorkflowSource::Global, global_workflows); - let user_workflows = WarpConfig::as_ref(app).local_user_workflows().clone(); + let user_workflows = GalaxyConfig::as_ref(app).local_user_workflows().clone(); workflows_by_source.insert(WorkflowSource::Local, user_workflows); #[cfg(feature = "local_fs")] diff --git a/app/src/search/search_bar.rs b/app/src/search/search_bar.rs index eb691212..f983a8fe 100644 --- a/app/src/search/search_bar.rs +++ b/app/src/search/search_bar.rs @@ -7,7 +7,7 @@ use std::collections::HashSet; use galaxyui::fonts::FamilyId; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{Clipped, Container, CrossAxisAlignment, Flex, ParentElement, Shrinkable, Text}, fonts::{Properties, Style, Weight}, presenter::ChildView, @@ -792,7 +792,7 @@ impl SearchBar { for loading_filter in loading_filters.into_iter() { ctx.emit_a11y_content(AccessibilityContent::new_without_help( format!("Loading {} suggestions", loading_filter.display_name()), - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, )); } @@ -803,7 +803,7 @@ impl SearchBar { ctx.emit_a11y_content(AccessibilityContent::new( "Error finding results", data_source_err.user_facing_error(), - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, )); return; } @@ -813,12 +813,12 @@ impl SearchBar { let a11y_content = match selected_result.accessibility_help_message() { None => AccessibilityContent::new_without_help( a11y_content_text, - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, ), Some(help_message) => AccessibilityContent::new( a11y_content_text, help_message, - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, ), }; ctx.emit_a11y_content(a11y_content); diff --git a/app/src/search/welcome_palette/view.rs b/app/src/search/welcome_palette/view.rs index d90198c8..54f4cfa4 100644 --- a/app/src/search/welcome_palette/view.rs +++ b/app/src/search/welcome_palette/view.rs @@ -48,7 +48,7 @@ use crate::send_telemetry_from_ctx; use crate::server::{ids::SyncId, telemetry::TelemetryEvent}; use crate::settings::AISettings; use crate::terminal::History; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::ui_components::icons::Icon; use crate::workflows::{WorkflowSelectionSource, WorkflowSource, WorkflowType}; use crate::workspace::WorkspaceAction; @@ -625,7 +625,7 @@ impl WelcomePalette { }) } - fn render_palette_list(&self, theme: &WarpTheme, app: &AppContext) -> Box { + fn render_palette_list(&self, theme: &GalaxyTheme, app: &AppContext) -> Box { match self.search_bar_state.as_ref(app).query_result_renderers() { None => { self.placeholder_query_renderer @@ -651,7 +651,7 @@ impl WelcomePalette { &self, renderers: &[QueryResultRenderer], selected_item: SelectedItem, - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> Box { let selected_index = match selected_item { diff --git a/app/src/server/cloud_objects/update_manager.rs b/app/src/server/cloud_objects/update_manager.rs index 61cb28aa..54b130ac 100644 --- a/app/src/server/cloud_objects/update_manager.rs +++ b/app/src/server/cloud_objects/update_manager.rs @@ -4475,8 +4475,27 @@ impl UpdateManager { initiated_by: InitiatedBy, ctx: &mut ModelContext, ) { - // If the object isn't known to the server yet, we can't delete it. + // If the object isn't known to the server yet, delete it locally. let Some(server_id) = id.server_id() else { + let uid = id.uid(); + let sync_ids_and_types = CloudModel::handle(ctx).update(ctx, |cloud_model, ctx| { + let (sync_ids_and_types, _) = cloud_model.delete_objects_by_id(vec![uid], ctx); + sync_ids_and_types + }); + if !sync_ids_and_types.is_empty() { + self.save_to_db([ModelEvent::DeleteObjects { + ids: sync_ids_and_types, + }]); + } + ctx.emit(UpdateManagerEvent::ObjectOperationComplete { + result: ObjectOperationResult { + success_type: OperationSuccessType::Success, + operation: ObjectOperation::Delete { initiated_by }, + client_id: None, + server_id: None, + num_objects: Some(1), + }, + }); return; }; diff --git a/app/src/server/mod.rs b/app/src/server/mod.rs index 9bfec97b..1027de88 100644 --- a/app/src/server/mod.rs +++ b/app/src/server/mod.rs @@ -13,5 +13,3 @@ pub mod sync_queue; pub mod telemetry; pub(crate) mod telemetry_ext; pub mod voice_transcriber; - -pub use galaxy_core::operating_system_info::OperatingSystemInfo; diff --git a/app/src/server/telemetry/collector.rs b/app/src/server/telemetry/collector.rs index c86d12f4..4626a749 100644 --- a/app/src/server/telemetry/collector.rs +++ b/app/src/server/telemetry/collector.rs @@ -1,228 +1,24 @@ use std::sync::Arc; -use std::{fs::remove_file, time::Duration}; -use anyhow::Context; -use chrono::{LocalResult, TimeZone, Utc}; -use galaxy_core::execution_mode::AppExecutionMode; -use galaxy_core::{report_error, report_if_error}; -use galaxyui::r#async::{FutureExt as _, Timer}; -use galaxyui::{App, Entity, ModelContext, SingletonEntity}; +use galaxyui::{Entity, ModelContext, SingletonEntity}; -use super::{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, - settings::{PrivacySettings, PrivacySettingsChangedEvent}, -}; +use crate::server::server_api::ServerApi; -use super::clear_event_queue; - -// 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, + _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, } } - /// Flushes telemetry events when the app is shutting down. - /// - /// Depending on the app's execution mode, this will either: - /// * Write events to disk, for sending on the next app startup - /// * Synchronously send events to rudderstack - pub fn flush_telemetry_events_for_shutdown(&self, ctx: &mut ModelContext) { - let execution_mode = AppExecutionMode::as_ref(ctx); + pub fn initialize_telemetry_collection(&self, _ctx: &mut ModelContext) {} - if execution_mode.send_telemetry_at_shutdown() { - let privacy_settings_snapshot = PrivacySettings::as_ref(ctx).get_snapshot(ctx); - let server_api = self.server_api.clone(); - match galaxyui::r#async::block_on(async move { - server_api - .flush_telemetry_events(privacy_settings_snapshot) - .with_timeout(TELEMETRY_SHUTDOWN_FLUSH_TIMEOUT) - .await - }) { - Ok(Ok(count)) => { - if count > 0 { - log::info!("Successfully flushed telemetry events before shutdown"); - } - } - Ok(Err(e)) => { - report_error!(e.context("Error flushing telemetry events before shutdown")); - } - Err(_) => { - log::warn!( - "Telemetry flush timed out after {}s during shutdown, skipping", - TELEMETRY_SHUTDOWN_FLUSH_TIMEOUT.as_secs() - ); - } - } - } else { - self.write_telemetry_events_to_disk(ctx); - } - } - - /// Sends rudderstack requests containing events persisted to disk (if telemetry is enabled). - /// Events may be written to disk at the end of a session prior to app termination; this - /// function should be called on startup to track events that were recorded at the end of the - /// last session and were not flushed. - fn flush_persisted_events_from_disk(&self, ctx: &mut ModelContext) { - let privacy_settings_snapshot = PrivacySettings::as_ref(ctx).get_snapshot(ctx); - let server_api = self.server_api.clone(); - let _ = ctx.spawn( - async move { - let new_path = rudder_event_file_path(); - let old_path = - galaxy_core::paths::state_dir().join(RUDDER_TELEMETRY_EVENTS_FILE_NAME); - - // Try flushing from both new and legacy locations. - for path in [new_path, old_path] { - report_if_error!(server_api - .flush_persisted_events_to_rudder(&path, privacy_settings_snapshot) - .await - .context("Failed to flush rudder events from disk")); - // Remove the file regardless of outcome of flushing the events to avoid the - // case where we accidentally try to re-flush the events on the next app startup. - if let Err(e) = remove_file(&path) { - if e.kind() != std::io::ErrorKind::NotFound { - galaxy_core::report_error!( - anyhow::anyhow!(e).context("Failed to remove persisted event file") - ); - } - } - } - }, - |_, _, _| (), - ); - } - - /// Schedules a background task to send an active usage event in a rudderstack request if - /// telemetry is enabled. The scheduled task once again schedules itself after - /// `ACTIVE_USAGE_DURATION`. - fn schedule_send_active_usage_event(&self, ctx: &mut ModelContext) { - let auth_state = AuthStateProvider::as_ref(ctx).get().clone(); - let is_telemetry_enabled = PrivacySettings::as_ref(ctx).is_telemetry_enabled; - let _ = ctx.spawn( - async move { - // Record app active if there was any activity now or right after the previous check - let last_active_timestamp = App::last_active_timestamp(); - if is_telemetry_enabled - && last_active_timestamp + ACTIVE_USAGE_DURATION.as_secs() as i64 - > Utc::now().timestamp() - { - if let LocalResult::Single(timestamp) = - Utc.timestamp_opt(last_active_timestamp, 0) - { - galaxyui::telemetry::record_app_active_event( - auth_state.user_id().map(|uid| uid.as_string()), - auth_state.anonymous_id(), - timestamp, - ); - } - } - Timer::after(ACTIVE_USAGE_DURATION).await; - }, - |me, _, ctx| me.schedule_send_active_usage_event(ctx), - ); - } - - /// Flushes events from the in-memory event queue and schedules a background task to send - /// them in rudderstack request if telemetry is enabled. The scheduled task once again schedules - /// itself after `TELEMETRY_FLUSH_DURATION`. - fn schedule_event_queue_flush(&self, ctx: &mut ModelContext) { - let server_api = self.server_api.clone(); - let privacy_settings_snapshot = PrivacySettings::as_ref(ctx).get_snapshot(ctx); - let _ = ctx.spawn( - async move { - match server_api - .flush_telemetry_events(privacy_settings_snapshot) - .await - { - Ok(count) => { - if count > 0 { - log::debug!("Flushed telemetry events."); - } - } - Err(e) => { - log::info!("Failed to flush events from Telemetry queue: {e}"); - } - } - Timer::after(TELEMETRY_FLUSH_DURATION).await; - }, - |me, _, ctx| me.schedule_event_queue_flush(ctx), - ); - } + pub fn flush_telemetry_events_for_shutdown(&self, _ctx: &mut ModelContext) {} } impl Entity for TelemetryCollector { diff --git a/app/src/server/telemetry/context.rs b/app/src/server/telemetry/context.rs index f950b2ab..ce461e54 100644 --- a/app/src/server/telemetry/context.rs +++ b/app/src/server/telemetry/context.rs @@ -1,33 +1,5 @@ -//! 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 super::rudder_message::Message as RudderMessage; -use crate::server::OperatingSystemInfo; - -use serde::Serialize; use serde_json::{json, Value}; -use std::sync::OnceLock; - -#[cfg(target_family = "wasm")] -use galaxyui::platform::wasm; - -static TELEMETRY_CONTEXT: OnceLock = OnceLock::new(); - -#[derive(Serialize)] -struct TelemetryContextInfo { - /// Info about the operating system of the client. - #[serde(skip_serializing_if = "Option::is_none")] - os: Option<&'static OperatingSystemInfo>, - /// The user agent provided by the browser, if running on Web. If not on - /// Web, this is always `None`. - #[serde(rename = "userAgent", skip_serializing_if = "Option::is_none")] - user_agent: Option, -} - -/// Newtype representing a [`Value`] with a serialized version of the context that we send to -/// Rudderstack. -/// See https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#contextual-fields. pub struct TelemetryContext(Value); impl TelemetryContext { @@ -36,65 +8,8 @@ impl TelemetryContext { } } -impl TelemetryContext { - fn new() -> Self { - let context = TelemetryContextInfo { - os: OperatingSystemInfo::get().ok(), - user_agent: user_agent(), - }; - - match serde_json::to_value(context) { - Ok(value) => Self(value), - Err(e) => { - log::error!("Failed to serialize telemetry context info to JSON value: {e:?}"); - Self(json!({})) - } - } - } -} - -/// Extension trait used to attach a telemetry context. -pub(super) trait AttachContext { - /// Attaches a context to the given object. - fn attach_context(&mut self); -} - -impl AttachContext for RudderMessage { - /// Attaches the context to the [`RudderMessage`]. Note this is currently last write wins; if a - /// message already has a `context` set it will be overridden. - // TODO(alokedesai): Merge the incoming context with the static `TelemetryContext`, if set. - fn attach_context(&mut self) { - let context = telemetry_context().as_value(); - match self { - RudderMessage::Identify(identify) => { - identify.context = Some(context); - } - RudderMessage::Track(track) => track.context = Some(context), - RudderMessage::Page(page) => page.context = Some(context), - RudderMessage::Screen(screen) => screen.context = Some(context), - RudderMessage::Group(group) => group.context = Some(context), - RudderMessage::Alias(alias) => alias.context = Some(context), - RudderMessage::Batch(batch) => batch.context = Some(context), - } - } -} - -/// Returns the user agent provided by the browser, if on Web. If not on Web, -/// or if the user agent was not able to be read, returns None. -fn user_agent() -> Option { - cfg_if::cfg_if! { - if #[cfg(target_family = "wasm")] { - wasm::user_agent() - } else { - None - } - } -} - -/// Returns the telemetry context -/// that should be attached to all telemetry events associated to this client. -/// -/// [Rudderstack](https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#contextual-fields) pub fn telemetry_context() -> &'static TelemetryContext { - TELEMETRY_CONTEXT.get_or_init(TelemetryContext::new) + use std::sync::OnceLock; + static TELEMETRY_CONTEXT: OnceLock = OnceLock::new(); + TELEMETRY_CONTEXT.get_or_init(|| TelemetryContext(json!({}))) } diff --git a/app/src/server/telemetry/macros.rs b/app/src/server/telemetry/macros.rs index b72a960f..dd2d7801 100644 --- a/app/src/server/telemetry/macros.rs +++ b/app/src/server/telemetry/macros.rs @@ -1,93 +1,27 @@ -/// Sends a telemetry event to Rudderstack immediately instead of adding it to the event queue that is -/// periodically flushed. This is useful under certain conditions where we want to ensure an event -/// is immediately sent to Rudderstack even if the user quits before the queue is flushed. +/// No-op: telemetry has been removed from Galaxy. #[macro_export] macro_rules! send_telemetry_sync_from_ctx { ($event:expr, $ctx:expr) => { - #[allow(unused_imports)] - use galaxy_core::telemetry::TelemetryEvent as _; - let event = $event; - if event.enablement_state().is_enabled() { - let server_api = - <$crate::server::server_api::ServerApiProvider as galaxyui::SingletonEntity>::handle( - $ctx, - ) - .as_ref($ctx) - .get(); - let privacy_settings_snapshot = - <$crate::settings::PrivacySettings as galaxyui::SingletonEntity>::handle($ctx) - .as_ref($ctx) - .get_snapshot($ctx); - let _ = $ctx.spawn( - async move { - if let Err(error) = server_api - .send_telemetry_event(event, privacy_settings_snapshot) - .await - { - log::warn!("Error occurred with sending telemetry event: {}", error); - } - }, - |_, _, _| {}, - ); - } + let _ = &$event; + let _ = &$ctx; }; } -/// Sends a telemetry event to Rudderstack immediately. This is the same as [`send_telemetry_sync_from_ctx`], -/// but can be used when the caller only has access to an [`App`] and not a -/// `ViewContext`. +/// No-op: telemetry has been removed from Galaxy. #[macro_export] macro_rules! send_telemetry_sync_from_app_ctx { ($event:expr, $app_ctx:expr) => { - #[allow(unused_imports)] - use galaxy_core::telemetry::TelemetryEvent as _; - if $event.enablement_state().is_enabled() { - let server_api = - <$crate::server::server_api::ServerApiProvider as galaxyui::SingletonEntity>::handle( - $app_ctx, - ) - .as_ref($app_ctx) - .get(); - let privacy_settings_snapshot = - <$crate::settings::PrivacySettings as galaxyui::SingletonEntity>::handle($app_ctx) - .as_ref($app_ctx) - .get_snapshot($app_ctx); - $app_ctx - .background_executor() - .spawn(async move { - if let Err(error) = server_api - .send_telemetry_event($event, privacy_settings_snapshot) - .await - { - log::warn!("Error occurred with sending telemetry event: {error}"); - } - }) - .detach(); - } + let _ = &$event; + let _ = &$app_ctx; }; } -/// Sends a telemetry `track` event Rudderstack asynchronously. This is the same as the -/// [`send_telemetry_from_ctx`], except can be called any time you have an Arc. -/// This should only be called when invoking one of the other macros isn't possible; for example, -/// when you are already on a background thread and thus can't access any app context. +/// No-op: telemetry has been removed from Galaxy. #[macro_export] macro_rules! send_telemetry_on_executor { - ($auth_state: expr, $event:expr, $executor:expr) => { - #[allow(unused_imports)] - use galaxy_core::telemetry::TelemetryEvent as _; - let event = $event; - if event.enablement_state().is_enabled() { - let user_id = $auth_state.user_id().map(|uid| uid.as_string()); - let anonymous_id = $auth_state.anonymous_id(); - galaxyui::record_telemetry_on_executor!( - user_id, - anonymous_id, - event.name().into(), - event.payload(), - event.contains_ugc(), - $executor - ); - } + ($auth_state:expr, $event:expr, $executor:expr) => { + let _ = &$auth_state; + let _ = &$event; + let _ = &$executor; }; } diff --git a/app/src/server/telemetry/mod.rs b/app/src/server/telemetry/mod.rs index ff038679..32507405 100644 --- a/app/src/server/telemetry/mod.rs +++ b/app/src/server/telemetry/mod.rs @@ -1,53 +1,19 @@ mod collector; mod context; pub mod context_provider; -mod events; +pub mod events; mod macros; pub mod rudder_message; pub mod secret_redaction; -use chrono::Utc; pub use collector::*; pub use context::telemetry_context; pub use events::*; -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; -use anyhow::Result; -use futures::FutureExt; -use galaxy_core::channel::RudderStackDestination; -use galaxyui::telemetry::Event; -use rudder_message::{ - Batch as RudderBatch, BatchMessage as RudderBatchMessageWithMetadata, - BatchMessageItem as RudderBatchMessage, Message as RudderMessage, -}; -use std::fs::File; -#[cfg(not(target_family = "wasm"))] -use std::fs::OpenOptions; -use std::future::Future; -use std::path::{Path, PathBuf}; - -/// 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(super) client: http_client::Client, + pub client: http_client::Client, } impl Default for TelemetryApi { @@ -58,353 +24,41 @@ impl Default for TelemetryApi { impl TelemetryApi { pub fn new() -> Self { - cfg_if::cfg_if! { - if #[cfg(test)] { - let client = http_client::Client::new_for_test(); - } else if #[cfg(target_family = "wasm")] { - let client = http_client::Client::default(); - } else { - use std::time::Duration; - - let client = http_client::Client::from_client_builder( - // We use our own http client directly instead of the Rudderstack SDK's because using - // our own client gives us the ability to have universal hooks for pre/post - // request/response logic. - reqwest::Client::builder() - // Don't allow insecure connections; they will be rejected by - // the server with a 403 Forbidden. - .https_only(true) - // Keep idle connections in the pool for up to 55s. AWS - // Application Load Balancers will drop idle connections after - // 60s and the default pool idle timeout is 90s; a pool idle - // timeout longer than the server timeout can lead to errors - // upon trying to use an idle connection. - .pool_idle_timeout(Duration::from_secs(55)) - .connect_timeout(Duration::from_secs(10)), - ).expect("Client should be constructed since we use a compatibility layer to use reqwest::Client"); - } + Self { + client: http_client::Client::default(), } - - Self { client } } - // Batches up telemetry events from the global queue and sends a Message to the Rudderstack API. - // Returns the number of events that were flushed. - pub async fn flush_events(&self, settings_snapshot: PrivacySettingsSnapshot) -> Result { - let events = galaxyui::telemetry::flush_events(); - let event_count = events.len(); - - #[cfg(not(target_family = "wasm"))] - if FeatureFlag::SendTelemetryToFile.is_enabled() { - self.persist_events_to_telemetry_log_file(events.clone())?; - } - - if ChannelState::is_release_bundle() || FeatureFlag::WithSandboxTelemetry.is_enabled() { - self.send_batch_messages_to_rudder( - events - .into_iter() - .map(Event::to_rudder_batch_message) - .collect(), - settings_snapshot, - ) - .await?; - } - - Ok(event_count) - } - - /// Flushes events directly to Rudder that were previously written into a file at `path` - /// (likely via a call to `write_events_to_disk`). - pub async fn flush_persisted_events_to_rudder( - &self, - path: &Path, - settings_snapshot: PrivacySettingsSnapshot, - ) -> Result<()> { - if path.exists() { - let file = File::open(path)?; - let events: Vec = serde_json::from_reader(file)?; - if !events.is_empty() { - let rudder_batch_messages = events - .into_iter() - .map(|message| RudderBatchMessageWithMetadata { - message, - // We don't persist any events that contain sensitive user data. - contains_ugc: false, - }) - .collect(); - self.send_batch_messages_to_rudder(rudder_batch_messages, settings_snapshot) - .await?; - log::info!("Successfully flushed events to rudder from disk"); - } - } - Ok(()) - } - - /// Writes the last `max_event_count` events into disk. This is useful for persisting events - /// where we can't make a network call to Rudder (such as when the app quits). To flush these - /// events to Rudder, call `flush_events_to_rudder_from_disk`. - pub fn flush_and_persist_events( - &self, - max_event_count: usize, - settings_snapshot: PrivacySettingsSnapshot, - ) -> Result<()> { - self.flush_and_persist_events_at_path( - max_event_count, - settings_snapshot, - rudder_event_file_path(), - ) - } - - fn flush_and_persist_events_at_path( - &self, - max_event_count: usize, - settings_snapshot: PrivacySettingsSnapshot, - path: impl AsRef, - ) -> Result<()> { - if settings_snapshot.should_disable_telemetry() { - log::info!("Not writing queued events to disk because telemetry is disabled."); - return Result::Ok(()); - } - log::info!("Writing queued events to disk because telemetry is enabled."); - - let file = File::create(path)?; - - let events = galaxyui::telemetry::flush_events(); - if events.len() > max_event_count { - log::error!("More telemetry events in queue than the limit to persist") - } - - self.persist_events_at_path(&file, max_event_count, events)?; - - Ok(()) - } - - fn persist_events_at_path( - &self, - file: &File, - max_event_count: usize, - events: Vec, - ) -> Result<()> { - let rudder_events_to_persist: Vec<_> = events - .into_iter() - .rev() - .take(max_event_count) - .map(TelemetryExt::to_rudder_batch_message) - .filter_map(|message| (!message.contains_ugc).then_some(message.message)) - .collect(); - serde_json::to_writer(file, &rudder_events_to_persist)?; - Ok(()) - } - - #[cfg(not(target_family = "wasm"))] - fn persist_events_to_telemetry_log_file(&self, events: Vec) -> Result<()> { - let log_directory = galaxy_logging::log_directory()?; - let telemetry_file_path = log_directory.join(&*ChannelState::telemetry_file_name()); - - let file = OpenOptions::new() - .create(true) - .append(true) - .open(&telemetry_file_path)?; - - self.persist_events_at_path(&file, events.len(), events) - } - - /// Sends a `TelemetryEvent` to the Rudderstack API. 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, forceably 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(()) } - /// Sends a POST request to the RudderStack HTTP API. - async fn send_rudder_request( + pub async fn flush_events( &self, - mut msg: RudderMessage, - rudder_stack_destination: RudderStackDestination, - ) -> Result<()> { - msg.attach_context(); + _settings_snapshot: crate::settings::PrivacySettingsSnapshot, + ) -> anyhow::Result { + Ok(0) + } - let path = match msg { - RudderMessage::Identify(_) => "/v1/identify", - RudderMessage::Track(_) => "/v1/track", - RudderMessage::Page(_) => "/v1/page", - RudderMessage::Screen(_) => "/v1/screen", - RudderMessage::Group(_) => "/v1/group", - RudderMessage::Alias(_) => "/v1/alias", - RudderMessage::Batch(_) => "/v1/batch", - }; - - self.client - .post(&format!("{}{}", rudder_stack_destination.root_url, path)) - .basic_auth(rudder_stack_destination.write_key, Some("")) - .json(&msg) - .send() - .await? - .error_for_status()?; + pub async fn flush_persisted_events_to_rudder( + &self, + _path: &std::path::Path, + _settings_snapshot: crate::settings::PrivacySettingsSnapshot, + ) -> anyhow::Result<()> { + Ok(()) + } + pub fn flush_and_persist_events( + &self, + _max_event_count: usize, + _settings_snapshot: crate::settings::PrivacySettingsSnapshot, + ) -> anyhow::Result<()> { Ok(()) } } - -#[cfg(test)] -#[path = "mod_tests.rs"] -mod tests; diff --git a/app/src/server/telemetry/rudder_message.rs b/app/src/server/telemetry/rudder_message.rs index 8e73357b..8b137891 100644 --- a/app/src/server/telemetry/rudder_message.rs +++ b/app/src/server/telemetry/rudder_message.rs @@ -1,249 +1 @@ -//! 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 7a2ec66a..78230bbb 100644 --- a/app/src/server/telemetry/secret_redaction.rs +++ b/app/src/server/telemetry/secret_redaction.rs @@ -1,125 +1,7 @@ -//! Best-effort secret redaction for telemetry payloads. -//! -//! Unlike the AI-side secret redaction in `app/src/ai/blocklist/block/secret_redaction.rs`, -//! which is gated on the user's secret-redaction (a.k.a. "safe mode") setting and is used -//! for visual obfuscation in the terminal, the redaction in this module is unconditional: -//! we always do a redaction pass on telemetry payloads that may contain user-generated -//! content, regardless of the user's safe-mode setting. The two settings are deliberately -//! decoupled — visual obfuscation is a UX preference, while telemetry-side redaction is a -//! defence-in-depth measure for data leaving the device. -//! -//! The regex used for redaction always includes the default patterns defined in -//! `crate::terminal::model::secrets::regexes::DEFAULT_REGEXES_WITH_NAMES`. Any custom -//! patterns the user has configured (or that their organization has configured via -//! enterprise secret redaction) are layered on top of those defaults. -//! -//! This module is intentionally lightweight: it does byte-range matching only and does -//! not track `SecretLevel`s or character ranges, since the telemetry path doesn't need -//! either. -use crate::terminal::model::secrets::regexes::DEFAULT_REGEXES_WITH_NAMES; -use lazy_static::lazy_static; -use parking_lot::RwLock; -use regex_automata::meta::Regex; -use serde_json::Value; -use std::collections::HashSet; -use std::ops::Range; -const REDACTION_REPLACEMENT_CHARACTER: &str = "*"; -lazy_static! { - /// Regex used to redact secrets from telemetry payloads. Initialized with the - /// default patterns so that redaction works even before the user's privacy - /// settings are loaded (and even for users who have never configured any - /// custom patterns). - static ref TELEMETRY_SECRETS_REGEX: RwLock = RwLock::new(build_default_regex()); +use regex::Regex; + +pub fn update_telemetry_secrets_regex<'a>( + _user_secrets: impl Iterator, + _enterprise_secrets: impl Iterator, +) { } -/// 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 17c891b0..8b137891 100644 --- a/app/src/server/telemetry_ext.rs +++ b/app/src/server/telemetry_ext.rs @@ -1,129 +1 @@ -use super::telemetry::rudder_message::{ - BatchMessage as RudderBatchMessage, BatchMessageItem as RudderBatchMessageItem, - Identify as RudderIdentify, Track as RudderTrack, -}; -use super::telemetry::secret_redaction::redact_secrets_in_value; -use crate::auth::UserUid; -use chrono::{DateTime, Utc}; -use galaxy_core::{ - channel::{Channel, ChannelState}, - execution_mode, -}; -use galaxyui::telemetry::EventPayload; -use serde_json::{json, Value}; -use super::telemetry::telemetry_context; - -pub trait TelemetryExt { - fn to_rudder_batch_message(self) -> RudderBatchMessage; -} - -impl TelemetryExt for galaxyui::telemetry::Event { - fn to_rudder_batch_message(self) -> RudderBatchMessage { - let message = match self.payload { - EventPayload::IdentifyUser { - user_id, - anonymous_id, - } => RudderBatchMessageItem::Identify(RudderIdentify { - user_id: Some(UserUid::new(user_id.as_str())), - anonymous_id: Some(anonymous_id), - original_timestamp: Some(self.timestamp), - integrations: Some(json!({ - "Amplitude": { - "session_id": self.session_created_at.timestamp(), - } - })), - context: Some(telemetry_context().as_value()), - ..Default::default() - }), - EventPayload::AppActive { - user_id, - anonymous_id, - } => form_rudder_track_message( - user_id.map(|uid| UserUid::new(uid.as_str())), - anonymous_id, - "Active App Usage".to_string(), - None, - self.timestamp, - self.session_created_at, - ), - EventPayload::NamedEvent { - user_id, - anonymous_id, - name, - mut value, - } => { - // For events that may contain user-generated content, run a - // best-effort secret-redaction pass on the payload before - // sending. This is independent of the user's safe-mode setting: - // visual obfuscation is a UX preference, while telemetry-side - // redaction is a defence-in-depth measure for data leaving the - // device. See `secret_redaction.rs` for details. - if self.contains_ugc { - if let Some(value) = value.as_mut() { - redact_secrets_in_value(value); - } - } - form_rudder_track_message( - user_id.map(|uid| UserUid::new(uid.as_str())), - anonymous_id, - name.to_string(), - value, - self.timestamp, - self.session_created_at, - ) - } - }; - - RudderBatchMessage { - message, - contains_ugc: self.contains_ugc, - } - } -} - -fn form_rudder_track_message( - user_id: Option, - anonymous_id: String, - name: String, - payload: Option, - timestamp: DateTime, - session_created_at: DateTime, -) -> RudderBatchMessageItem { - RudderBatchMessageItem::Track(RudderTrack { - user_id, - anonymous_id: Some(anonymous_id), - event: name, - properties: Some(json!({ - "release_mode": release_mode(ChannelState::channel()), - "tag": ChannelState::app_version().unwrap_or(""), - "client_id": execution_mode::current_client_id(), - "payload": payload - })), - original_timestamp: Some(timestamp), - integrations: Some(json!({ - "Amplitude": { - "session_id": session_created_at.timestamp(), - } - })), - context: Some(telemetry_context().as_value()), - }) -} - -fn release_mode(channel: Channel) -> &'static str { - match channel { - Channel::Stable => "stable_release", - Channel::Preview => "preview_release", - Channel::Local => "local", - Channel::Integration => "integration_test", - Channel::Dev => "dev_release", - // We don't ever expect to send telemetry for the OSS build, but - // until we have some time to clean things up here, we'll set a valid - // value that we never intend to receive. - Channel::Oss => "oss_release", - } -} - -#[cfg(test)] -#[path = "telemetry_ext_tests.rs"] -mod tests; diff --git a/app/src/settings/ai.rs b/app/src/settings/ai.rs index 6591b1f0..7dcb5f4e 100644 --- a/app/src/settings/ai.rs +++ b/app/src/settings/ai.rs @@ -1617,7 +1617,7 @@ impl AISettings { return None; } let path = std::path::Path::new(path_str); - crate::user_config::WarpConfig::as_ref(app) + crate::user_config::GalaxyConfig::as_ref(app) .tab_configs() .iter() .find(|config| config.source_path.as_deref().is_some_and(|p| p == path)) diff --git a/app/src/settings/import/alacritty_parser.rs b/app/src/settings/import/alacritty_parser.rs index 9ee0172e..dc401251 100644 --- a/app/src/settings/import/alacritty_parser.rs +++ b/app/src/settings/import/alacritty_parser.rs @@ -3,7 +3,7 @@ use async_recursion::async_recursion; use async_trait::async_trait; use galaxy_core::ui::{ color::hex_color::coloru_from_hex_string, - theme::{AnsiColor, AnsiColors, TerminalColors, WarpTheme}, + theme::{AnsiColor, AnsiColors, TerminalColors, GalaxyTheme}, }; use galaxyui::fonts::FontInfo; use serde::Deserialize; @@ -289,7 +289,7 @@ impl AlacrittyTheme { } else { let bright = terminal_colors.bright; let accent = calculate_accent_color(background, foreground, cursor_color, bright); - Ok(ThemeType::Single(WarpTheme::new( + Ok(ThemeType::Single(GalaxyTheme::new( background.into(), foreground.into(), accent.into(), diff --git a/app/src/settings/import/config.rs b/app/src/settings/import/config.rs index af07256f..609a7cd1 100644 --- a/app/src/settings/import/config.rs +++ b/app/src/settings/import/config.rs @@ -2,7 +2,7 @@ use std::{path::PathBuf, sync::Arc}; use galaxy_core::ui::{ color::hex_color::HexColorError as UiHexColorError, - theme::{AnsiColors, WarpTheme}, + theme::{AnsiColors, GalaxyTheme}, }; use pathfinder_color::ColorU; use serde::Serialize; @@ -29,8 +29,8 @@ use super::iterm_parser::ITermProfile; #[derive(Debug)] pub enum ThemeType { - LightAndDark { light: WarpTheme, dark: WarpTheme }, - Single(WarpTheme), + LightAndDark { light: GalaxyTheme, dark: GalaxyTheme }, + Single(GalaxyTheme), } #[derive(Clone, Debug)] diff --git a/app/src/settings/import/iterm_parser.rs b/app/src/settings/import/iterm_parser.rs index f2c6703c..c9fd317e 100644 --- a/app/src/settings/import/iterm_parser.rs +++ b/app/src/settings/import/iterm_parser.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use async_trait::async_trait; use bitflags::bitflags; -use galaxy_core::ui::theme::{AnsiColors, TerminalColors, WarpTheme}; +use galaxy_core::ui::theme::{AnsiColors, TerminalColors, GalaxyTheme}; use galaxyui::{ fonts::FontInfo, keymap::Keystroke, platform::mac::utils::unicode_char_to_key, DisplayIdx, }; @@ -126,7 +126,7 @@ impl ITermTheme { mut self, suffix: &'static str, default_theme: &ITermTheme, - ) -> Result { + ) -> Result { if self.foreground == default_theme.foreground || self.background == default_theme.background { @@ -149,7 +149,7 @@ impl ITermTheme { let accent = calculate_accent_color(background, foreground, cursor, bright); - Ok(WarpTheme::new( + Ok(GalaxyTheme::new( background.into(), foreground, accent.into(), diff --git a/app/src/settings/import/iterm_parser_tests.rs b/app/src/settings/import/iterm_parser_tests.rs index e58f747d..70aff184 100644 --- a/app/src/settings/import/iterm_parser_tests.rs +++ b/app/src/settings/import/iterm_parser_tests.rs @@ -1,5 +1,5 @@ use async_io::block_on; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::{fonts::FontInfo, keymap::Keystroke}; use pathfinder_color::ColorU; use plist::{Dictionary, Value}; @@ -106,9 +106,9 @@ fn test_color_dictionary_to_coloru() { #[test] fn test_into_warp_theme_valid() { - let theme: WarpTheme = solarized_dark_theme() + let theme: GalaxyTheme = solarized_dark_theme() .into_warp_theme("", &default_dark_theme()) - .expect("Should be able to convert into WarpTheme"); + .expect("Should be able to convert into GalaxyTheme"); assert_eq!( theme.accent(), Fill::Solid(ColorU { diff --git a/app/src/settings/import/view.rs b/app/src/settings/import/view.rs index 945274dd..7582a161 100644 --- a/app/src/settings/import/view.rs +++ b/app/src/settings/import/view.rs @@ -35,7 +35,7 @@ use crate::{ }, themes::theme::{CustomTheme, SelectedSystemThemes, ThemeKind}, ui_components::blended_colors, - user_config::{self, WarpConfig}, + user_config::{self, GalaxyConfig}, window_settings::WindowSettings, GlobalResourceHandlesProvider, TelemetryEvent, }; @@ -775,10 +775,10 @@ impl SettingsImportView { )); report_if_error!(theme_settings.use_system_theme.set_value(true, ctx)); }); - WarpConfig::handle(ctx).update(ctx, |config, ctx| { + GalaxyConfig::handle(ctx).update(ctx, |config, ctx| { config.add_new_theme_to_config(dark_kind, dark, ctx) }); - WarpConfig::handle(ctx).update(ctx, |config, ctx| { + GalaxyConfig::handle(ctx).update(ctx, |config, ctx| { config.add_new_theme_to_config(light_kind, light, ctx) }); } @@ -795,7 +795,7 @@ impl SettingsImportView { .set_value(theme_kind.clone(), ctx,)); report_if_error!(theme_settings.use_system_theme.set_value(false, ctx)); }); - WarpConfig::handle(ctx).update(ctx, |config, ctx| { + GalaxyConfig::handle(ctx).update(ctx, |config, ctx| { config.add_new_theme_to_config(theme_kind, theme, ctx) }); } diff --git a/app/src/settings/init.rs b/app/src/settings/init.rs index 84e44604..1394f484 100644 --- a/app/src/settings/init.rs +++ b/app/src/settings/init.rs @@ -201,7 +201,7 @@ pub fn init( appearance::register(ctx); - // Set up hot-reload for the settings file. When the WarpConfig watcher + // Set up hot-reload for the settings file. When the GalaxyConfig watcher // detects a change to settings.toml, reload preferences from disk and // push changed values into setting models. #[cfg(feature = "local_fs")] @@ -209,7 +209,7 @@ pub fn init( let prefs = ::as_ref(ctx); if prefs.is_settings_file() { ctx.subscribe_to_model( - &crate::user_config::WarpConfig::handle(ctx), + &crate::user_config::GalaxyConfig::handle(ctx), handle_warp_config_change, ); } @@ -218,24 +218,24 @@ pub fn init( user_defaults_on_startup } -/// Handles a `WarpConfig` change event, reloading settings from disk when +/// Handles a `GalaxyConfig` change event, reloading settings from disk when /// the settings file is modified, created, or deleted. #[cfg(feature = "local_fs")] fn handle_warp_config_change( - _: galaxyui::ModelHandle, - event: &crate::user_config::WarpConfigUpdateEvent, + _: galaxyui::ModelHandle, + event: &crate::user_config::GalaxyConfigUpdateEvent, ctx: &mut AppContext, ) { - use crate::user_config::{WarpConfig, WarpConfigUpdateEvent}; + use crate::user_config::{GalaxyConfig, GalaxyConfigUpdateEvent}; - if !matches!(event, WarpConfigUpdateEvent::Settings) { + if !matches!(event, GalaxyConfigUpdateEvent::Settings) { return; } let prefs = ::as_ref(ctx); if let Err(err) = prefs.reload_from_disk() { log::warn!("Settings file reload failed: {err}"); - WarpConfig::handle(ctx).update(ctx, |_, ctx| { - ctx.emit(WarpConfigUpdateEvent::SettingsErrors( + GalaxyConfig::handle(ctx).update(ctx, |_, ctx| { + ctx.emit(GalaxyConfigUpdateEvent::SettingsErrors( super::SettingsFileError::FileParseFailed(err.to_string()), )); }); @@ -243,11 +243,11 @@ fn handle_warp_config_change( } let failed_keys = settings::SettingsManager::handle(ctx) .update(ctx, |manager, ctx| manager.reload_all_public_settings(ctx)); - WarpConfig::handle(ctx).update(ctx, |_, ctx| { + GalaxyConfig::handle(ctx).update(ctx, |_, ctx| { if failed_keys.is_empty() { - ctx.emit(WarpConfigUpdateEvent::SettingsErrorsCleared); + ctx.emit(GalaxyConfigUpdateEvent::SettingsErrorsCleared); } else { - ctx.emit(WarpConfigUpdateEvent::SettingsErrors( + ctx.emit(GalaxyConfigUpdateEvent::SettingsErrors( super::SettingsFileError::InvalidSettings(failed_keys), )); } diff --git a/app/src/settings/mod.rs b/app/src/settings/mod.rs index ab9ee3b7..284ff3f3 100644 --- a/app/src/settings/mod.rs +++ b/app/src/settings/mod.rs @@ -118,8 +118,8 @@ impl SettingsFileError { use crate::{ root_view::QuakeModePinPosition, terminal::{BlockListSettings, BlockPadding}, - themes::theme::{ThemeKind, WarpTheme}, - user_config::WarpConfig, + themes::theme::{ThemeKind, GalaxyTheme}, + user_config::GalaxyConfig, }; use galaxy_core::features::FeatureFlag; use galaxyui::{ @@ -516,10 +516,10 @@ impl Settings { }) } - pub fn theme_for_theme_kind(theme_kind: &ThemeKind, ctx: &mut AppContext) -> WarpTheme { + pub fn theme_for_theme_kind(theme_kind: &ThemeKind, ctx: &mut AppContext) -> GalaxyTheme { match theme_kind { ThemeKind::InMemory(in_memory_theme) => in_memory_theme.theme(), - _ => WarpConfig::as_ref(ctx).theme_config().theme(theme_kind), + _ => GalaxyConfig::as_ref(ctx).theme_config().theme(theme_kind), } } } diff --git a/app/src/settings_view/ai_page.rs b/app/src/settings_view/ai_page.rs index 78626218..09298b62 100644 --- a/app/src/settings_view/ai_page.rs +++ b/app/src/settings_view/ai_page.rs @@ -2059,7 +2059,7 @@ pub enum AISettingsPageAction { RemoveDirectoryFromCodeReadAllowlist(PathBuf), ToggleRules, ToggleRuleSuggestions, - ToggleWarpDriveContext, + ToggleGalaxyDriveContext, SetApplyCodeDiffs(ActionPermission), SetReadFiles(ActionPermission), SetExecuteCommands(ActionPermission), @@ -2618,7 +2618,7 @@ impl TypedActionView for AISettingsPageView { }); ctx.notify(); } - AISettingsPageAction::ToggleWarpDriveContext => { + AISettingsPageAction::ToggleGalaxyDriveContext => { AISettings::handle(ctx).update(ctx, |settings, ctx| { let _ = settings .warp_drive_context_enabled @@ -5094,7 +5094,7 @@ impl AIFactWidget { ) -> Box { let toggle = render_ai_setting_toggle::( "Galaxy Drive as agent context", - AISettingsPageAction::ToggleWarpDriveContext, + AISettingsPageAction::ToggleGalaxyDriveContext, *ai_settings.warp_drive_context_enabled, ai_settings.is_any_ai_enabled(app), self.warp_drive_context_toggle.clone(), diff --git a/app/src/settings_view/appearance_page.rs b/app/src/settings_view/appearance_page.rs index 65306a4e..93f4fde0 100644 --- a/app/src/settings_view/appearance_page.rs +++ b/app/src/settings_view/appearance_page.rs @@ -45,8 +45,8 @@ use crate::terminal::settings::{ }; use crate::terminal::{BlockListSettings, ShowBlockDividers}; use crate::terminal::{ShowJumpToBottomOfBlockButton, SizeInfo}; -use crate::themes::theme::{self, RespectSystemTheme, SelectedSystemThemes, ThemeKind, WarpTheme}; -use crate::user_config::WarpConfig; +use crate::themes::theme::{self, RespectSystemTheme, SelectedSystemThemes, ThemeKind, GalaxyTheme}; +use crate::user_config::GalaxyConfig; use crate::util::bindings; use crate::window_settings::{ BackgroundBlurRadius, BackgroundBlurTexture, BackgroundOpacity, LeftPanelVisibilityAcrossTabs, @@ -2734,7 +2734,7 @@ impl ThemeSelectWidget { is_selected: bool, app: &AppContext, ) -> Box { - let theme: WarpTheme = WarpConfig::as_ref(app).theme_config().theme(&theme_kind); + let theme: GalaxyTheme = GalaxyConfig::as_ref(app).theme_config().theme(&theme_kind); let mode_ui_label = match theme_chooser_mode { ThemeChooserMode::SystemLight => "Light", ThemeChooserMode::SystemDark => "Dark", diff --git a/app/src/settings_view/code_page.rs b/app/src/settings_view/code_page.rs index 27df07d9..9d6044d1 100644 --- a/app/src/settings_view/code_page.rs +++ b/app/src/settings_view/code_page.rs @@ -2016,7 +2016,7 @@ impl CodePageWidget { &self, server_model: Option<&galaxyui::ModelHandle>, app: &AppContext, - theme: &galaxy_core::ui::theme::WarpTheme, + theme: &galaxy_core::ui::theme::GalaxyTheme, ) -> (ColorU, &'static str) { match server_model { Some(model) => { diff --git a/app/src/settings_view/features_page.rs b/app/src/settings_view/features_page.rs index d256fcc6..5ef3a68a 100644 --- a/app/src/settings_view/features_page.rs +++ b/app/src/settings_view/features_page.rs @@ -77,7 +77,7 @@ use crate::terminal::settings::{ }; use crate::terminal::{BlockListSettings, SnackbarEnabled}; use crate::undo_close::UndoCloseSettings; -use crate::user_config::{WarpConfig, WarpConfigUpdateEvent}; +use crate::user_config::{GalaxyConfig, GalaxyConfigUpdateEvent}; use crate::util::bindings::{ keybinding_name_to_display_string, reset_keybinding_to_default, set_custom_keybinding, }; @@ -2141,8 +2141,8 @@ impl FeaturesPageView { let default_session_mode_dropdown = ctx.add_typed_action_view(FilterableDropdown::new); Self::update_default_session_mode_dropdown(default_session_mode_dropdown.clone(), ctx); - ctx.subscribe_to_model(&WarpConfig::handle(ctx), |me, _, event, ctx| { - if matches!(event, WarpConfigUpdateEvent::TabConfigs) { + ctx.subscribe_to_model(&GalaxyConfig::handle(ctx), |me, _, event, ctx| { + if matches!(event, GalaxyConfigUpdateEvent::TabConfigs) { Self::update_default_session_mode_dropdown( me.default_session_mode_dropdown.clone(), ctx, @@ -3339,7 +3339,7 @@ impl FeaturesPageView { .collect(); // Append each loaded tab config - let tab_configs = WarpConfig::as_ref(ctx).tab_configs().to_vec(); + let tab_configs = GalaxyConfig::as_ref(ctx).tab_configs().to_vec(); for config in &tab_configs { if let Some(path) = &config.source_path { items.push(DropdownItem::new( diff --git a/app/src/settings_view/main_page.rs b/app/src/settings_view/main_page.rs index 2aaa4ea2..fbf8200d 100644 --- a/app/src/settings_view/main_page.rs +++ b/app/src/settings_view/main_page.rs @@ -160,7 +160,7 @@ impl From<&MainPageAction> for LoginGatedFeature { pub enum MainSettingsPageEvent { CheckForUpdate, #[allow(dead_code)] - OpenWarpDrive, + OpenGalaxyDrive, SignupAnonymousUser, } diff --git a/app/src/settings_view/mcp_servers/list_page.rs b/app/src/settings_view/mcp_servers/list_page.rs index fd74a4d3..e6d51eda 100644 --- a/app/src/settings_view/mcp_servers/list_page.rs +++ b/app/src/settings_view/mcp_servers/list_page.rs @@ -1555,7 +1555,7 @@ impl MCPServersListPageView { // If the path is the Warp data directory (e.g. ~/.warp or ~/.warp_dev), set the text to // "global". The Warp provider stores its data directory as the root path rather than the // home directory, unlike other providers that store the home directory directly. - if root_path == &crate::warp_managed_paths_watcher::warp_data_dir() { + if root_path == &crate::galaxy_managed_paths_watcher::galaxy_data_dir() { return Some("global".to_string()); } diff --git a/app/src/settings_view/mod.rs b/app/src/settings_view/mod.rs index e0b400da..97773c5b 100644 --- a/app/src/settings_view/mod.rs +++ b/app/src/settings_view/mod.rs @@ -159,7 +159,7 @@ pub enum SettingsViewEvent { StartResize, CheckForUpdate, LaunchNetworkLogging, - OpenWarpDrive, + OpenGalaxyDrive, SignupAnonymousUser, ShowToast { message: String, @@ -989,7 +989,7 @@ pub struct SettingsView { /// Mirrored from `Workspace` via [`set_settings_error_state`]. settings_error_banner_dismissed: bool, /// Mouse state handles for the nav-rail footer buttons. Constructed once - /// per `SettingsView` per `WARP.md`'s guidance that inline + /// per `SettingsView` per `GALAXY.md`'s guidance that inline /// `MouseStateHandle::default()` breaks hover/click tracking. footer_mouse_states: SettingsFooterMouseStates, } diff --git a/app/src/settings_view/privacy_page.rs b/app/src/settings_view/privacy_page.rs index 0ea04107..ae297ea2 100644 --- a/app/src/settings_view/privacy_page.rs +++ b/app/src/settings_view/privacy_page.rs @@ -13,7 +13,7 @@ use galaxy_core::context_flag::ContextFlag; use regex::Regex; use settings::Setting as _; -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, @@ -1751,6 +1751,6 @@ mod styles { pub const DESCRIPTION_LINE_MARGIN_BOTTOM: f32 = 6.; } -fn description_text_color(theme: &WarpTheme) -> galaxy_core::ui::theme::Fill { +fn description_text_color(theme: &GalaxyTheme) -> galaxy_core::ui::theme::Fill { theme.sub_text_color(theme.surface_2()) } diff --git a/app/src/settings_view/teams_page.rs b/app/src/settings_view/teams_page.rs index e11c0c62..1c60b743 100644 --- a/app/src/settings_view/teams_page.rs +++ b/app/src/settings_view/teams_page.rs @@ -189,7 +189,7 @@ pub enum TeamsPageAction { SendEmailInvites { team_uid: ServerId, }, - OpenWarpDrive, + OpenGalaxyDrive, GenerateUpgradeLink { team_uid: ServerId, }, @@ -298,7 +298,7 @@ impl TryFrom<&TeamsPageAction> for TelemetryEvent { #[derive(Clone)] pub enum TeamsPageViewEvent { TeamsChanged, - OpenWarpDrive, + OpenGalaxyDrive, ShowToast { message: String, flavor: ToastFlavor, @@ -492,7 +492,7 @@ impl TypedActionView for TeamsPageView { self.send_email_invites(*team_uid, ctx); ctx.notify(); } - TeamsPageAction::OpenWarpDrive => ctx.emit(TeamsPageViewEvent::OpenWarpDrive), + TeamsPageAction::OpenGalaxyDrive => ctx.emit(TeamsPageViewEvent::OpenGalaxyDrive), TeamsPageAction::ShowLeaveTeamConfirmationDialog => { self.delete_or_leave_team_confirmation_dialog .update(ctx, |dialog, ctx| { @@ -1365,7 +1365,7 @@ impl TeamsPageView { ctx, ); }); - ctx.dispatch_typed_action(&WorkspaceAction::OpenWarpDrive); + ctx.dispatch_typed_action(&WorkspaceAction::OpenGalaxyDrive); } fn set_team_member_role( diff --git a/app/src/tab_configs/session_config_rendering.rs b/app/src/tab_configs/session_config_rendering.rs index 7269d082..c4de35ce 100644 --- a/app/src/tab_configs/session_config_rendering.rs +++ b/app/src/tab_configs/session_config_rendering.rs @@ -16,7 +16,7 @@ use pathfinder_color::ColorU; use pathfinder_geometry::vector::vec2f; use galaxy_core::ui::theme::Fill; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use crate::appearance::Appearance; use crate::tab_configs::session_config::SessionType; @@ -32,7 +32,7 @@ const PILL_GAP: f32 = 8.; fn session_type_item_color( is_selected: bool, on_accent_bg: bool, - theme: &WarpTheme, + theme: &GalaxyTheme, bg_fill: Fill, ) -> ColorU { if on_accent_bg { diff --git a/app/src/tab_configs/session_config_tests.rs b/app/src/tab_configs/session_config_tests.rs index f3beec5a..f4f6be32 100644 --- a/app/src/tab_configs/session_config_tests.rs +++ b/app/src/tab_configs/session_config_tests.rs @@ -517,14 +517,14 @@ fn snapshot_2x2_grid() { #[test] fn snapshot_non_terminal_leaf_replaced_with_terminal() { use crate::app_state::NotebookPaneSnapshot; - use crate::drive::OpenWarpDriveObjectSettings; + use crate::drive::OpenGalaxyDriveObjectSettings; let notebook_leaf = PaneNodeSnapshot::Leaf(LeafSnapshot { is_focused: false, custom_vertical_tabs_title: None, contents: LeafContents::Notebook(NotebookPaneSnapshot::CloudNotebook { notebook_id: None, - settings: OpenWarpDriveObjectSettings::default(), + settings: OpenGalaxyDriveObjectSettings::default(), }), }); let snapshot = PaneNodeSnapshot::Branch(BranchSnapshot { diff --git a/app/src/terminal/block_filter.rs b/app/src/terminal/block_filter.rs index 7deeb6a9..274a01a3 100644 --- a/app/src/terminal/block_filter.rs +++ b/app/src/terminal/block_filter.rs @@ -3,7 +3,7 @@ use galaxyui::elements::{Align, Dash}; use galaxyui::ui_components::components::UiComponent; use galaxyui::FocusContext; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, DropShadow, Empty, Flex, Hoverable, MouseStateHandle, OffsetPositioning, @@ -755,7 +755,7 @@ impl View for BlockFilterEditor { Some(AccessibilityContent::new( "Type searched phrase.", "Press escape to quit", - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } } diff --git a/app/src/terminal/block_list_element.rs b/app/src/terminal/block_list_element.rs index 3a9b503b..ed76c32a 100644 --- a/app/src/terminal/block_list_element.rs +++ b/app/src/terminal/block_list_element.rs @@ -20,7 +20,7 @@ use crate::terminal::model::selection::{SelectAction, SelectionPoint}; use crate::terminal::safe_mode_settings::get_secret_obfuscation_mode; use crate::terminal::view::TerminalAction; use crate::terminal::{grid_renderer, SizeInfo}; -use crate::themes::theme::{Fill, WarpTheme}; +use crate::themes::theme::{Fill, GalaxyTheme}; use crate::ui_components::{self, icons as UIIcon}; use crate::util::color::Opacity; use crate::BlocklistAIHistoryModel; @@ -634,7 +634,7 @@ pub struct BlockListElement { font_size: f32, font_weight: Weight, line_height_ratio: f32, - warp_theme: WarpTheme, + warp_theme: GalaxyTheme, ui_builder: UiBuilder, block_borders_enabled: bool, overflow_offset: f32, @@ -2362,7 +2362,7 @@ impl BlockListElement { block: &Block, is_selected_by_anyone: bool, bounds: RectF, - warp_theme: &WarpTheme, + warp_theme: &GalaxyTheme, block_borders_enabled: bool, snackbar_header: &Option, ai_render_context: &BlocklistAIRenderContext, @@ -4761,7 +4761,7 @@ pub fn render_hoverable_block_button( should_ignore_mouse_events: bool, should_allow_action: bool, mouse_state: MouseStateHandle, - theme: &WarpTheme, + theme: &GalaxyTheme, ui_builder: &UiBuilder, on_click: F, ) -> Box diff --git a/app/src/terminal/blockgrid_renderer.rs b/app/src/terminal/blockgrid_renderer.rs index c4d86fd9..fabb73ac 100644 --- a/app/src/terminal/blockgrid_renderer.rs +++ b/app/src/terminal/blockgrid_renderer.rs @@ -6,7 +6,7 @@ use crate::terminal::model::grid::grid_handler::Link; use crate::terminal::model::index::Point; use crate::terminal::model::ObfuscateSecrets; use crate::terminal::SizeInfo; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use galaxyui::fonts::{FamilyId, Properties, Weight}; use galaxyui::geometry::rect::RectF; use galaxyui::geometry::vector::{vec2f, Vector2F}; @@ -22,7 +22,7 @@ use super::model::image_map::StoredImageMetadata; use super::model::SecretHandle; pub struct GridRenderParams { - pub warp_theme: WarpTheme, + pub warp_theme: GalaxyTheme, pub font_family: FamilyId, pub font_size: f32, pub font_weight: Weight, diff --git a/app/src/terminal/color.rs b/app/src/terminal/color.rs index a141bd93..727bb453 100644 --- a/app/src/terminal/color.rs +++ b/app/src/terminal/color.rs @@ -1,5 +1,5 @@ use crate::terminal::model::ansi::color_index; -use crate::themes::theme::{AnsiColors, WarpTheme}; +use crate::themes::theme::{AnsiColors, GalaxyTheme}; use galaxyui::color::ColorU; use std::fmt; use std::ops::{Index, IndexMut}; @@ -41,8 +41,8 @@ impl Colors { } } -impl From for Colors { - fn from(theme: WarpTheme) -> Self { +impl From for Colors { + fn from(theme: GalaxyTheme) -> Self { let colors = theme.terminal_colors(); Colors::new( PrimaryColors::new( diff --git a/app/src/terminal/grid_renderer.rs b/app/src/terminal/grid_renderer.rs index 56501bdc..e715ea5a 100644 --- a/app/src/terminal/grid_renderer.rs +++ b/app/src/terminal/grid_renderer.rs @@ -11,7 +11,7 @@ use crate::terminal::model::index::Point; use crate::terminal::model::selection::SelectionPoint; use crate::terminal::model::{ObfuscateSecrets, SecretHandle}; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::util::color::{ContrastingColor, MinimumAllowedContrast}; use core::mem; @@ -288,7 +288,7 @@ pub fn render_grid<'a>( end_row: usize, colors: &color::List, override_colors: &color::OverrideList, - theme: &WarpTheme, + theme: &GalaxyTheme, default_font_properties: Properties, font_family: FamilyId, font_size: f32, @@ -463,7 +463,7 @@ fn render_grid_without_ligatures<'a>( visible_rows: impl Iterator, colors: &color::List, override_colors: &color::OverrideList, - theme: &WarpTheme, + theme: &GalaxyTheme, default_font_properties: Properties, font_family: FamilyId, font_size: f32, @@ -967,7 +967,7 @@ fn render_grid_with_ligatures<'a>( visible_rows: impl Iterator, colors: &color::List, override_colors: &color::OverrideList, - theme: &WarpTheme, + theme: &GalaxyTheme, default_font_properties: Properties, font_family: FamilyId, font_size: f32, diff --git a/app/src/terminal/input.rs b/app/src/terminal/input.rs index aebc1b89..38e00213 100644 --- a/app/src/terminal/input.rs +++ b/app/src/terminal/input.rs @@ -192,7 +192,7 @@ use crate::{ settings_view::{flags, SettingsSection}, terminal::view::inline_banner::{PromptSuggestionsEvent, PromptSuggestionsView}, ui_components::{blended_colors, icons::Icon}, - user_config::WarpConfig, + user_config::GalaxyConfig, util::bindings::{self, CustomAction}, util::image::MAX_IMAGE_COUNT_FOR_QUERY, view_components::{DismissibleToast, ToastFlavor}, @@ -268,7 +268,7 @@ use galaxy_core::{ use galaxy_editor::editor::NavigationKey; use galaxy_util::path::ShellFamily; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, clipboard::{ClipboardContent, ImageData}, clipboard_utils::CLIPBOARD_IMAGE_MIME_TYPES, color::ColorU, @@ -2652,7 +2652,7 @@ impl Input { .app_workflows() .cloned() .collect_vec(); - let local_user_workflows = WarpConfig::as_ref(ctx).local_user_workflows().clone(); + let local_user_workflows = GalaxyConfig::as_ref(ctx).local_user_workflows().clone(); let workflows_search_view = ctx.add_typed_action_view(|ctx| { workflows::CategoriesView::new(local_user_workflows, app_workflows, ctx) @@ -6677,7 +6677,7 @@ impl Input { ctx.emit_a11y_content(AccessibilityContent::new( accessibility_text, "Press shift-tab to select the next workflow argument", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); // Only highlight an argument and show enum suggestions if history suggestions are not active @@ -7029,7 +7029,7 @@ impl Input { ctx.emit_a11y_content(AccessibilityContent::new_without_help( format!("Executed: {command}"), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); } InputSuggestionsEvent::CloseSuggestion { @@ -11164,7 +11164,7 @@ impl Input { if let Some(a11y_text) = self.selected_workflow_a11y_text(ctx) { ctx.emit_a11y_content(AccessibilityContent::new_without_help( a11y_text, - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); } } else { @@ -11246,7 +11246,7 @@ impl Input { if trigger == CommandXRayTrigger::Keystroke { ctx.emit_a11y_content(AccessibilityContent::new_without_help( description.a11y_text(), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )); } ctx.notify(); @@ -13883,7 +13883,7 @@ impl TypedActionView for Input { INPUT_A11Y_LABEL, // TODO (a11y) use bindings from user settings INPUT_A11Y_HELPER, - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } _ => ActionAccessibilityContent::Empty, @@ -14082,7 +14082,7 @@ impl View for Input { INPUT_A11Y_LABEL, // TODO (a11y) use bindings from user settings INPUT_A11Y_HELPER, - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } diff --git a/app/src/terminal/input/agent.rs b/app/src/terminal/input/agent.rs index 43a78080..beea38f1 100644 --- a/app/src/terminal/input/agent.rs +++ b/app/src/terminal/input/agent.rs @@ -599,12 +599,12 @@ impl Input { } pub mod styles { - use galaxy_core::ui::theme::WarpTheme; + use galaxy_core::ui::theme::GalaxyTheme; use pathfinder_color::ColorU; use crate::ui_components::blended_colors; - pub fn default_border_color(theme: &WarpTheme) -> ColorU { + pub fn default_border_color(theme: &GalaxyTheme) -> ColorU { blended_colors::neutral_2(theme) } } diff --git a/app/src/terminal/input/inline_menu/styles.rs b/app/src/terminal/input/inline_menu/styles.rs index 2883d332..d6d12dcf 100644 --- a/app/src/terminal/input/inline_menu/styles.rs +++ b/app/src/terminal/input/inline_menu/styles.rs @@ -5,7 +5,7 @@ //! visual design matching the Figma specifications. use galaxy_core::ui::appearance::Appearance; use galaxy_core::ui::color::blend::Blend; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::color::ColorU; use galaxyui::{AppContext, SingletonEntity}; @@ -46,15 +46,15 @@ pub fn item_background( } } -pub fn primary_text_color(theme: &WarpTheme, background: Fill) -> Fill { +pub fn primary_text_color(theme: &GalaxyTheme, background: Fill) -> Fill { theme.main_text_color(background) } -pub fn secondary_text_color(theme: &WarpTheme, background: Fill) -> Fill { +pub fn secondary_text_color(theme: &GalaxyTheme, background: Fill) -> Fill { theme.sub_text_color(background) } -pub fn disabled_text_color(theme: &WarpTheme, background: Fill) -> Fill { +pub fn disabled_text_color(theme: &GalaxyTheme, background: Fill) -> Fill { theme.disabled_text_color(background) } 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 72affbfb..c57d0c74 100644 --- a/app/src/terminal/input/slash_commands/data_source/mod.rs +++ b/app/src/terminal/input/slash_commands/data_source/mod.rs @@ -25,7 +25,7 @@ use crate::terminal::cli_agent_sessions::{ CLIAgentInputState, CLIAgentSessionsModel, CLIAgentSessionsModelEvent, }; use crate::terminal::model::session::SessionType; -use galaxy_core::ui::Icon as WarpIcon; +use galaxy_core::ui::Icon as GalaxyIcon; use super::AcceptSlashCommandOrSavedPrompt; use crate::{ @@ -440,13 +440,13 @@ impl InlineItem { override_icon } else { match skill.provider { - SkillProvider::Warp => WarpIcon::Warp, - SkillProvider::Claude => WarpIcon::ClaudeLogo, - SkillProvider::Codex => WarpIcon::OpenAILogo, - SkillProvider::Gemini => WarpIcon::GeminiLogo, - SkillProvider::Droid => WarpIcon::DroidLogo, - SkillProvider::OpenCode => WarpIcon::OpenCodeLogo, - _ => WarpIcon::Warp, + SkillProvider::Warp => GalaxyIcon::Warp, + SkillProvider::Claude => GalaxyIcon::ClaudeLogo, + SkillProvider::Codex => GalaxyIcon::OpenAILogo, + SkillProvider::Gemini => GalaxyIcon::GeminiLogo, + SkillProvider::Droid => GalaxyIcon::DroidLogo, + SkillProvider::OpenCode => GalaxyIcon::OpenCodeLogo, + _ => GalaxyIcon::Warp, } }; diff --git a/app/src/terminal/input/suggestions_mode_menu.rs b/app/src/terminal/input/suggestions_mode_menu.rs index 69432245..277eee40 100644 --- a/app/src/terminal/input/suggestions_mode_menu.rs +++ b/app/src/terminal/input/suggestions_mode_menu.rs @@ -18,7 +18,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; use galaxyui::elements::{ Align, Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DragBarSide, DropShadow, Element, Empty, Flex, ParentElement, Radius, Resizable, Shrinkable, @@ -187,7 +187,7 @@ impl Input { &self, margin: f32, corner_radius: CornerRadius, - theme: &WarpTheme, + theme: &GalaxyTheme, resize_config: SuggestionsResizeConfig, menu_positioning: MenuPositioning, content: Box, diff --git a/app/src/terminal/input/terminal.rs b/app/src/terminal/input/terminal.rs index dd9f6fa3..953dcaa3 100644 --- a/app/src/terminal/input/terminal.rs +++ b/app/src/terminal/input/terminal.rs @@ -298,10 +298,10 @@ impl Input { } pub mod styles { - use galaxy_core::ui::theme::WarpTheme; + use galaxy_core::ui::theme::GalaxyTheme; use pathfinder_color::ColorU; - pub fn default_border_color(theme: &WarpTheme) -> ColorU { + pub fn default_border_color(theme: &GalaxyTheme) -> ColorU { theme.outline().into() } } diff --git a/app/src/terminal/input/terminal_message_bar.rs b/app/src/terminal/input/terminal_message_bar.rs index 1f302f56..4e9fdbdc 100644 --- a/app/src/terminal/input/terminal_message_bar.rs +++ b/app/src/terminal/input/terminal_message_bar.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::elements::{Container, Element}; use galaxyui::keymap::Keystroke; use galaxyui::{AppContext, Entity, ModelHandle, SingletonEntity, View, ViewContext}; @@ -460,7 +460,7 @@ impl MessageTransformer> for AttachedTextSelectionMessag } } -fn message_magenta(theme: &WarpTheme) -> ColorU { +fn message_magenta(theme: &GalaxyTheme) -> ColorU { let mut color = theme.ansi_fg_magenta(); color.a = (255. * 0.65) as u8; color diff --git a/app/src/terminal/input_test.rs b/app/src/terminal/input_test.rs index 0d91eec8..ddd48485 100644 --- a/app/src/terminal/input_test.rs +++ b/app/src/terminal/input_test.rs @@ -22,7 +22,7 @@ use crate::search::files::model::FileSearchModel; use crate::terminal::cli_agent_sessions::CLIAgentSessionsModel; use crate::terminal::input::slash_command_model::SlashCommandEntryState; use crate::terminal::input::slash_commands::SlashCommandsEvent; -use crate::warp_managed_paths_watcher::WarpManagedPathsWatcher; +use crate::galaxy_managed_paths_watcher::GalaxyManagedPathsWatcher; use repo_metadata::repositories::DetectedRepositories; use repo_metadata::watcher::DirectoryWatcher; use repo_metadata::RepoMetadataModel; @@ -161,7 +161,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); app.add_singleton_model(SkillManager::new); // Add GlobalResourceHandlesProvider for persistence diff --git a/app/src/terminal/share_block_modal.rs b/app/src/terminal/share_block_modal.rs index de8ccbb7..e1dcaac6 100644 --- a/app/src/terminal/share_block_modal.rs +++ b/app/src/terminal/share_block_modal.rs @@ -16,7 +16,7 @@ use crate::{ safe_mode_settings::get_secret_obfuscation_mode, TerminalModel, }, - themes::theme::WarpTheme, + themes::theme::GalaxyTheme, ui_components::icons::Icon, util::bindings::CustomAction, view_components::ToastFlavor, @@ -1164,7 +1164,7 @@ fn should_send_title_gen_request(ctx: &ViewContext) -> bool { struct SingleBlock { terminal_model: Arc>, - theme: WarpTheme, + theme: GalaxyTheme, font_family: FamilyId, font_size: f32, line_height_ratio: f32, @@ -1188,7 +1188,7 @@ impl SingleBlock { #[allow(clippy::too_many_arguments)] fn new( terminal_model: Arc>, - theme: WarpTheme, + theme: GalaxyTheme, font_family: FamilyId, font_size: f32, line_height_ratio: f32, diff --git a/app/src/terminal/shared_session/viewer/terminal_manager.rs b/app/src/terminal/shared_session/viewer/terminal_manager.rs index 3c567f97..fe4a4b49 100644 --- a/app/src/terminal/shared_session/viewer/terminal_manager.rs +++ b/app/src/terminal/shared_session/viewer/terminal_manager.rs @@ -669,7 +669,7 @@ impl TerminalManager { }); #[cfg(target_family = "wasm")] - crate::platform::wasm::emit_event(crate::platform::wasm::WarpEvent::SessionJoined); + crate::platform::wasm::emit_event(crate::platform::wasm::GalaxyEvent::SessionJoined); } NetworkEvent::SessionEnded { reason } => { let Some(view) = weak_view_handle.upgrade(ctx) else { diff --git a/app/src/terminal/ssh/error.rs b/app/src/terminal/ssh/error.rs index 6b19d80a..ad7cf8bf 100644 --- a/app/src/terminal/ssh/error.rs +++ b/app/src/terminal/ssh/error.rs @@ -6,7 +6,7 @@ use crate::terminal::warpify::render::build_description_row; use crate::terminal::warpify::settings::WarpifySettings; use crate::ui_components::icons::Icon as UiIcon; use galaxy_core::channel::ChannelState; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::elements::HighlightedHyperlink; use galaxyui::elements::Hoverable; use galaxyui::elements::Icon; @@ -170,7 +170,7 @@ impl SshErrorBlock { fn render_title_ui( &self, app: &AppContext, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, ) -> Box { let header_contents = warpify::render::build_header_row( diff --git a/app/src/terminal/ssh/install_tmux.rs b/app/src/terminal/ssh/install_tmux.rs index 86b60d59..777547ef 100644 --- a/app/src/terminal/ssh/install_tmux.rs +++ b/app/src/terminal/ssh/install_tmux.rs @@ -10,7 +10,7 @@ use crate::terminal::warpify::render; use crate::terminal::warpify::settings::WarpifySettings; use crate::ui_components::blended_colors; use crate::ui_components::icons::Icon as UiIcon; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::elements::{ FormattedTextElement, HighlightedHyperlink, Hoverable, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, @@ -315,7 +315,7 @@ impl SshInstallTmuxBlock { fn render_title_ui( &self, app: &AppContext, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, ) -> Box { let header_contents = render::build_header_row( diff --git a/app/src/terminal/ssh/warpify.rs b/app/src/terminal/ssh/warpify.rs index 6a0355aa..eebb7adb 100644 --- a/app/src/terminal/ssh/warpify.rs +++ b/app/src/terminal/ssh/warpify.rs @@ -1,5 +1,5 @@ use asset_macro::bundled_asset; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::assets::asset_cache::{AssetCache, AssetState}; use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine}; @@ -65,7 +65,7 @@ impl Entity for SshWarpifyBlock { } impl SshWarpifyBlock { - fn render_title_ui(&self, theme: &WarpTheme, appearance: &Appearance) -> Box { + fn render_title_ui(&self, theme: &GalaxyTheme, appearance: &Appearance) -> Box { let icon = Icon::new(UiIcon::Warp.into(), theme.active_ui_detail()); warpify::render::header_row("Wormholing SSH Session...", icon, theme, appearance) } diff --git a/app/src/terminal/view.rs b/app/src/terminal/view.rs index 7f55af86..67bd03b4 100644 --- a/app/src/terminal/view.rs +++ b/app/src/terminal/view.rs @@ -321,7 +321,7 @@ use crate::terminal::{height_in_range_approx, heights_approx_gt, SizeUpdate}; use crate::terminal::{heights_approx_eq, CellSizeAndWindowPadding}; use crate::terminal::{AudibleBell, SizeUpdateReason}; use crate::terminal::{BlockListSettings, BlockListSettingsChangedEvent}; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use crate::ui_components::icons::{self}; use crate::util::bindings::{ custom_tag_to_keystroke, keybinding_name_to_display_string, keybinding_name_to_keystroke, @@ -407,7 +407,7 @@ use galaxyui::assets::asset_cache::{AssetCache, AssetCacheEvent}; use galaxyui::image_cache::ImageType; use galaxyui::units::{IntoLines, IntoPixels, Lines, Pixels}; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, elements::SavePosition, elements::{ Align, Clipped, ConstrainedBox, CornerRadius, Fill, Hoverable, Icon, MouseStateHandle, @@ -721,7 +721,7 @@ const DEFAULT_AI_BLOCK_HEIGHT: f32 = 96.; pub const DEFAULT_ASK_AI_AUTOSUGGESTION_TEXT: &str = "What happened here?"; -const WARP_MD_PATH: &str = "WARP.md"; +const GALAXY_MD_PATH: &str = "GALAXY.md"; pub const LONG_RUNNING_AGENT_REQUESTED_COMMAND_CONTEXT_KEY: &str = "LongRunningRequestedCommand"; pub const LONG_RUNNING_AGENT_REQUESTED_COMMAND_USER_TOOK_OVER_CONTEXT_KEY: &str = @@ -1678,7 +1678,7 @@ pub enum Event { OpenWorkflowModalWithCloudWorkflow(SyncId), // Tell the pane group to open the workflow modal with an unsaved workflow. OpenWorkflowModalWithTemporary(Box), - OpenWarpDriveObjectInPane(ObjectUid), + OpenGalaxyDriveObjectInPane(ObjectUid), OpenSuggestedAgentModeWorkflowModal { workflow_and_id: SuggestedAgentModeWorkflowAndId, }, @@ -2218,7 +2218,7 @@ impl BlocklistAIRenderContext { } /// Returns the AI context stripe color to use for a block, if any. - pub fn context_color_for_block(&self, block: &Block, theme: &WarpTheme) -> Option { + pub fn context_color_for_block(&self, block: &Block, theme: &GalaxyTheme) -> Option { match self.context_inclusion_state_for_block(block) { Some(AIContextInclusionState::Active) => self.context_color(theme), _ => None, @@ -2229,7 +2229,7 @@ impl BlocklistAIRenderContext { pub fn context_color_for_rich_content( &self, rich_content: &RichContentMetadata, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Option { match rich_content { RichContentMetadata::AIBlock(ai_metadata) @@ -2248,7 +2248,7 @@ impl BlocklistAIRenderContext { /// The context color to use for a block, given its conversation phase. /// This assumes the block is part of the active conversation. - fn context_color(&self, theme: &WarpTheme) -> Option { + fn context_color(&self, theme: &GalaxyTheme) -> Option { (self.is_ai_input_enabled && self.should_highlight_context).then(|| ai_brand_color(theme)) } } @@ -4012,7 +4012,7 @@ impl TerminalView { ConversationDetailsPanelEvent::OpenPlanNotebook { notebook_uid } => { // Convert NotebookId -> SyncId -> ObjectUid (String) let object_uid = SyncId::from(*notebook_uid).uid(); - ctx.emit(Event::OpenWarpDriveObjectInPane(object_uid)); + ctx.emit(Event::OpenGalaxyDriveObjectInPane(object_uid)); } } }); @@ -5628,8 +5628,6 @@ impl TerminalView { conversation.wall_to_wall_response_time_since_last_query(); let token_usage_list = conversation.total_token_usage(); - let total_input_tokens: u32 = token_usage_list.iter().map(|u| u.total_input).sum(); - let total_output_tokens: u32 = token_usage_list.iter().map(|u| u.output).sum(); let total_cache_read_tokens: u32 = token_usage_list.iter().map(|u| u.input_cache_read).sum(); let total_cache_write_tokens: u32 = token_usage_list.iter().map(|u| u.input_cache_write).sum(); @@ -5643,11 +5641,10 @@ impl TerminalView { 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, - total_input_tokens, - total_output_tokens, + current_context_tokens: conversation.current_context_tokens(), + estimated_cost_cents, total_cache_read_tokens, total_cache_write_tokens, - estimated_cost_cents, }; let timing_info = TimingInfo { @@ -8568,7 +8565,7 @@ impl TerminalView { let a11y_content = AccessibilityContent::new( format!("{title} recognized."), a11y_message, - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, ); ctx.emit_a11y_content(a11y_content); @@ -8681,7 +8678,7 @@ impl TerminalView { let a11y_content = AccessibilityContent::new( trigger.discovery_banner_copy(), "You can enable notifications through the command palette.", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, ); ctx.emit_a11y_content(a11y_content); @@ -8720,7 +8717,7 @@ impl TerminalView { let a11y_content = AccessibilityContent::new( banner_title, "Make sure you have enabled access for Galaxy notifications in System Preferences.", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, ); ctx.emit_a11y_content(a11y_content); @@ -13495,7 +13492,7 @@ impl TerminalView { let a11y_content = AccessibilityContent::new( format!("Suggested corrected command: {}", correction.command), "Press right arrow to insert or keep editing to ignore", - WarpA11yRole::HelpRole, + GalaxyA11yRole::HelpRole, ); ctx.emit_a11y_content(a11y_content); @@ -18807,7 +18804,7 @@ impl TerminalView { } AIBlockEvent::OpenCitation(citation) => match citation { AIAgentCitation::WarpDriveObject { uid } => { - ctx.emit(Event::OpenWarpDriveObjectInPane(uid.clone())); + ctx.emit(Event::OpenGalaxyDriveObjectInPane(uid.clone())); } AIAgentCitation::WarpDocumentation { path } => { ctx.open_url(&format!("https://docs.warp.dev/{path}")); @@ -18821,7 +18818,7 @@ impl TerminalView { } AIBlockEvent::OpenWorkflow { sync_id } => { if let Some(object) = CloudModel::as_ref(ctx).get_workflow(sync_id) { - ctx.emit(Event::OpenWarpDriveObjectInPane(object.uid())); + ctx.emit(Event::OpenGalaxyDriveObjectInPane(object.uid())); } } AIBlockEvent::OpenSuggestedAgentModeWorkflowModal { workflow_and_id } => { @@ -23098,7 +23095,7 @@ impl TerminalView { // TODO (a11y) Keybindings should be taken from the actual user's // configuration "Press cmd-C to read and copy both command and output, and cmd-option-shift-C to read and copy output only. Press cmd-B to bookmark the block: you could navigate between bookmarked blocks quickly using option-up and option-down.", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, ) }) } @@ -24097,7 +24094,7 @@ impl TypedActionView for TerminalView { .map_or(Empty, |selected| { Custom(AccessibilityContent::new_without_help( selected, - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) }) } @@ -24123,7 +24120,7 @@ impl TypedActionView for TerminalView { BookmarkBlock(_) | BookmarkSelectedBlock => { Custom(AccessibilityContent::new_without_help( "Toggle Bookmark block", - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) } ExpandBlockSelectionAbove | ExpandBlockSelectionBelow => { @@ -24145,19 +24142,19 @@ impl TypedActionView for TerminalView { "Selected all {} blocks.", self.num_non_hidden_selected_blocks() ), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), ScrollToBottomOfSelectedBlocks => Custom(AccessibilityContent::new_without_help( "Scrolled to bottom of selected block".to_string(), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), ScrollToTopOfSelectedBlocks => Custom(AccessibilityContent::new_without_help( "Scrolled to top of selected block".to_string(), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), ScrollToBottomOfOverhangingBlock(_) => Custom(AccessibilityContent::new_without_help( "Scrolled to bottom of bottommost visible block".to_string(), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), CopyOutputs => { let mut outputs = vec![]; @@ -24178,7 +24175,7 @@ impl TypedActionView for TerminalView { ); Custom(AccessibilityContent::new_without_help( text, - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) } Copy => { @@ -24197,7 +24194,7 @@ impl TypedActionView for TerminalView { let text = format!("Copied {} blocks.\n{}", blocks.len(), blocks.join("\n")); Custom(AccessibilityContent::new_without_help( text, - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )) } FocusInputAndClearSelection => { @@ -24205,7 +24202,7 @@ impl TypedActionView for TerminalView { INPUT_A11Y_LABEL, // TODO (a11y) use bindings from user settings INPUT_A11Y_HELPER, - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } KeyDown(key) => { @@ -24216,24 +24213,24 @@ impl TypedActionView for TerminalView { }; Custom(AccessibilityContent::new_without_help( label, - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } OpenBlockFilterEditor(block_index) => Custom(AccessibilityContent::new_without_help( format!("Open block filter editor for block {block_index}"), - WarpA11yRole::TextRole, + GalaxyA11yRole::TextRole, )), ShowInitializationBlock => Custom(AccessibilityContent::new_without_help( "Showed initialization block", - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )), ShowWarpifySettings => Custom(AccessibilityContent::new_without_help( "Opened Wormhole Settings", - WarpA11yRole::ButtonRole, + GalaxyA11yRole::ButtonRole, )), OpenFilesPalette { .. } => Custom(AccessibilityContent::new_without_help( "Opened file search palette", - WarpA11yRole::ButtonRole, + GalaxyA11yRole::ButtonRole, )), InsertCommandCorrection { .. } | BlockListContextMenu(_) @@ -24302,28 +24299,28 @@ impl TypedActionView for TerminalView { OpenInWarpBanner(action) => self.open_in_warp_banner_accessibility_content(*action), OpenAIBlockAttachedBlocksMenu { .. } => Custom(AccessibilityContent::new_without_help( "Open list of blocks attached as context to this AI query.".to_owned(), - WarpA11yRole::PopoverRole, + GalaxyA11yRole::PopoverRole, )), OpenAIBlockOverflowMenu { .. } => Custom(AccessibilityContent::new_without_help( "Open overflow menu with copy options for this AI block.".to_owned(), - WarpA11yRole::PopoverRole, + GalaxyA11yRole::PopoverRole, )), RewindAIConversation { .. } => Custom(AccessibilityContent::new_without_help( "Show confirmation dialog to rewind to before this point in the AI conversation." .to_owned(), - WarpA11yRole::ButtonRole, + GalaxyA11yRole::ButtonRole, )), ExecuteRewindAIConversation { .. } => Custom(AccessibilityContent::new_without_help( "Execute rewind to before this point in the AI conversation.".to_owned(), - WarpA11yRole::ButtonRole, + GalaxyA11yRole::ButtonRole, )), SelectAIAttachedBlock(_) => Custom(AccessibilityContent::new_without_help( "Click on a block attached as context to this AI query.".to_owned(), - WarpA11yRole::ButtonRole, + GalaxyA11yRole::ButtonRole, )), PickRepoToOpen => Custom(AccessibilityContent::new_without_help( "Use file picker to select a git repository".to_owned(), - WarpA11yRole::PopoverRole, + GalaxyA11yRole::PopoverRole, )), #[cfg(feature = "voice_input")] ToggleCLIAgentVoiceInput(_) => Empty, @@ -25252,11 +25249,11 @@ impl TypedActionView for TerminalView { } OpenProjectRulesPane => { if let Some(current_dir) = self.pwd() { - let mut warp_md_path = PathBuf::from(¤t_dir); - warp_md_path.push(WARP_MD_PATH); + let mut galaxy_md_path = PathBuf::from(¤t_dir); + galaxy_md_path.push(GALAXY_MD_PATH); #[cfg(feature = "local_fs")] ctx.emit(Event::OpenCodeInWarp { - source: CodeSource::ProjectRules { path: warp_md_path }, + source: CodeSource::ProjectRules { path: galaxy_md_path }, layout: *crate::util::file::external_editor::EditorSettings::as_ref(ctx) .open_file_layout .value(), @@ -26531,7 +26528,7 @@ fn maybe_wrap_terminal_element_in_scrollable( vertical_scroll_handle: ScrollStateHandle, horizontal_scroll_handle: ClippedScrollStateHandle, required_terminal_width: f32, - theme: &WarpTheme, + theme: &GalaxyTheme, element: impl NewScrollableElement + 'static, ) -> Box { let nonactive_thumb_background = theme.disabled_text_color(theme.background()).into(); diff --git a/app/src/terminal/view/block_banner/mod.rs b/app/src/terminal/view/block_banner/mod.rs index 6a0daf82..51aefdc6 100644 --- a/app/src/terminal/view/block_banner/mod.rs +++ b/app/src/terminal/view/block_banner/mod.rs @@ -17,7 +17,7 @@ use galaxyui::{ }; pub use warpify::*; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; const CONSTRAINED_BANNER_HEIGHT: f32 = 48.; const BANNER_TOP_MARGIN: f32 = 16.; @@ -53,7 +53,7 @@ impl WithinBlockBanner { fn render_block_banner( build_child: impl FnOnce(&MouseState) -> Box, hover_state: MouseStateHandle, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { Stack::new() .with_child( diff --git a/app/src/terminal/view/init_project/mod.rs b/app/src/terminal/view/init_project/mod.rs index 77086a04..b7dff0e2 100644 --- a/app/src/terminal/view/init_project/mod.rs +++ b/app/src/terminal/view/init_project/mod.rs @@ -39,12 +39,11 @@ use model::{InitStepData, InitStepStatus}; use std::path::{Path, PathBuf}; const ONBOARDING_TEXT: &str = "Great - let's begin setting up this project! Would you like to give me permission to index this codebase? It allows me to quickly understand context and provide more targeted solutions when working in this codebase. No code is stored on Galaxy servers."; -const ALREADY_SETUP_TEXT: &str = "It looks like this project has already been initialized. You can re-generate the AGENTS.md for this codebase by clicking the button below."; -// Native Warp rules file format. -pub const FILES_TO_CHECK: [&str; 2] = ["AGENTS.md", "WARP.md"]; -// File formats that can be linked to WARP.md. -pub const LINKABLE_FILES: [&str; 7] = [ - "CLAUDE.md", +const ALREADY_SETUP_TEXT: &str = "It looks like this project has already been initialized. You can re-generate the GALAXY.md for this codebase by clicking the button below."; +// Native Galaxy rules file format. +pub const FILES_TO_CHECK: [&str; 4] = ["GALAXY.md", "AGENTS.md", "WARP.md", "CLAUDE.md"]; +// File formats that can be linked to GALAXY.md. +pub const LINKABLE_FILES: [&str; 6] = [ ".cursorrules", "AGENT.md", "GEMINI.md", diff --git a/app/src/terminal/view/init_project/model.rs b/app/src/terminal/view/init_project/model.rs index 86b6acd4..e6a1bad3 100644 --- a/app/src/terminal/view/init_project/model.rs +++ b/app/src/terminal/view/init_project/model.rs @@ -54,7 +54,7 @@ pub enum InitStepStatus { Pending, /// Ready for user interaction (contains data for view to render) Ready(InitStepData), - /// User initiated action, e.g. AI generating WARP.md + /// User initiated action, e.g. AI generating GALAXY.md Running, /// Done (accepted, skipped, or auto-completed) Completed(InitActionResult), @@ -517,17 +517,20 @@ impl InitProjectModel { exists }, move |me, existing_files, ctx| { - let has_agents_md = existing_files.iter().any(|p| { + let has_rules_md = existing_files.iter().any(|p| { p.file_name() .map(|n| { let name = n.to_string_lossy().to_lowercase(); - name == "agents.md" || name == "warp.md" + name == "galaxy.md" + || name == "agents.md" + || name == "warp.md" + || name == "claude.md" }) .unwrap_or(false) }); - if has_agents_md { - // Already has AGENTS.md or WARP.md, mark as completed + if has_rules_md { + // Already has a rules file, mark as completed me.set_step( InitStepKind::ProjectScopedRules, Some(InitStep::new_completed( diff --git a/app/src/terminal/view/open_in_warp.rs b/app/src/terminal/view/open_in_warp.rs index fa11e4f9..fff5ef71 100644 --- a/app/src/terminal/view/open_in_warp.rs +++ b/app/src/terminal/view/open_in_warp.rs @@ -6,7 +6,7 @@ use std::{ use galaxy_util::path::EscapeChar; use galaxyui::{ - accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole}, SingletonEntity, ViewContext, }; use itertools::Itertools; @@ -238,7 +238,7 @@ impl TerminalView { Some(banner_state) => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("Open {} in Galaxy", banner_state.target.path.display()), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } None => ActionAccessibilityContent::Empty, @@ -247,14 +247,14 @@ impl TerminalView { OpenInWarpBannerAction::Close => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( "Close View in Galaxy banner", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } OpenInWarpBannerAction::LearnMore => { ActionAccessibilityContent::Custom(AccessibilityContent::new( "Learn more", "Learn more about opening Markdown files in Galaxy", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } } diff --git a/app/src/terminal/view/pane_impl.rs b/app/src/terminal/view/pane_impl.rs index c93ef768..2c7f043d 100644 --- a/app/src/terminal/view/pane_impl.rs +++ b/app/src/terminal/view/pane_impl.rs @@ -33,7 +33,7 @@ use crate::ui_components::buttons::icon_button_with_color; use crate::ui_components::icons; use crate::workspace::tab_settings::TabSettings; use galaxy_core::context_flag::ContextFlag; -use galaxy_core::ui::Icon as WarpIcon; +use galaxy_core::ui::Icon as GalaxyIcon; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, CrossAxisAlignment, Flex, MainAxisAlignment, MainAxisSize, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Shrinkable, Stack, @@ -796,9 +796,9 @@ impl TerminalView { { ConstrainedBox::new( if is_ambient_agent { - WarpIcon::OzCloud + GalaxyIcon::OzCloud } else { - WarpIcon::Oz + GalaxyIcon::Oz } .to_galaxyui_icon(blended_colors::text_sub(theme, theme.background()).into()) .finish(), diff --git a/app/src/terminal/view/shell_terminated_banner.rs b/app/src/terminal/view/shell_terminated_banner.rs index 66837833..c729f37d 100644 --- a/app/src/terminal/view/shell_terminated_banner.rs +++ b/app/src/terminal/view/shell_terminated_banner.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, cell::RefCell}; use galaxy_core::ui::{ appearance::Appearance, builder::UiBuilder, - theme::{color::internal_colors, WarpTheme}, + theme::{color::internal_colors, GalaxyTheme}, }; use galaxyui::{ clipboard::ClipboardContent, @@ -276,7 +276,7 @@ impl TerminationType { fn inverted_color_ui_builder(appearance: &Appearance) -> UiBuilder { let theme = appearance.theme(); - let theme = WarpTheme::new( + let theme = GalaxyTheme::new( theme.foreground(), theme.background().into_solid(), theme.background(), diff --git a/app/src/terminal/warpify/render.rs b/app/src/terminal/warpify/render.rs index 768cd666..7f3027cd 100644 --- a/app/src/terminal/warpify/render.rs +++ b/app/src/terminal/warpify/render.rs @@ -1,7 +1,7 @@ use crate::ai::blocklist::inline_action::inline_action_icons; use crate::ui_components::blended_colors; 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, @@ -41,7 +41,7 @@ pub const LEFT_STRIPE_WIDTH: f32 = 5.; pub fn build_header_row( text: &'static str, icon: Icon, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, ) -> Container { let mut row = Flex::row(); @@ -80,7 +80,7 @@ pub fn apply_spacing_styles(header_row: Container) -> Container { pub fn header_row( text: &'static str, icon: Icon, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, ) -> Box { apply_spacing_styles(build_header_row(text, icon, theme, appearance)).finish() @@ -96,7 +96,7 @@ fn green_check_icon(appearance: &Appearance, size: f32) -> Box { /// UI helper to render the ssh command that caused the warpification prompt. pub fn build_command_row( command: String, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, show_green_check: bool, ) -> Container { @@ -131,7 +131,7 @@ pub fn build_command_row( /// UI helper to render the description row of an SSH rich content block. pub fn build_description_row( text: FormattedText, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, highlight_index: HighlightedHyperlink, ) -> FormattedTextElement { @@ -150,7 +150,7 @@ pub fn build_description_row( ) } -pub fn description_row(text: &str, theme: &WarpTheme, appearance: &Appearance) -> Box { +pub fn description_row(text: &str, theme: &GalaxyTheme, appearance: &Appearance) -> Box { let text = FormattedText::new(vec![FormattedTextLine::Line(vec![ FormattedTextFragment::plain_text(text), ])]); @@ -202,7 +202,7 @@ pub fn render_never_warpify_ssh_link( Some(Align::new(link).bottom_right().finish()) } -fn get_subshell_flag_info(subshell_source: &SubshellSource, theme: &WarpTheme) -> (String, Fill) { +fn get_subshell_flag_info(subshell_source: &SubshellSource, theme: &GalaxyTheme) -> (String, Fill) { match subshell_source { SubshellSource::EnvVarCollection(environment_name) => ( environment_name.to_string(), @@ -245,7 +245,7 @@ pub fn render_subshell_flag( subshell_source: SubshellSource, font_family: FamilyId, font_size: f32, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let (flag_name, background_color) = get_subshell_flag_info(&subshell_source, theme); let container = Container::new( diff --git a/app/src/terminal/warpify/success_block.rs b/app/src/terminal/warpify/success_block.rs index 3a54138f..538ecded 100644 --- a/app/src/terminal/warpify/success_block.rs +++ b/app/src/terminal/warpify/success_block.rs @@ -11,7 +11,7 @@ use crate::ui_components::icons::Icon as UiIcon; use crate::workspace::WorkspaceAction; use channel_versions::overrides::TargetOS; use galaxy_core::semantic_selection::SemanticSelection; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::elements::{ CrossAxisAlignment, Icon, MainAxisAlignment, MainAxisSize, MouseStateHandle, SelectableArea, SelectionHandle, Text, @@ -145,7 +145,7 @@ impl WarpifySuccessBlock { pub fn render_spawning_command( &self, - theme: &WarpTheme, + theme: &GalaxyTheme, appearance: &Appearance, ) -> Box { let spawning_command = self.spawning_command.clone(); @@ -154,7 +154,7 @@ impl WarpifySuccessBlock { .finish() } - pub fn render_title_ui(&self, theme: &WarpTheme, appearance: &Appearance) -> Box { + pub fn render_title_ui(&self, theme: &GalaxyTheme, appearance: &Appearance) -> Box { let header_contents = render::build_header_row( "Session Wormholed", Icon::new(UiIcon::Warp.into(), theme.active_ui_detail()), diff --git a/app/src/terminal/writeable_pty/pty_controller_tests.rs b/app/src/terminal/writeable_pty/pty_controller_tests.rs index e6ceb442..c95f5b92 100644 --- a/app/src/terminal/writeable_pty/pty_controller_tests.rs +++ b/app/src/terminal/writeable_pty/pty_controller_tests.rs @@ -4,7 +4,7 @@ use crate::terminal::event_listener::ChannelEventListener; use crate::terminal::model::block::{BlockSize, SerializedBlock}; use crate::terminal::shell::ShellType; use crate::terminal::BlockPadding; -use crate::theme::WarpTheme; +use crate::theme::GalaxyTheme; use super::*; @@ -42,7 +42,7 @@ fn terminal_model(background_executor: Arc) -> Arc TerminalColors { } /// Default bundled themes -pub fn dark_theme() -> WarpTheme { - WarpTheme::new( +pub fn dark_theme() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x000000FF)), ColorU::from_u32(0xffffffff), Fill::Solid(ColorU::from_u32(0x19AAD8FF)), @@ -321,8 +321,8 @@ pub fn dark_theme() -> WarpTheme { ) } -pub fn light_theme() -> WarpTheme { - WarpTheme::new( +pub fn light_theme() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::white()), ColorU::new(17, 17, 17, OPAQUE), Fill::Solid(ColorU::from_u32(0x00c2ffff)), @@ -334,8 +334,8 @@ pub fn light_theme() -> WarpTheme { ) } -pub(super) fn dracula() -> WarpTheme { - WarpTheme::new( +pub(super) fn dracula() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x282A36FF)), ColorU::from_u32(0xF8F8F2FF), Fill::Solid(ColorU::from_u32(0xFF79C6FF)), @@ -347,8 +347,8 @@ pub(super) fn dracula() -> WarpTheme { ) } -pub(super) fn solarized_light() -> WarpTheme { - WarpTheme::new( +pub(super) fn solarized_light() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0xFDF6E3FF)), ColorU::from_u32(0x586E75FF), Fill::Solid(ColorU::from_u32(0x66B5A9FF)), @@ -360,8 +360,8 @@ pub(super) fn solarized_light() -> WarpTheme { ) } -pub(super) fn solarized_dark() -> WarpTheme { - WarpTheme::new( +pub(super) fn solarized_dark() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x002B36FF)), ColorU::from_u32(0xF8F8F2FF), Fill::Solid(ColorU::from_u32(0xCB4B16FF)), @@ -373,8 +373,8 @@ pub(super) fn solarized_dark() -> WarpTheme { ) } -pub(super) fn gruvbox_dark() -> WarpTheme { - WarpTheme::new( +pub(super) fn gruvbox_dark() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x282828FF)), ColorU::from_u32(0xEBDBB2FF), Fill::Solid(ColorU::from_u32(0xFC802DFF)), @@ -386,8 +386,8 @@ pub(super) fn gruvbox_dark() -> WarpTheme { ) } -pub(super) fn gruvbox_light() -> WarpTheme { - WarpTheme::new( +pub(super) fn gruvbox_light() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0xFBF1C7FF)), ColorU::from_u32(0x3C3836FF), Fill::Solid(ColorU::from_u32(0xAD3B14FF)), @@ -400,8 +400,8 @@ pub(super) fn gruvbox_light() -> WarpTheme { } /// Bundled gradient themes -pub(super) fn cyber_wave() -> WarpTheme { - WarpTheme::new( +pub(super) fn cyber_wave() -> GalaxyTheme { + GalaxyTheme::new( Fill::VerticalGradient(VerticalGradient::new( ColorU::black().blend(&coloru_with_opacity(ColorU::from_u32(0x00C2FFFF), 20)), ColorU::black(), @@ -419,8 +419,8 @@ pub(super) fn cyber_wave() -> WarpTheme { ) } -pub(super) fn willow_dream() -> WarpTheme { - WarpTheme::new( +pub(super) fn willow_dream() -> GalaxyTheme { + GalaxyTheme::new( Fill::VerticalGradient(VerticalGradient::new( ColorU::from_u32(0x206169FF), ColorU::from_u32(0x022F27FF), @@ -438,8 +438,8 @@ pub(super) fn willow_dream() -> WarpTheme { ) } -pub(super) fn fancy_dracula() -> WarpTheme { - WarpTheme::new( +pub(super) fn fancy_dracula() -> GalaxyTheme { + GalaxyTheme::new( Fill::VerticalGradient(VerticalGradient::new( ColorU::from_u32(0x252630FF), ColorU::from_u32(0x3D3F4FFF), @@ -457,8 +457,8 @@ pub(super) fn fancy_dracula() -> WarpTheme { ) } -pub(super) fn phenomenon() -> WarpTheme { - WarpTheme::new( +pub(super) fn phenomenon() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x121212FF)), ColorU::from_u32(0xFAF9F6FF), Fill::Solid(ColorU::from_u32(0x2E5D9EFF)), @@ -474,8 +474,8 @@ pub(super) fn phenomenon() -> WarpTheme { } /// Bundled themes with background images -pub(super) fn jellyfish() -> WarpTheme { - WarpTheme::new( +pub(super) fn jellyfish() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x1B1718FF)), ColorU::white(), Fill::Solid(ColorU::from_u32(0x538682FF)), @@ -490,8 +490,8 @@ pub(super) fn jellyfish() -> WarpTheme { ) } -pub(super) fn koi() -> WarpTheme { - WarpTheme::new( +pub(super) fn koi() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x211719FF)), ColorU::white(), Fill::Solid(ColorU::from_u32(0xFF3131FF)), @@ -506,8 +506,8 @@ pub(super) fn koi() -> WarpTheme { ) } -pub(super) fn leafy() -> WarpTheme { - WarpTheme::new( +pub(super) fn leafy() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::black()), ColorU::white(), Fill::Solid(ColorU::from_u32(0x55972DFF)), @@ -522,8 +522,8 @@ pub(super) fn leafy() -> WarpTheme { ) } -pub(super) fn marble() -> WarpTheme { - WarpTheme::new( +pub(super) fn marble() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0xE3E3E3FF)), ColorU::black(), Fill::Solid(ColorU::from_u32(0x585858FF)), @@ -538,11 +538,11 @@ pub(super) fn marble() -> WarpTheme { ) } -pub(super) fn pink_city() -> WarpTheme { +pub(super) fn pink_city() -> GalaxyTheme { let details = CustomDetails { ..CustomDetails::lighter_details() }; - WarpTheme::new( + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0xFBEFF6FF)), ColorU::black(), Fill::Solid(ColorU::from_u32(0xE10087FF)), @@ -557,8 +557,8 @@ pub(super) fn pink_city() -> WarpTheme { ) } -pub(super) fn snowy() -> WarpTheme { - WarpTheme::new( +pub(super) fn snowy() -> GalaxyTheme { + GalaxyTheme::new( Fill::VerticalGradient(VerticalGradient::new( ColorU::from_u32(0xFFFFFFFF), ColorU::from_u32(0xDEE6EBFF), @@ -576,8 +576,8 @@ pub(super) fn snowy() -> WarpTheme { ) } -pub(super) fn red_rock() -> WarpTheme { - WarpTheme::new( +pub(super) fn red_rock() -> GalaxyTheme { + GalaxyTheme::new( Fill::VerticalGradient(VerticalGradient::new( ColorU::from_u32(0x211719FF) .blend(&coloru_with_opacity(ColorU::from_u32(0x4C3435FF), 45)), @@ -597,8 +597,8 @@ pub(super) fn red_rock() -> WarpTheme { ) } -pub(super) fn dark_city() -> WarpTheme { - WarpTheme::new( +pub(super) fn dark_city() -> GalaxyTheme { + GalaxyTheme::new( Fill::VerticalGradient(VerticalGradient::new( ColorU::from_u32(0x01181FFF) .blend(&coloru_with_opacity(ColorU::from_u32(0x1A363FFF), 45)), @@ -618,8 +618,8 @@ pub(super) fn dark_city() -> WarpTheme { ) } -pub(super) fn sent_referral_reward() -> WarpTheme { - WarpTheme::new( +pub(super) fn sent_referral_reward() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x334567FF)), ColorU::white(), Fill::Solid(ColorU::from_u32(0xCD51FFFF)), @@ -634,8 +634,8 @@ pub(super) fn sent_referral_reward() -> WarpTheme { ) } -pub(super) fn solar_flare() -> WarpTheme { - WarpTheme::new( +pub(super) fn solar_flare() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x1B1C18FF)), ColorU::from_u32(0xDDE6EEFF), Fill::Solid(ColorU::from_u32(0x34895CFF)), @@ -650,8 +650,8 @@ pub(super) fn solar_flare() -> WarpTheme { ) } -pub(super) fn adeberry() -> WarpTheme { - WarpTheme::new( +pub(super) fn adeberry() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x1D2022FF)), ColorU::from_u32(0xE4EEF5FF), Fill::Solid(ColorU::from_u32(0x6C96B4FF)), @@ -663,8 +663,8 @@ pub(super) fn adeberry() -> WarpTheme { ) } -pub(super) fn samsung_dark() -> WarpTheme { - WarpTheme::new( +pub(super) fn samsung_dark() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x0C0F16FF)), ColorU::from_u32(0xEEF2FAFF), Fill::Solid(ColorU::from_u32(0x1F6FFFFF)), @@ -676,8 +676,8 @@ pub(super) fn samsung_dark() -> WarpTheme { ) } -pub(super) fn samsung_light() -> WarpTheme { - WarpTheme::new( +pub(super) fn samsung_light() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0xF7F9FCFF)), ColorU::from_u32(0x10131BFF), Fill::Solid(ColorU::from_u32(0x034AE5FF)), @@ -688,8 +688,8 @@ pub(super) fn samsung_light() -> WarpTheme { Some("Samsung Light".to_string()), ) } -pub(super) fn received_referral_reward() -> WarpTheme { - WarpTheme::new( +pub(super) fn received_referral_reward() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0xFFFFFFFF)), ColorU::black(), Fill::Solid(ColorU::from_u32(0xCD51FFFF)), diff --git a/app/src/themes/mod.rs b/app/src/themes/mod.rs index 9c91a3e5..8c0b6dc5 100644 --- a/app/src/themes/mod.rs +++ b/app/src/themes/mod.rs @@ -7,9 +7,9 @@ pub mod theme_creator_modal; pub mod theme_deletion_body; pub mod theme_deletion_modal; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; -pub fn onboarding_theme_picker_themes() -> [WarpTheme; 4] { +pub fn onboarding_theme_picker_themes() -> [GalaxyTheme; 4] { [ default_themes::phenomenon(), default_themes::dark_theme(), diff --git a/app/src/themes/theme.rs b/app/src/themes/theme.rs index f573987a..cdce2d86 100644 --- a/app/src/themes/theme.rs +++ b/app/src/themes/theme.rs @@ -254,7 +254,7 @@ impl InMemoryThemeOptions { self.path = path; } - pub fn theme(&self) -> WarpTheme { + pub fn theme(&self) -> GalaxyTheme { let bg_color = self.chosen_bg_color(); let fg_color = pick_foreground_color(bg_color); let possible_accent_colors: Vec = self @@ -273,7 +273,7 @@ impl InMemoryThemeOptions { (Details::Lighter, light_mode_colors()) }; - WarpTheme::new( + GalaxyTheme::new( bg_color.into(), fg_color, accent_color.into(), @@ -293,14 +293,14 @@ impl InMemoryThemeOptions { } #[derive(Debug, Clone)] -pub struct WarpThemeConfig { - theme_map: HashMap, +pub struct GalaxyThemeConfig { + theme_map: HashMap, } -impl WarpThemeConfig { +impl GalaxyThemeConfig { pub fn new() -> Self { // preload with built-in themes - let theme_map: HashMap = HashMap::from_iter([ + let theme_map: HashMap = HashMap::from_iter([ (ThemeKind::SentReferralReward, sent_referral_reward()), ( ThemeKind::ReceivedReferralReward, @@ -330,10 +330,10 @@ impl WarpThemeConfig { (ThemeKind::SamsungDark, samsung_dark()), (ThemeKind::SamsungLight, samsung_light()), ]); - WarpThemeConfig { theme_map } + GalaxyThemeConfig { theme_map } } - pub fn add_new_theme(&mut self, theme_name: ThemeKind, theme: WarpTheme) { + pub fn add_new_theme(&mut self, theme_name: ThemeKind, theme: GalaxyTheme) { self.theme_map.insert(theme_name, theme); } @@ -341,16 +341,16 @@ impl WarpThemeConfig { CustomTheme::new(name, path).into() } - pub fn theme_items(&self) -> impl Iterator { + pub fn theme_items(&self) -> impl Iterator { self.theme_map.iter() } - pub fn theme(&self, name: &ThemeKind) -> WarpTheme { + pub fn theme(&self, name: &ThemeKind) -> GalaxyTheme { self.theme_map.get(name).cloned().unwrap_or_else(dark_theme) } } -impl Default for WarpThemeConfig { +impl Default for GalaxyThemeConfig { fn default() -> Self { Self::new() } @@ -419,8 +419,8 @@ pub struct PromptColors { pub input_prompt_ssh: ColorU, } -impl From for PromptColors { - fn from(theme: WarpTheme) -> Self { +impl From for PromptColors { + fn from(theme: GalaxyTheme) -> Self { PromptColors { input_prompt_conversation_management: theme.terminal_colors().normal.white.into(), input_prompt_pwd: theme.terminal_colors().normal.magenta.into(), @@ -443,7 +443,7 @@ impl From for PromptColors { } pub fn render_preview( - theme: &WarpTheme, + theme: &GalaxyTheme, font_family: FamilyId, form_factor: Option, ) -> Box { diff --git a/app/src/themes/theme_chooser.rs b/app/src/themes/theme_chooser.rs index 7e52cba8..a1e786f2 100644 --- a/app/src/themes/theme_chooser.rs +++ b/app/src/themes/theme_chooser.rs @@ -1,6 +1,6 @@ use galaxy_editor::editor::NavigationKey; use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ Align, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, DispatchEventResult, Element, Empty, EventHandler, Fill, Flex, Hoverable, Icon, @@ -22,7 +22,7 @@ use pathfinder_color::ColorU; use settings::Setting as _; use crate::resource_center::{mark_feature_used_and_write_to_user_defaults, Tip, TipAction}; -use crate::themes::theme::{RespectSystemTheme, ThemeKind, WarpTheme}; +use crate::themes::theme::{RespectSystemTheme, ThemeKind, GalaxyTheme}; use crate::util::traffic_lights::traffic_light_data; use crate::workspace::PANEL_HEADER_HEIGHT; use crate::{ @@ -34,7 +34,7 @@ use crate::{ report_if_error, settings::{respect_system_theme, ThemeSettings}, themes::theme::SelectedSystemThemes, - user_config::{load_theme_configs, themes_dir, WarpConfig, WarpConfigUpdateEvent}, + user_config::{load_theme_configs, themes_dir, GalaxyConfig, GalaxyConfigUpdateEvent}, util::traffic_lights::{TrafficLightData, TrafficLightSide}, window_settings::WindowSettings, }; @@ -44,7 +44,7 @@ use crate::{ server::telemetry::TelemetryEvent, ui_components::window_focus_dimming::WindowFocusDimming, }; use crate::{ - themes::theme::WarpThemeConfig, + themes::theme::GalaxyThemeConfig, ui_components::buttons::{close_button, icon_button}, ui_components::icons, }; @@ -177,7 +177,7 @@ pub fn init(app: &mut AppContext) { fn theme_chooser_items( referral_theme_status: &ReferralThemeStatus, - theme_config: &WarpThemeConfig, + theme_config: &GalaxyThemeConfig, ) -> Vec { let sent_referral_theme_active = referral_theme_status.sent_referral_theme_active(); let received_referral_theme_active = referral_theme_status.received_referral_theme_active(); @@ -224,9 +224,9 @@ impl ThemeChooser { me.update_themes(ctx); }); - let warp_config_handle = WarpConfig::handle(ctx); + let warp_config_handle = GalaxyConfig::handle(ctx); ctx.subscribe_to_model(&warp_config_handle, |me, _, event, ctx| { - if let WarpConfigUpdateEvent::Themes = event { + if let GalaxyConfigUpdateEvent::Themes = event { me.update_themes(ctx); ctx.notify(); } @@ -247,7 +247,7 @@ impl ThemeChooser { let themes = theme_chooser_items( referral_theme_status.as_ref(ctx), - WarpConfig::as_ref(ctx).theme_config(), + GalaxyConfig::as_ref(ctx).theme_config(), ); Self { @@ -311,7 +311,7 @@ impl ThemeChooser { ctx.spawn( async move { load_theme_configs(&themes_dir()) }, move |theme_chooser, loaded_themes, ctx| { - ctx.update_model(&WarpConfig::handle(ctx), move |warp_config, ctx| { + ctx.update_model(&GalaxyConfig::handle(ctx), move |warp_config, ctx| { warp_config.update_theme_config(loaded_themes, ctx); }); theme_chooser.update_themes(ctx); @@ -324,7 +324,7 @@ impl ThemeChooser { ctx.spawn( async move { load_theme_configs(&themes_dir()) }, move |theme_chooser, loaded_themes, ctx| { - ctx.update_model(&WarpConfig::handle(ctx), move |warp_config, ctx| { + ctx.update_model(&GalaxyConfig::handle(ctx), move |warp_config, ctx| { warp_config.update_theme_config(loaded_themes, ctx); }); theme_chooser.update_themes(ctx); @@ -518,7 +518,7 @@ impl ThemeChooser { fn update_themes(&mut self, ctx: &mut ViewContext) { *self.themes = theme_chooser_items( self.referral_theme_status.as_ref(ctx), - WarpConfig::as_ref(ctx).theme_config(), + GalaxyConfig::as_ref(ctx).theme_config(), ); } @@ -848,7 +848,7 @@ impl View for ThemeChooser { Some(AccessibilityContent::new( "Theme chooser. Unfortunately, theme chooser window isn't compatible with screen readers yet.", "Press escape to close.", - WarpA11yRole::WindowRole, + GalaxyA11yRole::WindowRole, )) } @@ -878,12 +878,12 @@ impl View for ThemeChooser { #[derive(Clone)] struct ThemeChooserItem { pub kind: ThemeKind, - warp_theme: WarpTheme, + warp_theme: GalaxyTheme, mouse_state: MouseStateHandle, } impl ThemeChooserItem { - pub fn new(kind: ThemeKind, warp_theme: WarpTheme) -> Self { + pub fn new(kind: ThemeKind, warp_theme: GalaxyTheme) -> Self { Self { kind, warp_theme, diff --git a/app/src/themes/theme_creator_body.rs b/app/src/themes/theme_creator_body.rs index 94f2b3ff..48aa1d5b 100644 --- a/app/src/themes/theme_creator_body.rs +++ b/app/src/themes/theme_creator_body.rs @@ -7,7 +7,7 @@ use crate::{ send_telemetry_from_ctx, server::telemetry::TelemetryEvent, themes::theme::CustomTheme, }; #[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, @@ -220,7 +220,7 @@ impl ThemeCreatorBody { /// Note: the image option should be (original_theme_image_path, theme_name, image_extension). #[cfg(feature = "local_fs")] pub fn write_theme( - theme: &WarpTheme, + theme: &GalaxyTheme, dir: PathBuf, theme_yaml_file_name: String, image_option: Option<(PathBuf, String, &str)>, diff --git a/app/src/themes/theme_deletion_body.rs b/app/src/themes/theme_deletion_body.rs index 9e628274..e2c18cd6 100644 --- a/app/src/themes/theme_deletion_body.rs +++ b/app/src/themes/theme_deletion_body.rs @@ -2,7 +2,7 @@ use crate::appearance::Appearance; use crate::send_telemetry_from_ctx; use crate::server::telemetry::TelemetryEvent; use crate::settings::{active_theme_kind, ThemeSettings}; -use crate::themes::theme::{ThemeKind, WarpTheme}; +use crate::themes::theme::{ThemeKind, GalaxyTheme}; use crate::user_config; use crate::user_config::util::from_yaml; use galaxyui::assets::asset_cache::AssetSource; @@ -77,7 +77,7 @@ impl ThemeDeletionBody { // Check if the theme directory exists if fs::metadata(&dir).is_ok() { if let Some(ThemeKind::Custom(custom_theme)) = &self.theme_kind { - if let Ok(theme_from_yaml) = from_yaml::(custom_theme.path()) { + if let Ok(theme_from_yaml) = from_yaml::(custom_theme.path()) { // If theme has an image if let Some(image) = theme_from_yaml.background_image() { // Only delete the image if it is in the ./warp/themes directory. diff --git a/app/src/themes/theme_test.rs b/app/src/themes/theme_test.rs index 3639c208..0cb58376 100644 --- a/app/src/themes/theme_test.rs +++ b/app/src/themes/theme_test.rs @@ -23,7 +23,7 @@ fn in_memory_theme_generation_test() { let mountains_bg_path_string = mountains_bg_path.to_str().unwrap_or_default().to_owned(); assert_eq!( in_memory_theme.theme(), - WarpTheme::new( + GalaxyTheme::new( // the theme defaults to the 0th bg color ColorU::new(35, 31, 44, OPAQUE).into(), // this background color makes it a "dark" theme, so the foreground is white @@ -47,7 +47,7 @@ fn in_memory_theme_generation_test() { assert_eq!( in_memory_theme.theme(), - WarpTheme::new( + GalaxyTheme::new( // now the background is the 2nd one ColorU::new(229, 142, 113, OPAQUE).into(), // changing the background color made this a light theme diff --git a/app/src/ui_components/buttons.rs b/app/src/ui_components/buttons.rs index aba3703c..a0391763 100644 --- a/app/src/ui_components/buttons.rs +++ b/app/src/ui_components/buttons.rs @@ -2,7 +2,7 @@ use super::icons::{Icon, ICON_DIMENSIONS}; use super::{blended_colors, BORDER_RADIUS}; use crate::appearance::Appearance; use crate::themes::theme::Fill; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use galaxyui::elements::Radius; use galaxyui::elements::{CornerRadius, MouseStateHandle}; use galaxyui::ui_components::button::Button; @@ -33,7 +33,7 @@ pub struct AllButtonStyles { disabled_styles: Option, } -fn all_icon_button_styles(warp_theme: &WarpTheme, mode: ButtonMode) -> AllButtonStyles { +fn all_icon_button_styles(warp_theme: &GalaxyTheme, mode: ButtonMode) -> AllButtonStyles { AllButtonStyles { default_styles: icon_button_styles(warp_theme, mode, ButtonState::Default), hovered_styles: Some(icon_button_styles(warp_theme, mode, ButtonState::Hover)), @@ -43,7 +43,7 @@ fn all_icon_button_styles(warp_theme: &WarpTheme, mode: ButtonMode) -> AllButton } fn icon_button_styles( - warp_theme: &WarpTheme, + warp_theme: &GalaxyTheme, mode: ButtonMode, state: ButtonState, ) -> UiComponentStyles { @@ -86,7 +86,7 @@ fn icon_button_styles( styles } -fn combo_inner_button_styles(warp_theme: &WarpTheme, state: ButtonState) -> UiComponentStyles { +fn combo_inner_button_styles(warp_theme: &GalaxyTheme, state: ButtonState) -> UiComponentStyles { let background = match state { ButtonState::Default => None, ButtonState::Hover => Some(blended_colors::neutral_2(warp_theme)), @@ -138,7 +138,7 @@ pub fn combo_inner_button( button } -fn icon_color(warp_theme: &WarpTheme, mode: ButtonMode) -> Fill { +fn icon_color(warp_theme: &GalaxyTheme, mode: ButtonMode) -> Fill { match mode { ButtonMode::Base => warp_theme.foreground(), ButtonMode::Accent => blended_colors::accent(warp_theme), diff --git a/app/src/ui_components/icon_with_status.rs b/app/src/ui_components/icon_with_status.rs index 5ad9d022..7f017964 100644 --- a/app/src/ui_components/icon_with_status.rs +++ b/app/src/ui_components/icon_with_status.rs @@ -1,6 +1,6 @@ -use galaxy_core::ui::icons::Icon as WarpIcon; +use galaxy_core::ui::icons::Icon as GalaxyIcon; use galaxy_core::ui::theme::color::internal_colors; -use galaxy_core::ui::theme::{Fill as WarpThemeFill, WarpTheme}; +use galaxy_core::ui::theme::{Fill as GalaxyThemeFill, GalaxyTheme}; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, CornerRadius, Element, OffsetPositioning, ParentAnchor, ParentElement, ParentOffsetBounds, Radius, Stack, @@ -30,8 +30,8 @@ pub(crate) struct IconWithStatusSizing { pub(crate) enum IconWithStatusVariant { /// A generic icon with a given color on an overlay background. Neutral { - icon: WarpIcon, - icon_color: WarpThemeFill, + icon: GalaxyIcon, + icon_color: GalaxyThemeFill, }, /// A pre-built icon element on an overlay background. NeutralElement { icon_element: Box }, @@ -51,8 +51,8 @@ pub(crate) enum IconWithStatusVariant { pub(crate) fn render_icon_with_status( variant: IconWithStatusVariant, sizing: &IconWithStatusSizing, - theme: &WarpTheme, - badge_ring_background: WarpThemeFill, + theme: &GalaxyTheme, + badge_ring_background: GalaxyThemeFill, ) -> Box { let sub_text = theme.sub_text_color(theme.background()); @@ -85,9 +85,9 @@ pub(crate) fn render_icon_with_status( } IconWithStatusVariant::OzAgent { status, is_ambient } => { let icon = if is_ambient { - WarpIcon::OzCloud + GalaxyIcon::OzCloud } else { - WarpIcon::Oz + GalaxyIcon::Oz }; let inner = ConstrainedBox::new( icon.to_galaxyui_icon(theme.main_text_color(theme.background())) @@ -119,10 +119,10 @@ pub(crate) fn render_icon_with_status( let icon_element = agent .icon() .map(|icon| { - icon.to_galaxyui_icon(WarpThemeFill::Solid(icon_color)) + icon.to_galaxyui_icon(GalaxyThemeFill::Solid(icon_color)) .finish() }) - .unwrap_or_else(|| WarpIcon::Terminal.to_galaxyui_icon(sub_text).finish()); + .unwrap_or_else(|| GalaxyIcon::Terminal.to_galaxyui_icon(sub_text).finish()); let inner = ConstrainedBox::new(icon_element) .with_width(sizing.icon_size) .with_height(sizing.icon_size) @@ -150,15 +150,15 @@ fn render_with_optional_status_badge( circle: Box, status: Option<&ConversationStatus>, sizing: &IconWithStatusSizing, - theme: &WarpTheme, - badge_ring_background: WarpThemeFill, + theme: &GalaxyTheme, + badge_ring_background: GalaxyThemeFill, ) -> Box { let Some(status) = status else { return circle; }; let (icon, color) = status.status_icon_and_color(theme); let badge_icon = - ConstrainedBox::new(icon.to_galaxyui_icon(WarpThemeFill::Solid(color)).finish()) + ConstrainedBox::new(icon.to_galaxyui_icon(GalaxyThemeFill::Solid(color)).finish()) .with_width(sizing.badge_icon_size) .with_height(sizing.badge_icon_size) .finish(); diff --git a/app/src/uri/browser_url_handler.rs b/app/src/uri/browser_url_handler.rs index f07eaab1..3d1c362f 100644 --- a/app/src/uri/browser_url_handler.rs +++ b/app/src/uri/browser_url_handler.rs @@ -23,7 +23,7 @@ pub fn update_browser_url(url: Option, force_redirect: bool) { .unwrap_or_else(|_| { log::error!("Failed to replace browser state"); crate::platform::wasm::emit_event( - crate::platform::wasm::WarpEvent::ErrorLogged { + crate::platform::wasm::GalaxyEvent::ErrorLogged { error: String::from("Failed to replace browser state"), }, ); diff --git a/app/src/uri/mod.rs b/app/src/uri/mod.rs index e965efea..39280c69 100644 --- a/app/src/uri/mod.rs +++ b/app/src/uri/mod.rs @@ -7,7 +7,7 @@ pub mod browser_url_handler; use crate::ai::active_agent_views_model::{ActiveAgentViewsModel, ConversationOrTaskId}; use crate::ai::agent::api::ServerConversationToken; -use crate::drive::OpenWarpDriveObjectSettings; +use crate::drive::OpenGalaxyDriveObjectSettings; use crate::launch_configs::launch_config::LaunchConfig; use crate::linear::{LinearAction, LinearIssueWork}; use crate::root_view::{open_new_window_get_handles, OpenLaunchConfigArg}; @@ -16,7 +16,7 @@ use crate::server::telemetry::{LaunchConfigUiLocation, TelemetryEvent}; use crate::util::openable_file_type::{is_file_openable_in_warp, is_markdown_file}; use crate::workspace::{Workspace, WorkspaceAction, WorkspaceRegistry}; use crate::{cloud_object::ObjectType, workspace::ToastStack}; -use crate::{drive::OpenWarpDriveObjectArgs, view_components::DismissibleToast}; +use crate::{drive::OpenGalaxyDriveObjectArgs, view_components::DismissibleToast}; use crate::{features::FeatureFlag, workspace::active_terminal_in_window}; use crate::ai::ambient_agents::github_auth_notifier::GitHubAuthNotifier; @@ -280,10 +280,10 @@ impl UriHost { ctx.root_view_id(window_id) .map(|view_id| (window_id, view_id)) }); - let args = OpenWarpDriveObjectArgs { + let args = OpenGalaxyDriveObjectArgs { object_type, server_id, - settings: OpenWarpDriveObjectSettings { + settings: OpenGalaxyDriveObjectSettings { focused_folder_id, invitee_email, }, diff --git a/app/src/uri/parse_url_paths.rs b/app/src/uri/parse_url_paths.rs index 60b03e4b..4a9db51a 100644 --- a/app/src/uri/parse_url_paths.rs +++ b/app/src/uri/parse_url_paths.rs @@ -1,12 +1,12 @@ use crate::cloud_object::extract_server_id_and_object_type_from_warp_drive_link; -use crate::drive::OpenWarpDriveObjectArgs; +use crate::drive::OpenGalaxyDriveObjectArgs; use crate::ChannelState; use url::Url; #[derive(PartialEq, Debug)] pub enum WarpWebLink { Session, - DriveObject(Box), + DriveObject(Box), } pub fn get_item_data_from_warp_link(url: &Url) -> Option { diff --git a/app/src/uri/uri_test.rs b/app/src/uri/uri_test.rs index a4d0df78..5e3e08ad 100644 --- a/app/src/uri/uri_test.rs +++ b/app/src/uri/uri_test.rs @@ -155,10 +155,10 @@ fn test_warp_web_link_notebook() { )) .unwrap() ), - Some(WarpWebLink::DriveObject(Box::new(OpenWarpDriveObjectArgs { + Some(WarpWebLink::DriveObject(Box::new(OpenGalaxyDriveObjectArgs { object_type: ObjectType::Notebook, server_id: ServerId::from_string_lossy("LkDlnAe34vfYD2JXsAkssc"), - settings: OpenWarpDriveObjectSettings { + settings: OpenGalaxyDriveObjectSettings { focused_folder_id: Some(ServerId::from(123)), invitee_email: Some(String::from("test@example.com")), }, @@ -191,10 +191,10 @@ fn test_warp_web_link_workflow() { )) .unwrap() ), - Some(WarpWebLink::DriveObject(Box::new(OpenWarpDriveObjectArgs { + Some(WarpWebLink::DriveObject(Box::new(OpenGalaxyDriveObjectArgs { object_type: ObjectType::Workflow, server_id: ServerId::from_string_lossy("ZCJSkai2gpwTqpBFs5HOfZ"), - settings: OpenWarpDriveObjectSettings::default(), + settings: OpenGalaxyDriveObjectSettings::default(), }))) ); } diff --git a/app/src/uri/web_intent_parser.rs b/app/src/uri/web_intent_parser.rs index eba7054e..2f44b770 100644 --- a/app/src/uri/web_intent_parser.rs +++ b/app/src/uri/web_intent_parser.rs @@ -175,7 +175,7 @@ pub fn open_url_on_desktop(url: &Url) { | Ok(WebIntent::DriveObject(intent)) | Ok(WebIntent::SessionView(intent)) | Ok(WebIntent::Action(intent)) => { - crate::platform::wasm::emit_event(crate::platform::wasm::WarpEvent::OpenOnNative { + crate::platform::wasm::emit_event(crate::platform::wasm::GalaxyEvent::OpenOnNative { url: intent.into(), }); } diff --git a/app/src/user_config/mod.rs b/app/src/user_config/mod.rs index 61d89340..455978d6 100644 --- a/app/src/user_config/mod.rs +++ b/app/src/user_config/mod.rs @@ -5,12 +5,12 @@ pub mod util; mod imp; use crate::tab_configs::{TabConfig, TabConfigError}; -use crate::themes::theme::WarpThemeConfig; +use crate::themes::theme::GalaxyThemeConfig; use crate::{ launch_configs::launch_config::LaunchConfig, themes::theme::ThemeKind, workflows::workflow::Workflow, }; -use galaxy_core::ui::theme::WarpTheme; +use galaxy_core::ui::theme::GalaxyTheme; use galaxyui::{Entity, ModelContext, SingletonEntity}; use lazy_static::lazy_static; #[cfg(feature = "local_fs")] @@ -53,7 +53,7 @@ lazy_static! { } #[derive(Clone)] -pub enum WarpConfigUpdateEvent { +pub enum GalaxyConfigUpdateEvent { Themes, #[cfg_attr(not(feature = "local_fs"), expect(dead_code))] LocalUserWorkflows, @@ -82,24 +82,24 @@ pub enum WarpConfigUpdateEvent { /// tab configs, etc.) and, on platforms where it differs, `config_local_dir()` /// (`settings.toml`, `keybindings.yaml`, `user_preferences.json`). #[derive(Default)] -pub struct WarpConfig { +pub struct GalaxyConfig { launch_configs: Vec, tab_configs: Vec, #[cfg_attr(target_family = "wasm", allow(dead_code))] tab_config_errors: Vec, - theme_config: WarpThemeConfig, + theme_config: GalaxyThemeConfig, local_user_workflows: Vec, } -/// Platform-independent parts of WarpConfig. +/// Platform-independent parts of GalaxyConfig. /// /// Additional platform-dependent functionality can be found in impl blocks /// in native.rs and wasm.rs. -impl WarpConfig { +impl GalaxyConfig { #[cfg(test)] pub fn mock(_ctx: &mut ModelContext) -> Self { Self { - theme_config: WarpThemeConfig::new(), + theme_config: GalaxyThemeConfig::new(), ..Default::default() } } @@ -112,7 +112,7 @@ impl WarpConfig { &self.tab_configs } - pub fn theme_config(&self) -> &WarpThemeConfig { + pub fn theme_config(&self) -> &GalaxyThemeConfig { &self.theme_config } @@ -120,7 +120,7 @@ impl WarpConfig { &self.local_user_workflows } - /// Saving the newly created launch configuration to the WarpConfig that we currently + /// Saving the newly created launch configuration to the GalaxyConfig that we currently /// have. pub fn append_launch_config( &mut self, @@ -129,27 +129,27 @@ impl WarpConfig { ) { if !self.launch_configs.contains(launch_config) { self.launch_configs.push(launch_config.to_owned()); - ctx.emit(WarpConfigUpdateEvent::LaunchConfigs); + ctx.emit(GalaxyConfigUpdateEvent::LaunchConfigs); } } pub fn update_theme_config( &mut self, - theme_config: WarpThemeConfig, + theme_config: GalaxyThemeConfig, ctx: &mut ModelContext, ) { self.theme_config = theme_config; - ctx.emit(WarpConfigUpdateEvent::Themes); + ctx.emit(GalaxyConfigUpdateEvent::Themes); } pub fn add_new_theme_to_config( &mut self, theme_name: ThemeKind, - theme: WarpTheme, + theme: GalaxyTheme, ctx: &mut ModelContext, ) { self.theme_config.add_new_theme(theme_name, theme); - ctx.emit(WarpConfigUpdateEvent::Themes); + ctx.emit(GalaxyConfigUpdateEvent::Themes); } /// Eagerly removes a tab config by its source path and emits a `TabConfigs` event. @@ -161,7 +161,7 @@ impl WarpConfig { self.tab_configs .retain(|c| c.source_path.as_deref() != Some(path)); if self.tab_configs.len() != before { - ctx.emit(WarpConfigUpdateEvent::TabConfigs); + ctx.emit(GalaxyConfigUpdateEvent::TabConfigs); } } } @@ -393,11 +393,11 @@ pub(crate) fn find_unused_worktree_config_path(dir: &Path, branch_name: &str) -> } } -impl Entity for WarpConfig { - type Event = WarpConfigUpdateEvent; +impl Entity for GalaxyConfig { + type Event = GalaxyConfigUpdateEvent; } -impl SingletonEntity for WarpConfig {} +impl SingletonEntity for GalaxyConfig {} #[cfg(test)] #[path = "mod_test.rs"] diff --git a/app/src/user_config/native.rs b/app/src/user_config/native.rs index 2991e309..19c1eb28 100644 --- a/app/src/user_config/native.rs +++ b/app/src/user_config/native.rs @@ -11,10 +11,10 @@ use repo_metadata::RepositoryUpdate; use crate::features::FeatureFlag; use crate::launch_configs::launch_config::LaunchConfig; use crate::tab_configs::{TabConfig, TabConfigError}; -use crate::themes::theme::WarpThemeConfig; -use crate::warp_managed_paths_watcher::{ - repository_update_touches_path, repository_update_touches_prefix, WarpManagedPathsWatcher, - WarpManagedPathsWatcherEvent, +use crate::themes::theme::GalaxyThemeConfig; +use crate::galaxy_managed_paths_watcher::{ + repository_update_touches_path, repository_update_touches_prefix, GalaxyManagedPathsWatcher, + GalaxyManagedPathsWatcherEvent, }; use crate::workflows::workflow::Workflow; @@ -23,11 +23,11 @@ use super::util::{ parse_multi_workflow_dir_entry, parse_single_theme_dir_entry, parse_tab_config_dir_entry, }; use super::{ - launch_configs_dir, tab_configs_dir, themes_dir, workflows_dir, WarpConfigUpdateEvent, + launch_configs_dir, tab_configs_dir, themes_dir, workflows_dir, GalaxyConfigUpdateEvent, LAUNCH_CONFIG_COMMENT, }; -impl super::WarpConfig { +impl super::GalaxyConfig { pub fn new(ctx: &mut ModelContext) -> Self { // Load launch configs, and workflows from disk asynchronously on a background // thread. @@ -39,7 +39,7 @@ impl super::WarpConfig { async move { load_launch_configs(&launch_configs_dir()) }, |me, launch_configs, ctx| { me.launch_configs = launch_configs; - ctx.emit(WarpConfigUpdateEvent::LaunchConfigs); + ctx.emit(GalaxyConfigUpdateEvent::LaunchConfigs); }, ); if FeatureFlag::TabConfigs.is_enabled() { @@ -48,7 +48,7 @@ impl super::WarpConfig { |me, (tab_configs, tab_config_errors), ctx| { me.tab_configs = tab_configs; me.tab_config_errors = tab_config_errors; - ctx.emit(WarpConfigUpdateEvent::TabConfigs); + ctx.emit(GalaxyConfigUpdateEvent::TabConfigs); // Don't emit TabConfigErrors on startup — the error toast // should only appear when the user saves a config file, // not on app restart. @@ -59,11 +59,11 @@ impl super::WarpConfig { async move { load_workflows(&workflows_dir()) }, |me, user_workflows, ctx| { me.local_user_workflows = user_workflows; - ctx.emit(WarpConfigUpdateEvent::LocalUserWorkflows); + ctx.emit(GalaxyConfigUpdateEvent::LocalUserWorkflows); }, ); ctx.subscribe_to_model( - &WarpManagedPathsWatcher::handle(ctx), + &GalaxyManagedPathsWatcher::handle(ctx), Self::handle_warp_managed_paths_event, ); @@ -75,10 +75,10 @@ impl super::WarpConfig { fn handle_warp_managed_paths_event( &mut self, - event: &WarpManagedPathsWatcherEvent, + event: &GalaxyManagedPathsWatcherEvent, ctx: &mut ModelContext, ) { - let WarpManagedPathsWatcherEvent::FilesChanged(update) = event; + let GalaxyManagedPathsWatcherEvent::FilesChanged(update) = event; if update_touches_dir(update, &themes_dir()) { let theme_dir = themes_dir(); @@ -86,7 +86,7 @@ impl super::WarpConfig { async move { load_theme_configs(&theme_dir) }, |me, theme_config, ctx| { me.theme_config = theme_config; - ctx.emit(WarpConfigUpdateEvent::Themes); + ctx.emit(GalaxyConfigUpdateEvent::Themes); }, ); } @@ -97,7 +97,7 @@ impl super::WarpConfig { async move { load_workflows(&workflow_dir) }, |me, workflows, ctx| { me.local_user_workflows = workflows; - ctx.emit(WarpConfigUpdateEvent::LocalUserWorkflows); + ctx.emit(GalaxyConfigUpdateEvent::LocalUserWorkflows); }, ); } @@ -108,7 +108,7 @@ impl super::WarpConfig { async move { load_launch_configs(&launch_config_dir) }, |me, launch_configs, ctx| { me.launch_configs = launch_configs; - ctx.emit(WarpConfigUpdateEvent::LaunchConfigs); + ctx.emit(GalaxyConfigUpdateEvent::LaunchConfigs); }, ); } @@ -120,9 +120,9 @@ impl super::WarpConfig { |me, (configs, errors), ctx| { me.tab_configs = configs; me.tab_config_errors = errors.clone(); - ctx.emit(WarpConfigUpdateEvent::TabConfigs); + ctx.emit(GalaxyConfigUpdateEvent::TabConfigs); if !errors.is_empty() { - ctx.emit(WarpConfigUpdateEvent::TabConfigErrors(errors)); + ctx.emit(GalaxyConfigUpdateEvent::TabConfigErrors(errors)); } }, ); @@ -131,7 +131,7 @@ impl super::WarpConfig { if FeatureFlag::SettingsFile.is_enabled() && update_touches_path(update, &crate::settings::user_preferences_toml_file_path()) { - ctx.emit(WarpConfigUpdateEvent::Settings); + ctx.emit(GalaxyConfigUpdateEvent::Settings); } } @@ -165,8 +165,8 @@ impl super::WarpConfig { } } -pub fn load_theme_configs(theme_path: &Path) -> WarpThemeConfig { - let mut theme_configs = WarpThemeConfig::new(); +pub fn load_theme_configs(theme_path: &Path) -> GalaxyThemeConfig { + let mut theme_configs = GalaxyThemeConfig::new(); for_each_dir_entry(theme_path, parse_single_theme_dir_entry) .into_iter() .for_each(|(theme_name, theme)| theme_configs.add_new_theme(theme_name, theme)); diff --git a/app/src/user_config/util.rs b/app/src/user_config/util.rs index baff692c..adbcba0f 100644 --- a/app/src/user_config/util.rs +++ b/app/src/user_config/util.rs @@ -11,7 +11,7 @@ use walkdir::{DirEntry, WalkDir}; use crate::launch_configs::launch_config::LaunchConfig; use crate::tab_configs::{TabConfig, TabConfigError}; -use crate::themes::theme::{ThemeKind, WarpTheme, WarpThemeConfig}; +use crate::themes::theme::{ThemeKind, GalaxyTheme, GalaxyThemeConfig}; use crate::workflows::workflow::Workflow; const CONFIG_FILE_SUFFIXES: &[&str] = &[".yaml", ".yml"]; @@ -141,15 +141,15 @@ fn name_to_camel_case(name: &str) -> String { name.split('_').map(title_case).join(" ") } -pub(super) fn parse_single_theme_dir_entry(item: &DirEntry) -> Option<(ThemeKind, WarpTheme)> { - parse_single_item_file(item, |file_name, mut theme: WarpTheme| { +pub(super) fn parse_single_theme_dir_entry(item: &DirEntry) -> Option<(ThemeKind, GalaxyTheme)> { + parse_single_item_file(item, |file_name, mut theme: GalaxyTheme| { // If the name exists in the .yaml, we use it. Otherwise we treat a "human readable" version of the filename as the theme name. let theme_kind = if let Some(name) = theme.name() { - WarpThemeConfig::file_to_theme(name, item.path().into()) + GalaxyThemeConfig::file_to_theme(name, item.path().into()) } else { let name = file_name_to_human_readable_name(file_name.as_str()); theme.set_name(name.clone()); - WarpThemeConfig::file_to_theme(name, item.path().into()) + GalaxyThemeConfig::file_to_theme(name, item.path().into()) }; (theme_kind, theme) diff --git a/app/src/user_config/wasm.rs b/app/src/user_config/wasm.rs index 0d4ccbb1..16e6f92a 100644 --- a/app/src/user_config/wasm.rs +++ b/app/src/user_config/wasm.rs @@ -3,23 +3,23 @@ use std::path::Path; use galaxyui::ModelContext; use crate::launch_configs::launch_config::LaunchConfig; -use crate::themes::theme::WarpThemeConfig; +use crate::themes::theme::GalaxyThemeConfig; use crate::workflows::workflow::Workflow; -impl super::WarpConfig { +impl super::GalaxyConfig { pub fn new(_ctx: &mut ModelContext) -> Self { Self { launch_configs: Default::default(), tab_configs: Default::default(), tab_config_errors: Default::default(), - theme_config: WarpThemeConfig::new(), + theme_config: GalaxyThemeConfig::new(), local_user_workflows: Default::default(), } } } /// Loads all themes relative to the `workflow_path`. -pub fn load_theme_configs(_theme_path: &Path) -> WarpThemeConfig { +pub fn load_theme_configs(_theme_path: &Path) -> GalaxyThemeConfig { // There's no local filesystem for wasm, so we'll never be able to retrieve // themes from any path. Default::default() diff --git a/app/src/util/bindings.rs b/app/src/util/bindings.rs index 2e5b334c..208105e2 100644 --- a/app/src/util/bindings.rs +++ b/app/src/util/bindings.rs @@ -32,7 +32,7 @@ pub const MAC_MENUS_CONTEXT: DescriptionContext = DescriptionContext::Custom("ma pub enum CustomAction { NewTab, NewFile, - ShowAboutWarp, + ShowAboutGalaxy, ShowSettings, ConfigureKeybindings, ShowAccount, @@ -104,7 +104,7 @@ pub enum CustomAction { ToggleSyncTerminalInputsInCurrentTab, DisableSyncTerminalInputs, ReopenClosedSession, - ToggleWarpDrive, + ToggleGalaxyDrive, AddWindow, CloseCurrentSession, CloseWindow, @@ -390,7 +390,7 @@ pub fn custom_tag_to_keystroke(custom: CustomTag) -> Option { // This is one of the app's hardcoded keybindings. CustomAction::AddWindow => Keystroke::parse(cmd_or_ctrl_shift("n")).ok(), - CustomAction::ToggleWarpDrive => { + CustomAction::ToggleGalaxyDrive => { if OperatingSystem::get().is_mac() { Keystroke::parse("cmd-\\").ok() } else { @@ -435,7 +435,7 @@ pub fn custom_tag_to_keystroke(custom: CustomTag) -> Option { } CustomAction::NewTerminalTab | CustomAction::NewFile - | CustomAction::ShowAboutWarp + | CustomAction::ShowAboutGalaxy | CustomAction::SplitPaneLeft | CustomAction::SelectAllBlocks | CustomAction::SplitPaneUp diff --git a/app/src/util/traffic_lights.rs b/app/src/util/traffic_lights.rs index 64e3c5c5..6e5f6a15 100644 --- a/app/src/util/traffic_lights.rs +++ b/app/src/util/traffic_lights.rs @@ -49,7 +49,7 @@ use windows_only::*; #[cfg(not(target_os = "windows"))] use galaxyui::elements::Empty; -use crate::themes::theme::WarpTheme; +use crate::themes::theme::GalaxyTheme; use galaxyui::elements::MouseStateHandle; use galaxyui::platform::FullscreenState; use galaxyui::{AppContext, Element, WindowId}; @@ -150,7 +150,7 @@ impl TrafficLightData { &self, fullscreen_state: FullscreenState, mouse_states: &TrafficLightMouseStates, - theme: &WarpTheme, + theme: &GalaxyTheme, _app: &AppContext, ) -> Box { if !cfg!(target_os = "linux") { @@ -286,7 +286,7 @@ impl TrafficLightData { fn render_button( mouse_state: MouseStateHandle, child: Box, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Hoverable { Hoverable::new(mouse_state, |state| { let background_color = if state.is_hovered() { @@ -311,7 +311,7 @@ impl TrafficLightData { &self, fullscreen_state: FullscreenState, mouse_states: &TrafficLightMouseStates, - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> Box { self.render_tab_row(fullscreen_state, mouse_states, theme, app) @@ -447,7 +447,7 @@ impl TrafficLightData { &self, _fullscreen_state: FullscreenState, _mouse_states: &TrafficLightMouseStates, - _theme: &WarpTheme, + _theme: &GalaxyTheme, _app: &AppContext, ) -> Box { Empty::new().finish() diff --git a/app/src/util/traffic_lights/windows/renderer.rs b/app/src/util/traffic_lights/windows/renderer.rs index 3487f49d..77bbad4e 100644 --- a/app/src/util/traffic_lights/windows/renderer.rs +++ b/app/src/util/traffic_lights/windows/renderer.rs @@ -4,7 +4,7 @@ use crate::util::traffic_lights::windows::RendererState; use crate::util::traffic_lights::windows_only::WINDOWS_BRIGHT_RED; use crate::util::traffic_lights::{TrafficLightData, TrafficLightMouseStates}; use crate::workspace::TOTAL_TAB_BAR_HEIGHT; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxyui::elements::{ Align, ConstrainedBox, Container, CrossAxisAlignment, Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Text, @@ -48,28 +48,28 @@ impl WindowsTrafficLightIcon { } } - fn background_hover_color(&self, theme: &WarpTheme) -> Fill { + fn background_hover_color(&self, theme: &GalaxyTheme) -> Fill { match self { Self::Close => WINDOWS_BRIGHT_RED.into(), Self::Minimize | Self::Maximize | Self::Restore => theme.surface_3(), } } - fn icon_hover_color(&self, theme: &WarpTheme) -> ColorU { + fn icon_hover_color(&self, theme: &GalaxyTheme) -> ColorU { match self { Self::Close => ColorU::white(), Self::Minimize | Self::Maximize | Self::Restore => self.icon_color(theme), } } - fn icon_color(&self, theme: &WarpTheme) -> ColorU { + fn icon_color(&self, theme: &GalaxyTheme) -> ColorU { theme.foreground().into_solid() } fn render( &self, mouse_state_handle: MouseStateHandle, - theme: &WarpTheme, + theme: &GalaxyTheme, icon_font_family: FamilyId, action_name: &'static str, ) -> Box { @@ -107,7 +107,7 @@ impl WindowsTrafficLightIcon { fn render_tab_row_with_glyph_icons( fullscreen_state: FullscreenState, mouse_states: &TrafficLightMouseStates, - theme: &WarpTheme, + theme: &GalaxyTheme, icon_font_family: FamilyId, ) -> Box { let flex = Flex::row() @@ -158,7 +158,7 @@ impl TrafficLightData { &self, fullscreen_state: FullscreenState, mouse_states: &TrafficLightMouseStates, - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> Box { match RendererState::handle(app).as_ref(app).icon_font_family() { @@ -185,7 +185,7 @@ impl TrafficLightData { &self, fullscreen_state: FullscreenState, mouse_states: &TrafficLightMouseStates, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let fg_color = theme.foreground().into_solid(); ConstrainedBox::new( diff --git a/app/src/view_components/find.rs b/app/src/view_components/find.rs index 23182d20..41c08dc1 100644 --- a/app/src/view_components/find.rs +++ b/app/src/view_components/find.rs @@ -14,7 +14,7 @@ use galaxyui::elements::{ChildAnchor, OffsetPositioning, Radius, SavePosition, S use galaxyui::keymap::EditableBinding; use galaxyui::ui_components::components::UiComponent; pub use galaxyui::{ - accessibility::{AccessibilityContent, WarpA11yRole}, + accessibility::{AccessibilityContent, GalaxyA11yRole}, elements::{ParentElement as _, Stack}, geometry::vector::vec2f, AppContext, @@ -258,10 +258,10 @@ impl + 'static> Find { self.model.as_ref(ctx).match_count() ), "Use enter and shift-enter to navigate between matches. Escape to quit.", - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, ) } else { - AccessibilityContent::new_without_help("No results.", WarpA11yRole::UserAction) + AccessibilityContent::new_without_help("No results.", GalaxyA11yRole::UserAction) }; ctx.emit_a11y_content(content); } @@ -500,7 +500,7 @@ impl + 'static> View for Find { Some(AccessibilityContent::new( "Type searched phrase.", "Press escape to quit, use enter and shift-enter to navigate between matches", - WarpA11yRole::TextareaRole, + GalaxyA11yRole::TextareaRole, )) } diff --git a/app/src/wasm_nux_dialog.rs b/app/src/wasm_nux_dialog.rs index 3035bd23..d9efe8fa 100644 --- a/app/src/wasm_nux_dialog.rs +++ b/app/src/wasm_nux_dialog.rs @@ -269,7 +269,7 @@ impl TypedActionView for WasmNUXDialog { if let Some(url) = web_intent_parser::parse_web_intent_from_current_url() { // Signals to the react app to open the native app. crate::platform::wasm::emit_event( - crate::platform::wasm::WarpEvent::OpenOnNative { + crate::platform::wasm::GalaxyEvent::OpenOnNative { url: String::from(url.as_str()), }, ); diff --git a/app/src/workflows/categories.rs b/app/src/workflows/categories.rs index 659635b4..87363c94 100644 --- a/app/src/workflows/categories.rs +++ b/app/src/workflows/categories.rs @@ -18,15 +18,15 @@ use crate::{ cloud_object::model::persistence::CloudModel, workspaces::user_workspaces::UserWorkspaces, }; use crate::{editor::Event as EditorEvent, send_telemetry_from_ctx}; -use crate::{server::telemetry::TelemetryEvent, user_config::WarpConfig}; +use crate::{server::telemetry::TelemetryEvent, user_config::GalaxyConfig}; use crate::{ - themes::theme::{self, Blend, WarpTheme}, - user_config::WarpConfigUpdateEvent, + themes::theme::{self, Blend, GalaxyTheme}, + user_config::GalaxyConfigUpdateEvent, }; use fuzzy_match::{match_indices_case_insensitive, FuzzyMatchResult}; use galaxy_core::ui::builder::UiBuilder; use galaxy_core::ui::theme::color::internal_colors; -use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole}; +use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole}; use galaxyui::color::ColorU; use galaxyui::elements::{ Align, CrossAxisAlignment, EventHandler, Highlight, Hoverable, MainAxisSize, MouseStateHandle, @@ -174,7 +174,7 @@ impl WorkflowViewType { WorkflowViewType::Team => "Showing team workflows".into(), }; - AccessibilityContent::new_without_help(a11y_content, WarpA11yRole::UserAction) + AccessibilityContent::new_without_help(a11y_content, GalaxyA11yRole::UserAction) } } @@ -339,7 +339,7 @@ impl SelectionState { } } - fn background_color(&self, theme: &WarpTheme) -> theme::Fill { + fn background_color(&self, theme: &GalaxyTheme) -> theme::Fill { match self { SelectionState::Unselected => theme.surface_2(), SelectionState::Selected => theme.surface_2().blend(&theme.accent_overlay()), @@ -406,8 +406,8 @@ impl CategoriesView { ctx.notify(); }); - ctx.subscribe_to_model(&WarpConfig::handle(ctx), |me, _, event, ctx| { - if let WarpConfigUpdateEvent::LocalUserWorkflows = event { + ctx.subscribe_to_model(&GalaxyConfig::handle(ctx), |me, _, event, ctx| { + if let GalaxyConfigUpdateEvent::LocalUserWorkflows = event { me.update_workflows(ctx); } }); @@ -722,7 +722,7 @@ impl CategoriesView { ); ctx.emit_a11y_content(AccessibilityContent::new_without_help( a11y_content_text, - WarpA11yRole::MenuItemRole, + GalaxyA11yRole::MenuItemRole, )); } } @@ -1156,7 +1156,7 @@ impl CategoriesView { } fn update_workflows(&mut self, ctx: &mut ViewContext) { - let workflows = WarpConfig::as_ref(ctx) + let workflows = GalaxyConfig::as_ref(ctx) .local_user_workflows() .iter() .map(Clone::clone) @@ -1212,7 +1212,7 @@ impl View for CategoriesView { Some(AccessibilityContent::new( "Workflows", "Search or use arrow up and arrow down keys to navigate and find a workflow. Use enter to confirm the workflow and esc to quit.", - WarpA11yRole::MenuRole, + GalaxyA11yRole::MenuRole, )) } diff --git a/app/src/workflows/local_workflows.rs b/app/src/workflows/local_workflows.rs index b8d67d66..2d288f4d 100644 --- a/app/src/workflows/local_workflows.rs +++ b/app/src/workflows/local_workflows.rs @@ -12,7 +12,7 @@ use warp_workflows::workflows as global_workflows; #[cfg(feature = "local_fs")] use crate::user_config::load_workflows; -use crate::{terminal::model::session::Session, user_config::WarpConfig}; +use crate::{terminal::model::session::Session, user_config::GalaxyConfig}; use super::{workflow::Workflow, WorkflowSource}; @@ -136,7 +136,7 @@ impl LocalWorkflows { .map(|workflow| (WorkflowSource::Project, workflow)), ) .chain( - WarpConfig::as_ref(ctx) + GalaxyConfig::as_ref(ctx) .local_user_workflows() .iter() .map(|workflow| (WorkflowSource::Local, workflow)), diff --git a/app/src/workflows/local_workflows_test.rs b/app/src/workflows/local_workflows_test.rs index 13060771..ab48aef1 100644 --- a/app/src/workflows/local_workflows_test.rs +++ b/app/src/workflows/local_workflows_test.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use super::*; fn initialize_app(app: &App) { - app.add_singleton_model(WarpConfig::mock); + app.add_singleton_model(GalaxyConfig::mock); } #[test] diff --git a/app/src/workflows/manager.rs b/app/src/workflows/manager.rs index ba726da0..b1fca8cb 100644 --- a/app/src/workflows/manager.rs +++ b/app/src/workflows/manager.rs @@ -1,7 +1,7 @@ use super::{workflow::Workflow, CloudWorkflowModel}; use crate::{ cloud_object::{model::persistence::CloudModel, GenericCloudObject, Owner}, - drive::OpenWarpDriveObjectSettings, + drive::OpenGalaxyDriveObjectSettings, pane_group::{PaneContent, WorkflowPane}, safe_warn, server::{ @@ -67,7 +67,7 @@ impl WorkflowManager { pub fn create_pane( &mut self, source: &WorkflowOpenSource, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, mode: WorkflowViewMode, window_id: WindowId, ctx: &mut ModelContext, @@ -122,7 +122,7 @@ impl WorkflowManager { *initial_folder_id, ClientId::default(), ), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), mode, ctx, ); diff --git a/app/src/workflows/workflow_view.rs b/app/src/workflows/workflow_view.rs index a02d9e73..193dfb1f 100644 --- a/app/src/workflows/workflow_view.rs +++ b/app/src/workflows/workflow_view.rs @@ -36,7 +36,7 @@ use crate::{ workflow_arg_selector::{WorkflowArgSelector, WorkflowArgSelectorEvent}, workflow_arg_type_helpers::{self, ArgumentEditorRowIndex}, }, - CloudObjectTypeAndId, DriveObjectType, OpenWarpDriveObjectSettings, + CloudObjectTypeAndId, DriveObjectType, OpenGalaxyDriveObjectSettings, }, editor::{ EditorOptions, EditorView, EnterAction, EnterSettings, Event as EditorEvent, @@ -591,7 +591,7 @@ impl WorkflowView { { self.load( workflow.clone(), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), self.workflow_view_mode, ctx, ); @@ -611,7 +611,7 @@ impl WorkflowView { { self.load( workflow, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), self.workflow_view_mode, ctx, ); @@ -629,7 +629,7 @@ impl WorkflowView { if let Some(workflow) = cloud_workflow { self.load( workflow, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), self.workflow_view_mode, ctx, ); @@ -639,7 +639,7 @@ impl WorkflowView { pub fn wait_for_initial_load_then_load( &mut self, workflow_id: SyncId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, mode: WorkflowViewMode, window_id: WindowId, ctx: &mut ViewContext, @@ -680,7 +680,7 @@ impl WorkflowView { fn fetch_and_load_workflow( &mut self, workflow_id: ServerId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, mode: WorkflowViewMode, window_id: WindowId, ctx: &mut ViewContext, @@ -718,7 +718,7 @@ impl WorkflowView { pub fn load( &mut self, workflow: CloudWorkflow, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, mode: WorkflowViewMode, ctx: &mut ViewContext, ) { diff --git a/app/src/workspace/action.rs b/app/src/workspace/action.rs index 7074ff80..2bd53a96 100644 --- a/app/src/workspace/action.rs +++ b/app/src/workspace/action.rs @@ -254,11 +254,11 @@ pub enum WorkspaceAction { /// In Code Mode V2 this toggles the left panel which contains both the project explorer and /// Warp Drive. This happens as explicit action from the user. ToggleLeftPanel, - /// Toggles directly to the Warp Drive tab of the left panel in Code Mode V2 - ToggleWarpDrive, - /// Unconditionally opens Warp Drive. This is used in the case of user lifecycle + /// Toggles directly to the Galaxy Drive tab of the left panel in Code Mode V2 + ToggleGalaxyDrive, + /// Unconditionally opens Galaxy Drive. This is used in the case of user lifecycle /// events like new user onboarding or when the user joins a team. - OpenWarpDrive, + OpenGalaxyDrive, /// Toggles the right panel. This happens as an explicit action from the user. ToggleRightPanel, /// Opens the code review panel (right panel) without toggling. If already open, @@ -825,8 +825,8 @@ impl WorkspaceAction { | StartTabDrag | FinalizeDropTab | ToggleLeftPanel - | ToggleWarpDrive - | OpenWarpDrive + | ToggleGalaxyDrive + | OpenGalaxyDrive | ClosePanel | ToggleRightPanel | OpenCodeReviewPanel(..) diff --git a/app/src/workspace/mod.rs b/app/src/workspace/mod.rs index bc751b70..e6521da0 100644 --- a/app/src/workspace/mod.rs +++ b/app/src/workspace/mod.rs @@ -714,7 +714,7 @@ pub fn init(app: &mut AppContext) { WorkspaceAction::ToggleLeftPanel, ) .with_context_predicate(id!("Workspace")) - .with_custom_action(CustomAction::ToggleWarpDrive), + .with_custom_action(CustomAction::ToggleGalaxyDrive), EditableBinding::new( TOGGLE_RIGHT_PANEL_BINDING_NAME, BindingDescription::new("Toggle code review") @@ -764,7 +764,7 @@ pub fn init(app: &mut AppContext) { EditableBinding::new( LEFT_PANEL_WARP_DRIVE_BINDING_NAME, BindingDescription::new("Left Panel: Galaxy Drive"), - WorkspaceAction::ToggleWarpDrive, + WorkspaceAction::ToggleGalaxyDrive, ) .with_group(bindings::BindingGroup::Navigation.as_str()) .with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)) @@ -791,7 +791,7 @@ pub fn init(app: &mut AppContext) { TOGGLE_WARP_DRIVE_BINDING_NAME, BindingDescription::new("Toggle Galaxy Drive") .with_custom_description(bindings::MAC_MENUS_CONTEXT, "Galaxy Drive"), - WorkspaceAction::ToggleWarpDrive, + WorkspaceAction::ToggleGalaxyDrive, ) .with_context_predicate(id!("Workspace") & id!(flags::ENABLE_WARP_DRIVE)), EditableBinding::new( @@ -1401,7 +1401,7 @@ fn add_open_setting_pages_as_editable_binding(app: &mut AppContext) { ) .with_group(bindings::BindingGroup::Settings.as_str()) .with_context_predicate(id!("Workspace")) - .with_custom_action(CustomAction::ShowAboutWarp), + .with_custom_action(CustomAction::ShowAboutGalaxy), EditableBinding::new( "workspace:show_settings_teams_page", BindingDescription::new("Open Settings: Teams") diff --git a/app/src/workspace/view.rs b/app/src/workspace/view.rs index 2eda9c52..f554152a 100644 --- a/app/src/workspace/view.rs +++ b/app/src/workspace/view.rs @@ -233,7 +233,7 @@ use crate::drive::import::modal::{ImportModal, ImportModalEvent}; 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::experiments::{BlockOnboarding, Experiment}; use crate::menu::{ @@ -338,7 +338,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, }; @@ -480,7 +480,7 @@ use galaxyui::text_layout::ClipConfig; use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles}; use galaxyui::{ accessibility::{ - AccessibilityContent, AccessibilityVerbosity, ActionAccessibilityContent, WarpA11yRole, + AccessibilityContent, AccessibilityVerbosity, ActionAccessibilityContent, GalaxyA11yRole, }, elements::{ Align, Border, ChildAnchor, ChildView, Clipped, ConstrainedBox, Container, CornerRadius, @@ -1372,7 +1372,7 @@ impl Workspace { if let Some(id) = id_to_force_expand { self.open_notebook( &NotebookSource::Existing(id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); @@ -1388,7 +1388,7 @@ impl Workspace { if let Some(id) = id_to_force_expand { self.open_workflow_with_existing( id, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, ); CloudModel::handle(ctx).update(ctx, |cloud_model, ctx| { @@ -1936,7 +1936,7 @@ impl Workspace { ); }); } else { - WarpConfig::handle(ctx).update(ctx, |warp_config, ctx| { + GalaxyConfig::handle(ctx).update(ctx, |warp_config, ctx| { warp_config.remove_tab_config_by_path(path, ctx); }); } @@ -2404,7 +2404,7 @@ impl Workspace { ); } - /// Subscribes to `WarpConfigUpdateEvent::TabConfigErrors` and shows a persistent + /// Subscribes to `GalaxyConfigUpdateEvent::TabConfigErrors` and shows a persistent /// error toast for each tab config file that failed to parse. Uses `object_id` /// keyed by file path so that re-saving the same file auto-dismisses the stale /// toast. @@ -2412,9 +2412,9 @@ impl Workspace { toast_stack: ViewHandle>, ctx: &mut ViewContext, ) { - ctx.subscribe_to_model(&WarpConfig::handle(ctx), move |_me, _, event, ctx| { + ctx.subscribe_to_model(&GalaxyConfig::handle(ctx), move |_me, _, event, ctx| { match event { - WarpConfigUpdateEvent::TabConfigs => { + GalaxyConfigUpdateEvent::TabConfigs => { // On every tab config reload, dismiss error toasts for // files that now parse successfully. The model has already // been updated with the current error set before this event @@ -2429,7 +2429,7 @@ impl Workspace { toast_stack.dismiss_toasts_by_prefix("tab_config_error:", ctx); }); } - WarpConfigUpdateEvent::TabConfigErrors(errors) => { + GalaxyConfigUpdateEvent::TabConfigErrors(errors) => { let home_dir = dirs::home_dir(); for error in errors { let object_id = format!("tab_config_error:{}", error.file_path.display()); @@ -2463,17 +2463,17 @@ impl Workspace { }); } - /// Subscribes to `WarpConfigUpdateEvent::SettingsErrors` and + /// Subscribes to `GalaxyConfigUpdateEvent::SettingsErrors` and /// `SettingsErrorsCleared` to update the workspace settings-error banner /// and mirror the state into the settings pane for its nav-rail footer. fn subscribe_to_settings_errors(ctx: &mut ViewContext) { - ctx.subscribe_to_model(&WarpConfig::handle(ctx), |me, _, event, ctx| match event { - WarpConfigUpdateEvent::SettingsErrors(error) => { + ctx.subscribe_to_model(&GalaxyConfig::handle(ctx), |me, _, event, ctx| match event { + GalaxyConfigUpdateEvent::SettingsErrors(error) => { me.settings_file_error = Some(error.clone()); me.sync_settings_error_state_into_settings_pane(ctx); ctx.notify(); } - WarpConfigUpdateEvent::SettingsErrorsCleared => { + GalaxyConfigUpdateEvent::SettingsErrorsCleared => { me.settings_file_error = None; me.sync_settings_error_state_into_settings_pane(ctx); ctx.notify(); @@ -5635,7 +5635,7 @@ impl Workspace { AgentManagementViewEvent::OpenPlanNotebook { notebook_uid } => { self.open_notebook( &NotebookSource::Existing((*notebook_uid).into()), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, false, ); @@ -6086,7 +6086,7 @@ impl Workspace { // 4. User tab configs if FeatureFlag::TabConfigs.is_enabled() { - let tab_configs = WarpConfig::as_ref(ctx).tab_configs().to_vec(); + let tab_configs = GalaxyConfig::as_ref(ctx).tab_configs().to_vec(); // Count occurrences of each config name so we can disambiguate // duplicates in the menu (e.g. "My Tab Config", "My Tab Config (1)"). @@ -6780,7 +6780,7 @@ impl Workspace { ObjectType::Notebook => { self.open_notebook( &NotebookSource::Existing(sync_id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); @@ -6788,7 +6788,7 @@ impl Workspace { ObjectType::Workflow => { self.open_workflow_in_pane( &WorkflowOpenSource::Existing(sync_id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::View, ctx, ); @@ -6817,7 +6817,7 @@ impl Workspace { pub fn open_notebook( &mut self, source: &NotebookSource, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, default_to_new_pane: bool, ) { @@ -6900,7 +6900,7 @@ impl Workspace { pub fn open_workflow_from_intent( &mut self, workflow_id: SyncId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) { // If running workflows is supported, do so. Otherwise, or if the workflow isn't in memory, @@ -6942,7 +6942,7 @@ impl Workspace { pub fn open_workflow_in_pane( &mut self, source: &WorkflowOpenSource, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, mode: WorkflowViewMode, ctx: &mut ViewContext, ) { @@ -7697,7 +7697,7 @@ impl Workspace { ); self.tips_completed.update(ctx, |tips_completed, ctx| { mark_feature_used_and_write_to_user_defaults( - Tip::Action(TipAction::OpenWarpDrive), + Tip::Action(TipAction::OpenGalaxyDrive), tips_completed, ctx, ); @@ -8860,7 +8860,7 @@ impl Workspace { ctx.notify(); } LaunchConfigModalEvent::SuccessfullySavedConfig(launch_config) => { - ctx.update_model(&WarpConfig::handle(ctx), move |warp_config, ctx| { + ctx.update_model(&GalaxyConfig::handle(ctx), move |warp_config, ctx| { warp_config.append_launch_config(launch_config, ctx); }); ctx.notify(); @@ -10843,7 +10843,7 @@ impl Workspace { pub fn add_tab_for_cloud_notebook( &mut self, notebook_id: SyncId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) { // TODO: We should validate that this notebook exists and fallback if it doesn't @@ -10861,7 +10861,7 @@ impl Workspace { fn add_tab_for_cloud_workflow( &mut self, workflow_id: SyncId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) { let panes_layout = PanesLayout::Snapshot(Box::new(PaneNodeSnapshot::Leaf(LeafSnapshot { @@ -12449,7 +12449,7 @@ impl Workspace { } CommandPaletteEvent::OpenNotebook { id } => self.open_notebook( &NotebookSource::Existing(*id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ), @@ -12732,7 +12732,7 @@ impl Workspace { SettingsViewEvent::LaunchNetworkLogging => { self.open_network_log_pane(ctx); } - SettingsViewEvent::OpenWarpDrive => { + SettingsViewEvent::OpenGalaxyDrive => { self.close_all_overlays(ctx); self.open_or_toggle_warp_drive( false, /* toggle */ @@ -13032,7 +13032,7 @@ impl Workspace { pane_group::Event::OpenCloudWorkflowForEdit(workflow_id) => self .open_workflow_with_existing( *workflow_id, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, ), pane_group::Event::OpenWorkflowModalWithTemporary(workflow) => { @@ -13094,7 +13094,7 @@ impl Workspace { } => { self.move_to_drive_space(*cloud_object_type_and_id, *space, ctx); } - pane_group::Event::OpenWarpDriveLink { + pane_group::Event::OpenGalaxyDriveLink { open_warp_drive_args, } => { let object_found = CloudModel::as_ref(ctx) @@ -13674,7 +13674,7 @@ impl Workspace { ctx.notify(); } pane_group::Event::ClearHoveredTabIndex => self.hovered_tab_index = None, - pane_group::Event::OpenWarpDriveObjectInPane(uid) => { + pane_group::Event::OpenGalaxyDriveObjectInPane(uid) => { self.open_warp_drive_object_in_new_pane(uid, ctx); } pane_group::Event::OpenSuggestedAgentModeWorkflowModal { workflow_and_id } => { @@ -14414,7 +14414,7 @@ impl Workspace { DrivePanelEvent::OpenWorkflowModalWithCloudWorkflow(workflow_id) => { self.open_workflow_with_existing( *workflow_id, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, ); } @@ -14427,14 +14427,14 @@ impl Workspace { ); } DrivePanelEvent::OpenNotebook(source) => { - self.open_notebook(source, &OpenWarpDriveObjectSettings::default(), ctx, true) + self.open_notebook(source, &OpenGalaxyDriveObjectSettings::default(), ctx, true) } DrivePanelEvent::OpenEnvVarCollection(source) => { self.open_env_var_collection(source, false, ctx) } DrivePanelEvent::OpenWorkflowInPane(source, mode) => self.open_workflow_in_pane( source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), *mode, ctx, ), @@ -14878,7 +14878,7 @@ impl Workspace { AcceptNotebook(sync_id) => { self.open_notebook( &NotebookSource::Existing(*sync_id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); @@ -16348,7 +16348,7 @@ impl Workspace { fn open_workflow_with_existing( &mut self, workflow_id: SyncId, - settings: &OpenWarpDriveObjectSettings, + settings: &OpenGalaxyDriveObjectSettings, ctx: &mut ViewContext, ) { let source = WorkflowOpenSource::Existing(workflow_id); @@ -16368,7 +16368,7 @@ impl Workspace { }; self.open_workflow_in_pane( &source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::Create, ctx, ); @@ -16389,7 +16389,7 @@ impl Workspace { }; self.open_workflow_in_pane( &source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::Create, ctx, ); @@ -19556,7 +19556,7 @@ impl TypedActionView for Workspace { WorkspaceAction::SetA11yVerbosityLevel(verbosity) => { ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help( format!("{verbosity:?} accessibility announcements set"), - WarpA11yRole::UserAction, + GalaxyA11yRole::UserAction, )) } _ => ActionAccessibilityContent::from_debug(), @@ -19987,7 +19987,7 @@ impl TypedActionView for Workspace { owner: personal_drive, initial_folder_id: None, }, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); @@ -20049,7 +20049,7 @@ impl TypedActionView for Workspace { }; self.open_workflow_in_pane( &source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::Create, ctx, ); @@ -20067,7 +20067,7 @@ impl TypedActionView for Workspace { }; self.open_workflow_in_pane( &source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::Create, ctx, ); @@ -20108,7 +20108,7 @@ impl TypedActionView for Workspace { self.finish_tab_rename(ctx); self.current_workspace_state.is_tab_being_dragged = true; } - OpenWarpDrive => { + OpenGalaxyDrive => { if WarpDriveSettings::is_warp_drive_enabled(ctx) { self.open_left_panel_view(&LeftPanelAction::WarpDrive, ctx); } @@ -20618,7 +20618,7 @@ impl TypedActionView for Workspace { }); self.open_workflow_with_existing( *workflow_id, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, ); } @@ -20938,7 +20938,7 @@ impl TypedActionView for Workspace { } OpenNotebook { id } => self.open_notebook( &NotebookSource::Existing(*id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ), @@ -21096,7 +21096,7 @@ impl TypedActionView for Workspace { }; self.open_workflow_in_pane( &source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::Create, ctx, ); @@ -21114,7 +21114,7 @@ impl TypedActionView for Workspace { }; self.open_workflow_in_pane( &source, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), WorkflowViewMode::Create, ctx, ); @@ -21352,7 +21352,7 @@ impl TypedActionView for Workspace { self.toggle_left_panel_view(&LeftPanelAction::ProjectExplorer, is_showing, 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/free_tier_limit_hit_modal.rs b/app/src/workspace/view/free_tier_limit_hit_modal.rs index ba254aeb..db00acaa 100644 --- a/app/src/workspace/view/free_tier_limit_hit_modal.rs +++ b/app/src/workspace/view/free_tier_limit_hit_modal.rs @@ -8,7 +8,7 @@ use crate::TelemetryEvent; use asset_macro::bundled_or_fetched_asset; use galaxy_core::send_telemetry_from_ctx; use galaxy_core::ui::appearance::Appearance; -use galaxy_core::ui::theme::{Fill, WarpTheme}; +use galaxy_core::ui::theme::{Fill, GalaxyTheme}; use galaxy_graphql::billing::{PlanPricing, StripeSubscriptionPlan}; use galaxyui::elements::{ Align, Border, CacheOption, ChildAnchor, ConstrainedBox, Container, CornerRadius, @@ -97,7 +97,7 @@ impl FreeTierLimitHitModal { fn render_checklist_item_dynamic( text: String, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let formatted_text = FormattedText::new([FormattedTextLine::Line(vec![ FormattedTextFragment::plain_text(text), diff --git a/app/src/workspace/view/global_search/view.rs b/app/src/workspace/view/global_search/view.rs index a9607002..a820948f 100644 --- a/app/src/workspace/view/global_search/view.rs +++ b/app/src/workspace/view/global_search/view.rs @@ -1074,7 +1074,7 @@ impl GlobalSearchView { directory_path: &Path, matched_path: &MatchedPath, appearance: &Appearance, - theme: &galaxy_core::ui::theme::WarpTheme, + theme: &galaxy_core::ui::theme::GalaxyTheme, app: &AppContext, ) -> Box { let is_selected = self.is_row_at_index_selected(index); @@ -1249,7 +1249,7 @@ impl GlobalSearchView { matched: &Match, match_index: usize, appearance: &Appearance, - theme: &galaxy_core::ui::theme::WarpTheme, + theme: &galaxy_core::ui::theme::GalaxyTheme, ) -> Box { let is_selected = self.is_row_at_index_selected(index); let line_number = matched.line_number; @@ -1853,7 +1853,7 @@ impl GlobalSearchView { index: usize, dir_entry: &DirectoryEntry, appearance: &Appearance, - theme: &galaxy_core::ui::theme::WarpTheme, + theme: &galaxy_core::ui::theme::GalaxyTheme, ) -> Box { let is_selected = self.is_row_at_index_selected(index); let mouse_state = dir_entry.mouse_state.clone(); diff --git a/app/src/workspace/view/vertical_tabs.rs b/app/src/workspace/view/vertical_tabs.rs index 1809d305..9ba9da1d 100644 --- a/app/src/workspace/view/vertical_tabs.rs +++ b/app/src/workspace/view/vertical_tabs.rs @@ -52,12 +52,11 @@ use crate::workspace::{ use languages::language_by_filename; 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, GalaxyTheme}; +use galaxy_core::ui::Icon as GalaxyIcon; use galaxyui::elements::DispatchEventResult; use galaxyui::elements::{ resizable_state_handle, Border, ChildAnchor, Clipped, ClippedScrollStateHandle, @@ -254,13 +253,13 @@ enum TerminalPrimaryLineFont { Monospace, } -fn oz_icon_fill(theme: &WarpTheme) -> WarpThemeFill { +fn oz_icon_fill(theme: &GalaxyTheme) -> GalaxyThemeFill { theme.main_text_color(theme.background()) } fn render_pane_icon_with_status( variant: IconWithStatusVariant, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let sizing = match &variant { IconWithStatusVariant::OzAgent { .. } => &VERTICAL_TABS_AGENT_SIZING, @@ -286,7 +285,7 @@ fn pane_row_background( is_selected: bool, is_hovered: bool, is_being_dragged: bool, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Option { if let Some(color) = pane_color { let opacity = if is_selected || is_hovered { @@ -309,7 +308,7 @@ fn render_pane_row_element( padding: Padding, defer_events_to_children: bool, content: Box, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let detail_target = supports_vertical_tabs_detail_sidecar(&props.typed).then(|| { detail_target_for_hovered_row( @@ -1087,7 +1086,7 @@ fn vertical_tabs_tab_bar_location(insert_index: usize, tab_count: usize) -> TabB } } -fn render_vertical_tab_hover_indicator(theme: &WarpTheme) -> Box { +fn render_vertical_tab_hover_indicator(theme: &GalaxyTheme) -> Box { ConstrainedBox::new( Container::new(Empty::new().finish()) .with_background(ThemeFill::Solid(theme.accent().into())) @@ -1118,7 +1117,7 @@ fn render_vertical_tab_insertion_target( insert_index: usize, tab_count: usize, is_drag_target: bool, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let content = if is_drag_target { render_vertical_tab_hover_indicator(theme) @@ -1143,7 +1142,7 @@ fn add_vertical_tab_insertion_target_overlay( is_drag_target: bool, parent_anchor: ParentAnchor, child_anchor: ChildAnchor, - theme: &WarpTheme, + theme: &GalaxyTheme, ) { stack.add_positioned_overlay_child( render_vertical_tab_insertion_target(insert_index, tab_count, is_drag_target, theme), @@ -1166,7 +1165,7 @@ fn render_control_bar( let theme = appearance.theme(); let sub_text = theme.sub_text_color(theme.background()); - let search_icon = ConstrainedBox::new(WarpIcon::Search.to_galaxyui_icon(sub_text).finish()) + let search_icon = ConstrainedBox::new(GalaxyIcon::Search.to_galaxyui_icon(sub_text).finish()) .with_width(SEARCH_ICON_SIZE) .with_height(SEARCH_ICON_SIZE) .finish(); @@ -1226,35 +1225,35 @@ fn render_detail_kind_badge_icon( if let Some(icon) = cli_agent_session.and_then(|session| session.agent.icon()) { let color = cli_agent_session .and_then(|session| session.agent.brand_color()) - .map(WarpThemeFill::Solid) + .map(GalaxyThemeFill::Solid) .unwrap_or_else(|| theme.accent()); return icon.to_galaxyui_icon(color).finish(); } let icon = if terminal_view.is_ambient_agent_session(app) { - WarpIcon::OzCloud + GalaxyIcon::OzCloud } else if terminal_view .selected_conversation_display_title(app) .is_some() { - WarpIcon::Oz + GalaxyIcon::Oz } else { - WarpIcon::Terminal + GalaxyIcon::Terminal }; let color = match icon { - WarpIcon::Oz | WarpIcon::OzCloud => oz_icon_fill(theme), - WarpIcon::Terminal => disabled_text, + GalaxyIcon::Oz | GalaxyIcon::OzCloud => oz_icon_fill(theme), + GalaxyIcon::Terminal => disabled_text, _ => sub_text, }; icon.to_galaxyui_icon(color).finish() } TypedPane::Code(_) => icon_from_file_path(&props.title, appearance) - .unwrap_or_else(|| WarpIcon::Code2.to_galaxyui_icon(sub_text).finish()), + .unwrap_or_else(|| GalaxyIcon::Code2.to_galaxyui_icon(sub_text).finish()), typed => { let fill = typed .warp_drive_object_type() .map(|object_type| { - WarpThemeFill::Solid(warp_drive_icon_color(appearance, object_type)) + GalaxyThemeFill::Solid(warp_drive_icon_color(appearance, object_type)) }) .unwrap_or(sub_text); typed.icon().to_galaxyui_icon(fill).finish() @@ -1276,7 +1275,7 @@ fn render_settings_button( state.settings_button_mouse_state.clone(), move |hover_state| { let icon = ConstrainedBox::new( - WarpIcon::Settings + GalaxyIcon::Settings .to_galaxyui_icon(if is_popup_open { main_text } else { sub_text }) .finish(), ) @@ -2084,13 +2083,13 @@ fn render_group_action_buttons( action_buttons_mouse_state: MouseStateHandle, kebab_mouse_state: MouseStateHandle, close_mouse_state: MouseStateHandle, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let meta_color = theme.sub_text_color(theme.background()); let kebab_button = Hoverable::new(kebab_mouse_state, move |button_state| { let mut container = Container::new( - ConstrainedBox::new(WarpIcon::DotsVertical.to_galaxyui_icon(meta_color).finish()) + ConstrainedBox::new(GalaxyIcon::DotsVertical.to_galaxyui_icon(meta_color).finish()) .with_width(GROUP_ACTION_BUTTON_ICON_SIZE) .with_height(GROUP_ACTION_BUTTON_ICON_SIZE) .finish(), @@ -2113,7 +2112,7 @@ fn render_group_action_buttons( let close_button = Hoverable::new(close_mouse_state, move |button_state| { let mut container = Container::new( - ConstrainedBox::new(WarpIcon::X.to_galaxyui_icon(meta_color).finish()) + ConstrainedBox::new(GalaxyIcon::X.to_galaxyui_icon(meta_color).finish()) .with_width(GROUP_ACTION_BUTTON_ICON_SIZE) .with_height(GROUP_ACTION_BUTTON_ICON_SIZE) .finish(), @@ -2231,8 +2230,8 @@ fn resolve_icon_with_status_variant( let main_text = theme.main_text_color(theme.background()); let sub_text = theme.sub_text_color(theme.background()); - let drive_color = |object_type: DriveObjectType| -> WarpThemeFill { - WarpThemeFill::Solid(warp_drive_icon_color(appearance, object_type)) + let drive_color = |object_type: DriveObjectType| -> GalaxyThemeFill { + GalaxyThemeFill::Solid(warp_drive_icon_color(appearance, object_type)) }; match typed { @@ -2275,7 +2274,7 @@ fn resolve_icon_with_status_variant( } else { // Plain terminal: use foreground color per design spec IconWithStatusVariant::Neutral { - icon: WarpIcon::Terminal, + icon: GalaxyIcon::Terminal, icon_color: main_text, } } @@ -2285,7 +2284,7 @@ fn resolve_icon_with_status_variant( IconWithStatusVariant::NeutralElement { icon_element } } else { IconWithStatusVariant::Neutral { - icon: WarpIcon::Code2, + icon: GalaxyIcon::Code2, icon_color: sub_text, } } @@ -2341,9 +2340,9 @@ fn has_unread_activity(typed: &TypedPane<'_>, app: &AppContext) -> bool { const INDICATOR_DOT_SIZE: f32 = 8.; -fn render_title_indicator(theme: &WarpTheme) -> Box { +fn render_title_indicator(theme: &GalaxyTheme) -> Box { ConstrainedBox::new( - WarpIcon::CircleFilled + GalaxyIcon::CircleFilled .to_galaxyui_icon(theme.accent()) .finish(), ) @@ -2555,24 +2554,24 @@ impl TypedPane<'_> { } } - fn icon(&self) -> WarpIcon { + fn icon(&self) -> GalaxyIcon { match self { - TypedPane::Terminal(_) => WarpIcon::Terminal, - TypedPane::Code(_) => WarpIcon::Code2, - TypedPane::CodeDiff => WarpIcon::Diff, - TypedPane::File => WarpIcon::File, - TypedPane::Notebook { is_plan: true } => WarpIcon::Compass, - TypedPane::Notebook { is_plan: false } => WarpIcon::Notebook, - TypedPane::Workflow { is_ai_prompt: true } => WarpIcon::Prompt, + TypedPane::Terminal(_) => GalaxyIcon::Terminal, + TypedPane::Code(_) => GalaxyIcon::Code2, + TypedPane::CodeDiff => GalaxyIcon::Diff, + TypedPane::File => GalaxyIcon::File, + TypedPane::Notebook { is_plan: true } => GalaxyIcon::Compass, + TypedPane::Notebook { is_plan: false } => GalaxyIcon::Notebook, + TypedPane::Workflow { is_ai_prompt: true } => GalaxyIcon::Prompt, TypedPane::Workflow { is_ai_prompt: false, - } => WarpIcon::Workflow, - TypedPane::Settings | TypedPane::EnvironmentManagement => WarpIcon::Gear, - TypedPane::EnvVarCollection => WarpIcon::EnvVarCollection, - TypedPane::AIFact => WarpIcon::BookOpen, - TypedPane::AIDocument => WarpIcon::Compass, - TypedPane::ExecutionProfileEditor => WarpIcon::Lightning, - TypedPane::Other => WarpIcon::File, + } => GalaxyIcon::Workflow, + TypedPane::Settings | TypedPane::EnvironmentManagement => GalaxyIcon::Gear, + TypedPane::EnvVarCollection => GalaxyIcon::EnvVarCollection, + TypedPane::AIFact => GalaxyIcon::BookOpen, + TypedPane::AIDocument => GalaxyIcon::Compass, + TypedPane::ExecutionProfileEditor => GalaxyIcon::Lightning, + TypedPane::Other => GalaxyIcon::File, } } } @@ -3333,7 +3332,7 @@ fn compact_branch_subtitle_display( fn render_git_branch_text( branch: &str, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, font_size: f32, appearance: &Appearance, ) -> Box { @@ -3366,7 +3365,7 @@ enum MetadataLeftContent { fn render_text_line( text: &str, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, clip: ClipConfig, appearance: &Appearance, ) -> Box { @@ -3399,7 +3398,7 @@ fn render_inline_tab_rename_editor( fn render_title_override( props: &PaneProps<'_>, font_size: f32, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, clip: ClipConfig, appearance: &Appearance, app: &AppContext, @@ -3433,7 +3432,7 @@ fn render_pane_title_slot( props: &PaneProps<'_>, generated_title: impl FnOnce() -> Box, font_size: f32, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, clip: ClipConfig, appearance: &Appearance, app: &AppContext, @@ -3629,9 +3628,9 @@ fn render_summary_pane_kind_icon_circle( let (icon_element, background): (Box, ElementFill) = match kind { SummaryPaneKind::OzAgent { is_ambient } => { let icon = if is_ambient { - WarpIcon::OzCloud + GalaxyIcon::OzCloud } else { - WarpIcon::Oz + GalaxyIcon::Oz }; ( icon.to_galaxyui_icon(oz_icon_fill(theme)).finish(), @@ -3643,11 +3642,11 @@ fn render_summary_pane_kind_icon_circle( let icon_element = agent .icon() .map(|icon| { - icon.to_galaxyui_icon(WarpThemeFill::Solid(icon_color)) + icon.to_galaxyui_icon(GalaxyThemeFill::Solid(icon_color)) .finish() }) .unwrap_or_else(|| { - WarpIcon::Terminal + GalaxyIcon::Terminal .to_galaxyui_icon(theme.sub_text_color(theme.background())) .finish() }); @@ -3663,7 +3662,7 @@ fn render_summary_pane_kind_icon_circle( } SummaryPaneKind::Code { title } => ( icon_from_file_path(&title, appearance).unwrap_or_else(|| { - WarpIcon::Code2 + GalaxyIcon::Code2 .to_galaxyui_icon(theme.sub_text_color(theme.background())) .finish() }), @@ -3705,36 +3704,36 @@ fn render_summary_pane_kind_icon_circle( fn summary_pane_kind_icon( kind: SummaryPaneKind, appearance: &Appearance, -) -> (WarpIcon, WarpThemeFill) { +) -> (GalaxyIcon, GalaxyThemeFill) { let theme = appearance.theme(); let main_text = theme.main_text_color(theme.background()); let sub_text = theme.sub_text_color(theme.background()); - let drive_color = |object_type: DriveObjectType| -> WarpThemeFill { - WarpThemeFill::Solid(warp_drive_icon_color(appearance, object_type)) + let drive_color = |object_type: DriveObjectType| -> GalaxyThemeFill { + GalaxyThemeFill::Solid(warp_drive_icon_color(appearance, object_type)) }; match kind { - SummaryPaneKind::Terminal => (WarpIcon::Terminal, main_text), + SummaryPaneKind::Terminal => (GalaxyIcon::Terminal, main_text), SummaryPaneKind::OzAgent { is_ambient } => ( if is_ambient { - WarpIcon::OzCloud + GalaxyIcon::OzCloud } else { - WarpIcon::Oz + GalaxyIcon::Oz }, main_text, ), SummaryPaneKind::CLIAgent { agent } => ( - agent.icon().unwrap_or(WarpIcon::Terminal), - WarpThemeFill::Solid(agent.brand_icon_color()), + agent.icon().unwrap_or(GalaxyIcon::Terminal), + GalaxyThemeFill::Solid(agent.brand_icon_color()), ), - SummaryPaneKind::Code { .. } => (WarpIcon::Code2, sub_text), - SummaryPaneKind::CodeDiff => (WarpIcon::Diff, sub_text), - SummaryPaneKind::File => (WarpIcon::File, sub_text), + SummaryPaneKind::Code { .. } => (GalaxyIcon::Code2, sub_text), + SummaryPaneKind::CodeDiff => (GalaxyIcon::Diff, sub_text), + SummaryPaneKind::File => (GalaxyIcon::File, sub_text), SummaryPaneKind::Notebook { is_plan } => ( if is_plan { - WarpIcon::Compass + GalaxyIcon::Compass } else { - WarpIcon::Notebook + GalaxyIcon::Notebook }, drive_color(DriveObjectType::Notebook { is_ai_document: is_plan, @@ -3742,9 +3741,9 @@ fn summary_pane_kind_icon( ), SummaryPaneKind::Workflow { is_ai_prompt } => ( if is_ai_prompt { - WarpIcon::Prompt + GalaxyIcon::Prompt } else { - WarpIcon::Workflow + GalaxyIcon::Workflow }, if is_ai_prompt { drive_color(DriveObjectType::AgentModeWorkflow) @@ -3753,16 +3752,16 @@ fn summary_pane_kind_icon( }, ), SummaryPaneKind::Settings | SummaryPaneKind::EnvironmentManagement => { - (WarpIcon::Gear, main_text) + (GalaxyIcon::Gear, main_text) } SummaryPaneKind::EnvVarCollection => ( - WarpIcon::EnvVarCollection, + GalaxyIcon::EnvVarCollection, drive_color(DriveObjectType::EnvVarCollection), ), - SummaryPaneKind::AIFact => (WarpIcon::BookOpen, drive_color(DriveObjectType::AIFact)), - SummaryPaneKind::AIDocument => (WarpIcon::Compass, sub_text), - SummaryPaneKind::ExecutionProfileEditor => (WarpIcon::Lightning, sub_text), - SummaryPaneKind::Other => (WarpIcon::File, sub_text), + SummaryPaneKind::AIFact => (GalaxyIcon::BookOpen, drive_color(DriveObjectType::AIFact)), + SummaryPaneKind::AIDocument => (GalaxyIcon::Compass, sub_text), + SummaryPaneKind::ExecutionProfileEditor => (GalaxyIcon::Lightning, sub_text), + SummaryPaneKind::Other => (GalaxyIcon::File, sub_text), } } @@ -3817,7 +3816,7 @@ fn render_summary_branch_line( fn render_terminal_primary_line_for_view( terminal_view: &TerminalView, appearance: &Appearance, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, app: &AppContext, ) -> Box { let title_text = terminal_view.terminal_title_from_shell(); @@ -3853,7 +3852,7 @@ fn render_terminal_primary_line( primary_line: TerminalPrimaryLineData, terminal_view: &TerminalView, appearance: &Appearance, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, ) -> Box { let theme = appearance.theme(); @@ -4171,7 +4170,7 @@ fn compute_tab_group_color_mode( tab: &TabData, pane_group: &PaneGroup, visible_pane_ids: &[PaneId], - theme: &WarpTheme, + theme: &GalaxyTheme, app: &AppContext, ) -> TabGroupColorMode { // Manual override applies to the whole group. @@ -4466,7 +4465,7 @@ pub(super) fn render_settings_popup( Expanded::new( 1., render_popup_segment( - WarpIcon::Menu01, + GalaxyIcon::Menu01, matches!(current_mode, VerticalTabsViewMode::Compact), state.compact_segment_mouse_state.clone(), VerticalTabsViewMode::Compact, @@ -4480,7 +4479,7 @@ pub(super) fn render_settings_popup( Expanded::new( 1., render_popup_segment( - WarpIcon::Grid, + GalaxyIcon::Grid, matches!(current_mode, VerticalTabsViewMode::Expanded), state.expanded_segment_mouse_state.clone(), VerticalTabsViewMode::Expanded, @@ -4505,7 +4504,7 @@ pub(super) fn render_settings_popup( .finish(); // Divider between toggle and "Pane title as" section - let make_divider = |theme: &WarpTheme| { + let make_divider = |theme: &GalaxyTheme| { Container::new( ConstrainedBox::new( Container::new(Empty::new().finish()) @@ -4706,7 +4705,7 @@ fn render_compact_subtitle_option( mouse_state: MouseStateHandle, value: VerticalTabsCompactSubtitle, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { const ICON_SIZE: f32 = 16.; const FONT_SIZE: f32 = 12.; @@ -4716,7 +4715,7 @@ fn render_compact_subtitle_option( let main_text = theme.main_text_color(theme.background()); Hoverable::new(mouse_state, move |hover_state| { let check_icon: Box = if is_selected { - ConstrainedBox::new(WarpIcon::Check.to_galaxyui_icon(main_text).finish()) + ConstrainedBox::new(GalaxyIcon::Check.to_galaxyui_icon(main_text).finish()) .with_width(ICON_SIZE) .with_height(ICON_SIZE) .finish() @@ -4759,7 +4758,7 @@ fn render_tab_item_mode_option( mouse_state: MouseStateHandle, value: VerticalTabsTabItemMode, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { const ICON_SIZE: f32 = 16.; const FONT_SIZE: f32 = 12.; @@ -4769,7 +4768,7 @@ fn render_tab_item_mode_option( let main_text = theme.main_text_color(theme.background()); Hoverable::new(mouse_state, move |hover_state| { let check_icon: Box = if is_selected { - ConstrainedBox::new(WarpIcon::Check.to_galaxyui_icon(main_text).finish()) + ConstrainedBox::new(GalaxyIcon::Check.to_galaxyui_icon(main_text).finish()) .with_width(ICON_SIZE) .with_height(ICON_SIZE) .finish() @@ -4812,7 +4811,7 @@ fn render_primary_info_option( mouse_state: MouseStateHandle, value: VerticalTabsPrimaryInfo, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { const ICON_SIZE: f32 = 16.; const FONT_SIZE: f32 = 12.; @@ -4822,7 +4821,7 @@ fn render_primary_info_option( let main_text = theme.main_text_color(theme.background()); Hoverable::new(mouse_state, move |hover_state| { let check_icon: Box = if is_selected { - ConstrainedBox::new(WarpIcon::Check.to_galaxyui_icon(main_text).finish()) + ConstrainedBox::new(GalaxyIcon::Check.to_galaxyui_icon(main_text).finish()) .with_width(ICON_SIZE) .with_height(ICON_SIZE) .finish() @@ -4871,7 +4870,7 @@ fn render_show_toggle_option( action: WorkspaceAction, info_tooltip: Option, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { const ICON_SIZE: f32 = 16.; const FONT_SIZE: f32 = 12.; @@ -4889,7 +4888,7 @@ fn render_show_toggle_option( Hoverable::new(mouse_state, move |hover_state| { let check_icon: Box = if is_enabled { - ConstrainedBox::new(WarpIcon::Check.to_galaxyui_icon(main_text).finish()) + ConstrainedBox::new(GalaxyIcon::Check.to_galaxyui_icon(main_text).finish()) .with_width(ICON_SIZE) .with_height(ICON_SIZE) .finish() @@ -4959,12 +4958,12 @@ fn render_show_toggle_option( } fn render_popup_segment( - icon: WarpIcon, + icon: GalaxyIcon, is_selected: bool, mouse_state: MouseStateHandle, mode: VerticalTabsViewMode, - theme: &WarpTheme, - icon_color: WarpThemeFill, + theme: &GalaxyTheme, + icon_color: GalaxyThemeFill, ) -> Box { Hoverable::new(mouse_state, move |hover_state| { let background = if is_selected { @@ -5002,7 +5001,7 @@ fn render_popup_text_segment( mouse_state: MouseStateHandle, granularity: VerticalTabsDisplayGranularity, appearance: &Appearance, - theme: &WarpTheme, + theme: &GalaxyTheme, ) -> Box { let label = label.to_string(); let main_text = theme.main_text_color(theme.background()); @@ -5170,25 +5169,25 @@ fn detail_sidecar_width_and_bounds(available_width: f32) -> (f32, PositionedElem } struct DetailSidecarTextColors { - main: WarpThemeFill, - sub: WarpThemeFill, - disabled: WarpThemeFill, + main: GalaxyThemeFill, + sub: GalaxyThemeFill, + disabled: GalaxyThemeFill, } -fn detail_sidecar_background(theme: &WarpTheme) -> ColorU { +fn detail_sidecar_background(theme: &GalaxyTheme) -> ColorU { theme .background() .blend(&internal_colors::fg_overlay_2(theme)) .into_solid() } -fn detail_sidecar_border_fill(theme: &WarpTheme) -> ThemeFill { +fn detail_sidecar_border_fill(theme: &GalaxyTheme) -> ThemeFill { theme .background() .blend(&internal_colors::fg_overlay_4(theme)) } -fn detail_sidecar_text_colors(theme: &WarpTheme) -> DetailSidecarTextColors { +fn detail_sidecar_text_colors(theme: &GalaxyTheme) -> DetailSidecarTextColors { let bg = ThemeFill::Solid(detail_sidecar_background(theme)); DetailSidecarTextColors { main: theme.main_text_color(bg), @@ -5201,7 +5200,7 @@ fn render_detail_badge( label: impl Into, icon: Option>, background: Option, - text_color: WarpThemeFill, + text_color: GalaxyThemeFill, appearance: &Appearance, ) -> Box { let mut content = Flex::row() @@ -5244,14 +5243,14 @@ fn render_detail_status_pill( .with_cross_axis_alignment(CrossAxisAlignment::Center) .with_spacing(4.) .with_child( - ConstrainedBox::new(icon.to_galaxyui_icon(WarpThemeFill::Solid(color)).finish()) + ConstrainedBox::new(icon.to_galaxyui_icon(GalaxyThemeFill::Solid(color)).finish()) .with_width(12.) .with_height(12.) .finish(), ) .with_child( Text::new_inline(status.to_string(), appearance.ui_font_family(), 10.) - .with_color(WarpThemeFill::Solid(color).into()) + .with_color(GalaxyThemeFill::Solid(color).into()) .finish(), ) .finish(), @@ -5265,7 +5264,7 @@ fn render_detail_status_pill( fn render_detail_wrapping_text( text: impl Into, font_size: f32, - color: WarpThemeFill, + color: GalaxyThemeFill, style: Option, appearance: &Appearance, ) -> Box { @@ -5280,7 +5279,7 @@ fn render_detail_wrapping_text( fn render_terminal_detail_primary_line( primary_line: &TerminalPrimaryLineData, - color: WarpThemeFill, + color: GalaxyThemeFill, appearance: &Appearance, ) -> Box { let font_family = match primary_line { diff --git a/app/src/workspace/view/wasm_view.rs b/app/src/workspace/view/wasm_view.rs index 886a5bf1..12be04cf 100644 --- a/app/src/workspace/view/wasm_view.rs +++ b/app/src/workspace/view/wasm_view.rs @@ -20,7 +20,7 @@ use crate::view_components::action_button::{ }; use crate::wasm_nux_dialog::{WasmNUXDialog, WasmNUXDialogEvent}; use crate::workspace::action::WorkspaceAction; -use crate::workspace::view::{NotebookSource, OpenWarpDriveObjectSettings, Workspace}; +use crate::workspace::view::{NotebookSource, OpenGalaxyDriveObjectSettings, Workspace}; use crate::BlocklistAIHistoryModel; const TRANSCRIPT_PANEL_WIDTH: f32 = 280.0; @@ -101,7 +101,7 @@ impl Workspace { ConversationDetailsPanelEvent::OpenPlanNotebook { notebook_uid } => { me.open_notebook( &NotebookSource::Existing((*notebook_uid).into()), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); diff --git a/app/src/workspace/view_test.rs b/app/src/workspace/view_test.rs index fdbef1d8..6449fd3d 100644 --- a/app/src/workspace/view_test.rs +++ b/app/src/workspace/view_test.rs @@ -68,7 +68,7 @@ use crate::resource_center::Tip; use crate::terminal::cli_agent_sessions::CLIAgentSessionsModel; use crate::test_util::settings::initialize_settings_for_tests; use crate::undo_close::UndoCloseSettings; -use crate::warp_managed_paths_watcher::WarpManagedPathsWatcher; +use crate::galaxy_managed_paths_watcher::GalaxyManagedPathsWatcher; use crate::workflows::local_workflows::LocalWorkflows; use crate::{experiments, workspace, GlobalResourceHandlesProvider}; use crate::{AgentNotificationsModel, ObjectActions}; @@ -147,7 +147,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(WarpManagedPathsWatcher::new_for_testing); + app.add_singleton_model(GalaxyManagedPathsWatcher::new_for_testing); app.add_singleton_model(FileMCPWatcher::new); app.add_singleton_model(|_| FileBasedMCPManager::default()); @@ -208,7 +208,7 @@ fn initialize_app(app: &mut App) { // binding descriptions eagerly, and `workspace:send_feedback`'s dynamic // label calls `is_feedback_skill_available`, which reads `SkillManager`. // Registered after `HomeDirectoryWatcher`, `DirectoryWatcher`, - // `WarpManagedPathsWatcher`, `DetectedRepositories`, and `RepoMetadataModel` + // `GalaxyManagedPathsWatcher`, `DetectedRepositories`, and `RepoMetadataModel` // because `SkillWatcher::new` subscribes to all of them. app.add_singleton_model(SkillManager::new); @@ -1307,7 +1307,7 @@ fn test_notebook_pane_tracking() { owner: Owner::mock_current_user(), initial_folder_id: None, }, - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); @@ -1347,7 +1347,7 @@ fn test_notebook_pane_tracking() { // Re-opening the notebook should not create a new view. workspace.open_notebook( &NotebookSource::Existing(notebook_id), - &OpenWarpDriveObjectSettings::default(), + &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); @@ -1479,7 +1479,7 @@ fn test_open_or_toggle_warp_drive() { .tips_completed .as_ref(ctx) .features_used - .contains(&Tip::Action(TipAction::OpenWarpDrive)), + .contains(&Tip::Action(TipAction::OpenGalaxyDrive)), "Warp drive welcome tip should not be completed" ); @@ -1498,7 +1498,7 @@ fn test_open_or_toggle_warp_drive() { .tips_completed .as_ref(ctx) .features_used - .contains(&Tip::Action(TipAction::OpenWarpDrive)), + .contains(&Tip::Action(TipAction::OpenGalaxyDrive)), "Warp drive welcome tip should not be completed" ); @@ -1517,7 +1517,7 @@ fn test_open_or_toggle_warp_drive() { .tips_completed .as_ref(ctx) .features_used - .contains(&Tip::Action(TipAction::OpenWarpDrive)), + .contains(&Tip::Action(TipAction::OpenGalaxyDrive)), "Warp drive welcome tip should not be completed" ); }); diff --git a/app/src/workspaces/gql_convert.rs b/app/src/workspaces/gql_convert.rs index ae96e10c..da71b155 100644 --- a/app/src/workspaces/gql_convert.rs +++ b/app/src/workspaces/gql_convert.rs @@ -261,11 +261,10 @@ impl From<&gql_usage::ConversationUsage> for ConversationUsageInfo { lines_added: tool.apply_file_diff_stats.lines_added, lines_removed: tool.apply_file_diff_stats.lines_removed, commands_executed: tool.run_command_stats.commands_executed, - total_input_tokens: 0, - total_output_tokens: 0, + current_context_tokens: 0, + estimated_cost_cents: 0.0, total_cache_read_tokens: 0, total_cache_write_tokens: 0, - estimated_cost_cents: 0.0, } } } diff --git a/crates/ai/src/project_context/model.rs b/crates/ai/src/project_context/model.rs index 7a22b46f..eec47c6a 100644 --- a/crates/ai/src/project_context/model.rs +++ b/crates/ai/src/project_context/model.rs @@ -13,7 +13,7 @@ cfg_if::cfg_if! { use ignore::gitignore::Gitignore; use async_channel::Sender; - const RULES_FILE_PATTERN: [&str; 2] = ["WARP.md", "AGENTS.md"]; + const RULES_FILE_PATTERN: [&str; 4] = ["GALAXY.md", "WARP.md", "CLAUDE.md", "AGENTS.md"]; const MAX_SCAN_DEPTH: usize = 3; const MAX_FILES_TO_SCAN: usize = 5000; } @@ -28,13 +28,23 @@ pub struct ProjectRule { #[derive(Debug, Default)] struct RuleAtPath { parent_path: PathBuf, + galaxy_md: Option, warp_md: Option, + claude_md: Option, agents_md: Option, } impl RuleAtPath { - fn respected_rule(&self) -> Option<&ProjectRule> { - self.warp_md.as_ref().or(self.agents_md.as_ref()) + fn all_rules(&self) -> Vec<&ProjectRule> { + [ + self.galaxy_md.as_ref(), + self.warp_md.as_ref(), + self.claude_md.as_ref(), + self.agents_md.as_ref(), + ] + .into_iter() + .flatten() + .collect() } } @@ -82,12 +92,14 @@ impl ProjectRules { // Collect all applicable rules (rules in directories that are ancestors of the target path) for rule in &self.rules { - if let Some(respected_rule) = rule.respected_rule() { - // Check if the rule's directory is an ancestor of or equal to the target path - if path.starts_with(&rule.parent_path) { - active_rules.push(respected_rule.clone()); - } else { - available_rule_paths.push(respected_rule.path.to_string_lossy().to_string()); + if path.starts_with(&rule.parent_path) { + for project_rule in rule.all_rules() { + active_rules.push(project_rule.clone()); + } + } else { + for project_rule in rule.all_rules() { + available_rule_paths + .push(project_rule.path.to_string_lossy().to_string()); } } } @@ -109,16 +121,16 @@ impl ProjectRules { .iter_mut() .find(|rule| rule.parent_path == parent)?; - if file_name.to_lowercase() == "warp.md" { - rule.warp_md.take() - } else if file_name.to_lowercase() == "agents.md" { - rule.agents_md.take() - } else { - None + match file_name.to_lowercase().as_str() { + "galaxy.md" => rule.galaxy_md.take(), + "warp.md" => rule.warp_md.take(), + "claude.md" => rule.claude_md.take(), + "agents.md" => rule.agents_md.take(), + _ => None, } } - /// Upsert a rule to the set of project rules. This will create a new RuleAtPath entry if none exists and update the existin one + /// Upsert a rule to the set of project rules. This will create a new RuleAtPath entry if none exists and update the existing one /// otherwise. #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] fn upsert_rule(&mut self, path: &Path, content: String) { @@ -139,32 +151,29 @@ impl ProjectRules { content, }); - match existing_rule { - Some(rule) => { - if file_name.to_lowercase() == "warp.md" { - rule.warp_md = rule_file; - } else if file_name.to_lowercase() == "agents.md" { - rule.agents_md = rule_file; - } - } + let rule_ref = match existing_rule { + Some(rule) => rule, None => { - let mut rule = RuleAtPath { + self.rules.push(RuleAtPath { parent_path: parent.to_path_buf(), ..Default::default() - }; - if file_name.to_lowercase() == "warp.md" { - rule.warp_md = rule_file; - } else if file_name.to_lowercase() == "agents.md" { - rule.agents_md = rule_file; - } - self.rules.push(rule); + }); + self.rules.last_mut().unwrap() } }; + + match file_name.to_lowercase().as_str() { + "galaxy.md" => rule_ref.galaxy_md = rule_file, + "warp.md" => rule_ref.warp_md = rule_file, + "claude.md" => rule_ref.claude_md = rule_file, + "agents.md" => rule_ref.agents_md = rule_file, + _ => {} + } } } /// Singleton model that keeps track of mapping between paths and rule files -/// Currently supports WARP.md files, but designed to be extensible +/// Supports GALAXY.md, WARP.md, CLAUDE.md, and AGENTS.md project rule files #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] #[derive(Debug, Default)] pub struct ProjectContextModel { @@ -237,18 +246,12 @@ impl ProjectContextModel { discovered_rules: rule_files .rules .iter() - .filter_map(|rule| { - rule.warp_md.as_ref().map(|rule| ProjectRulePath { + .flat_map(|rule| { + rule.all_rules().into_iter().map(|r| ProjectRulePath { project_root: root_clone.clone(), - path: rule.path.clone(), + path: r.path.clone(), }) }) - .chain(rule_files.rules.iter().filter_map(|rule| { - rule.agents_md.as_ref().map(|rule| ProjectRulePath { - project_root: root_clone.clone(), - path: rule.path.clone(), - }) - })) .collect(), deleted_rules: Default::default(), }; @@ -489,7 +492,7 @@ impl ProjectContextModel { (existing_rules, rules_delta) } - /// Scan a directory for rule files (currently WARP.md, extensible for future file types) + /// Scan a directory for rule files (GALAXY.md, WARP.md, CLAUDE.md, AGENTS.md) /// Uses repo_metadata::entry::build_tree for efficient directory traversal #[cfg(feature = "local_fs")] async fn scan_directory_for_rules(dir_path: &Path) -> Result { @@ -576,11 +579,10 @@ impl ProjectContextModel { pub fn indexed_rules(&self) -> impl Iterator + '_ { self.path_to_rules.values().flat_map(|rules| { - rules.rules.iter().filter_map(|rules| { - rules - .respected_rule() - .map(|project_rule| project_rule.path.clone()) - }) + rules + .rules + .iter() + .flat_map(|rule| rule.all_rules().into_iter().map(|r| r.path.clone())) }) } @@ -590,8 +592,9 @@ impl ProjectContextModel { .get(workspace_path) .into_iter() .flat_map(|rules| { - rules.rules.iter().filter_map(|rule| { - rule.respected_rule() + rules.rules.iter().flat_map(|rule| { + rule.all_rules() + .into_iter() .map(|project_rule| project_rule.path.clone()) }) }) diff --git a/crates/ai/src/project_context/model_tests.rs b/crates/ai/src/project_context/model_tests.rs index b132b7be..3a9afabe 100644 --- a/crates/ai/src/project_context/model_tests.rs +++ b/crates/ai/src/project_context/model_tests.rs @@ -121,12 +121,12 @@ fn test_find_applicable_rules_handles_root_path() { #[test] fn test_find_applicable_rules_complex_scenario() { - // This test covers the example from the original request: // For path /a/b/c/file.rs with rules: // - /a/WARP.md // - /a/AGENTS.md // - /a/b/WARP.md // - /a/b/AGENTS.md + // All ancestor rule files should be included. let mut rules = ProjectRules::default(); rules.upsert_rule(Path::new("/a/WARP.md"), "a_warp".to_string()); @@ -138,13 +138,13 @@ fn test_find_applicable_rules_complex_scenario() { let path = PathBuf::from("/a/b/c/file.rs"); let result = rules.find_active_or_applicable_rules(&path).active_rules; - assert_eq!(result.len(), 2); + assert_eq!(result.len(), 4); - // Expect only WARP.md files to be included as they have higher priority. - assert_eq!(result[0].path, PathBuf::from("/a/WARP.md")); - assert_eq!(result[0].content, "a_warp"); - assert_eq!(result[1].path, PathBuf::from("/a/b/WARP.md")); - assert_eq!(result[1].content, "ab_warp"); + let paths: Vec = result.iter().map(|r| r.path.clone()).collect(); + assert!(paths.contains(&PathBuf::from("/a/WARP.md"))); + assert!(paths.contains(&PathBuf::from("/a/AGENTS.md"))); + assert!(paths.contains(&PathBuf::from("/a/b/WARP.md"))); + assert!(paths.contains(&PathBuf::from("/a/b/AGENTS.md"))); } #[test] diff --git a/crates/ai/src/skills/skill_provider.rs b/crates/ai/src/skills/skill_provider.rs index 545facc8..accfe882 100644 --- a/crates/ai/src/skills/skill_provider.rs +++ b/crates/ai/src/skills/skill_provider.rs @@ -159,7 +159,7 @@ pub fn provider_rank(provider: SkillProvider) -> usize { pub fn home_skills_path(provider: SkillProvider) -> Option { if provider == SkillProvider::Warp { - return galaxy_core::paths::warp_home_skills_dir(); + return galaxy_core::paths::galaxy_home_skills_dir(); } let definition = SKILL_PROVIDER_DEFINITIONS .iter() @@ -220,17 +220,17 @@ mod tests { 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(galaxy_home_skills_dir) = galaxy_core::paths::galaxy_home_skills_dir() else { eprintln!("Skipping test: home directory not available"); return; }; - let path = warp_home_skills_dir.join("my-skill").join("SKILL.md"); + let path = galaxy_home_skills_dir.join("my-skill").join("SKILL.md"); assert_eq!(get_provider_for_path(&path), Some(SkillProvider::Warp)); assert_eq!(get_scope_for_path(&path), SkillScope::Home); diff --git a/crates/galaxy_cli/src/lib.rs b/crates/galaxy_cli/src/lib.rs index 4bf67fd2..512bf3d9 100644 --- a/crates/galaxy_cli/src/lib.rs +++ b/crates/galaxy_cli/src/lib.rs @@ -216,7 +216,7 @@ impl Args { } } - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { let args: Vec = env::args().collect(); if args.len() > 1 && args[1] == "secret" { eprintln!("error: unrecognized subcommand 'secret'\n"); @@ -313,7 +313,7 @@ impl Args { } // Hide the secret subcommand from help text. - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { command = command.mut_subcommand("secret", |c| c.hide(true)); } diff --git a/crates/galaxy_core/src/paths.rs b/crates/galaxy_core/src/paths.rs index 2927af5f..51d41aba 100644 --- a/crates/galaxy_core/src/paths.rs +++ b/crates/galaxy_core/src/paths.rs @@ -52,7 +52,7 @@ fn base_warp_config_dir_name() -> String { /// /// This preserves the historical `.warp*` directory shape while still isolating dev, local, /// integration, oss, and optional development profiles. -pub fn warp_home_config_dir_name() -> String { +pub fn galaxy_home_config_dir_name() -> String { let base_dir_name = base_warp_config_dir_name(); if let Some(data_profile) = ChannelState::data_profile() { @@ -67,13 +67,13 @@ pub fn warp_home_config_dir_name() -> String { /// Unlike [`data_dir`] and [`config_local_dir`] on non-macOS platforms, this intentionally keeps /// user-facing config under a `.warp-core*` directory in the home directory instead of /// using the platform XDG/AppData project directories. -pub fn warp_home_config_dir() -> Option { - dirs::home_dir().map(|home_dir| home_dir.join(warp_home_config_dir_name())) +pub fn galaxy_home_config_dir() -> Option { + dirs::home_dir().map(|home_dir| home_dir.join(galaxy_home_config_dir_name())) } /// Returns the legacy `~/.warp*` config directory path for the current channel, /// used to detect and migrate data from a previous Warp installation. -pub fn legacy_warp_home_config_dir() -> Option { +pub fn legacy_galaxy_home_config_dir() -> Option { let base = LEGACY_WARP_CONFIG_DIR; let dir_name = match ChannelState::channel() { Channel::Stable | Channel::Preview => base.to_owned(), @@ -100,10 +100,10 @@ pub fn legacy_warp_home_config_dir() -> Option { /// - The new directory already exists. /// - The old directory does not exist. pub fn migrate_legacy_config_dir_if_needed() { - let Some(old_dir) = legacy_warp_home_config_dir() else { + let Some(old_dir) = legacy_galaxy_home_config_dir() else { return; }; - let Some(new_dir) = warp_home_config_dir() else { + let Some(new_dir) = galaxy_home_config_dir() else { return; }; @@ -198,12 +198,12 @@ pub fn migrate_legacy_config_dir_if_needed() { } } -pub fn warp_home_skills_dir() -> Option { - warp_home_config_dir().map(|warp_config_dir| warp_config_dir.join("skills")) +pub fn galaxy_home_skills_dir() -> Option { + galaxy_home_config_dir().map(|warp_config_dir| warp_config_dir.join("skills")) } -pub fn warp_home_mcp_config_file_path() -> Option { - warp_home_config_dir().map(|warp_config_dir| warp_config_dir.join(".mcp.json")) +pub fn galaxy_home_mcp_config_file_path() -> Option { + galaxy_home_config_dir().map(|warp_config_dir| warp_config_dir.join(".mcp.json")) } /// Returns the macOS config directory name for the current channel. diff --git a/crates/galaxy_core/src/paths_tests.rs b/crates/galaxy_core/src/paths_tests.rs index 174b9745..75cb5625 100644 --- a/crates/galaxy_core/src/paths_tests.rs +++ b/crates/galaxy_core/src/paths_tests.rs @@ -37,7 +37,7 @@ fn test_config_local_dir_path() { } #[test] -fn test_warp_home_config_dir_path() { +fn test_galaxy_home_config_dir_path() { let home_dir = home_dir().expect("Should be able to compute home directory"); let expected_dir_name = match ChannelState::data_profile() { Some(data_profile) => format!(".warp-core-oss-{data_profile}"), @@ -45,20 +45,20 @@ fn test_warp_home_config_dir_path() { }; assert_eq!( - warp_home_config_dir(), + galaxy_home_config_dir(), Some(home_dir.join(expected_dir_name)) ); } #[test] fn test_warp_home_skills_and_mcp_paths() { - let Some(config_dir) = warp_home_config_dir() else { + let Some(config_dir) = galaxy_home_config_dir() else { panic!("Should be able to compute Warp home config directory"); }; - assert_eq!(warp_home_skills_dir(), Some(config_dir.join("skills"))); + assert_eq!(galaxy_home_skills_dir(), Some(config_dir.join("skills"))); assert_eq!( - warp_home_mcp_config_file_path(), + galaxy_home_mcp_config_file_path(), Some(config_dir.join(".mcp.json")) ); } diff --git a/crates/galaxy_core/src/telemetry.rs b/crates/galaxy_core/src/telemetry.rs index 4b94a25d..2270a84e 100644 --- a/crates/galaxy_core/src/telemetry.rs +++ b/crates/galaxy_core/src/telemetry.rs @@ -1,62 +1,19 @@ -use std::{fmt, marker::PhantomData}; - use galaxyui::{AppContext, Entity, SingletonEntity}; use serde_json::Value; use strum::IntoEnumIterator; -// Re-export for macro use. #[doc(hidden)] #[cfg(not(target_family = "wasm"))] pub use inventory::submit; -use crate::{ - channel::{Channel, ChannelState}, - features::FeatureFlag, -}; +use crate::features::FeatureFlag; -/// Core trait defining telemetry event behavior. -/// -/// This trait encapsulates the basic functionality required for any telemetry event -/// in the Warp ecosystem. It enables events to be defined in any crate while maintaining -/// consistent telemetry reporting behavior. pub trait TelemetryEvent: RegisteredTelemetryEvent { - /// Returns the name of the telemetry event. - /// - /// The name should be a stable identifier that uniquely identifies this type of event. - /// It is used for analytics tracking and should remain consistent over time. - /// - /// Returns a borrowed string to avoid allocations for static event names. fn name(&self) -> &'static str; - - /// Returns optional structured data associated with this event. - /// - /// The payload allows events to include additional context or metadata beyond - /// just the event name. This is useful for including dynamic data about the - /// event occurrence. - /// - /// Returns None if the event has no additional data to report. fn payload(&self) -> Option; - - /// Returns a human-readable description of what this event represents. - /// - /// The description should clearly explain the significance of the event to help - /// with analytics and monitoring. This is used both for documentation and - /// telemetry dashboards. fn description(&self) -> &'static str; - - /// Determines if an event is enabled in the current build. This only works when all - /// feature flags are set appropriately, so this should be used when running - /// the bundled app. fn enablement_state(&self) -> EnablementState; - - /// Returns whether this event contains user-generated content (UGC). - /// - /// Events containing UGC may need special handling for privacy and data - /// retention reasons. This flag helps route the event to the appropriate - /// analytics destination. fn contains_ugc(&self) -> bool; - - /// Returns an iterator over the descriptors for all telemetry events of this type. fn event_descs() -> impl Iterator>; } @@ -72,40 +29,28 @@ macro_rules! register_telemetry_event { }; } -/// Marker trait for known telemetry events. We rely on this to print an exhaustive telemetry -/// table in Warp's documentation. -/// -/// DO NOT implement this trait directly - use the [`register_telemetry_event!`] macro instead. pub trait RegisteredTelemetryEvent {} -/// An abstract description of a telemetry event we may emit. Every [`TelemetryEvent`] has a -/// corresponding [`TelemetryEventDesc`]. -pub trait TelemetryEventDesc: fmt::Debug { +pub trait TelemetryEventDesc: std::fmt::Debug { fn name(&self) -> &'static str; fn description(&self) -> &'static str; fn enablement_state(&self) -> EnablementState; } -/// A type-erased version of [`TelemetryEventRegistration`]. This is only used by the -/// [`register_telemetry_event!`] macro implementation. #[doc(hidden)] pub trait AnyTelemetryEventRegistration: Sync { - /// Returns an iterator over the descriptors for all telemetry events in this [`TelemetryEvent`] implementation. fn events(&self) -> Box>>; } -/// Adapter for statically registering all [`TelemetryEvent`] implementations. #[doc(hidden)] pub struct TelemetryEventRegistration { - /// Marker that `TelemetryEventRegistration` references `T`, but doesn't own a `T` value. - /// See https://doc.rust-lang.org/nomicon/phantom-data.html - _marker: PhantomData T>, + _marker: std::marker::PhantomData T>, } impl TelemetryEventRegistration { pub const fn adapt() -> &'static dyn AnyTelemetryEventRegistration { &Self { - _marker: PhantomData, + _marker: std::marker::PhantomData, } } } @@ -116,9 +61,6 @@ impl AnyTelemetryEventRegistration for TelemetryEve } } -/// Returns an iterator over all discriminants of `T` as [`TelemetryEventDesc`]s. -/// -/// Telemetry events that use [`strum`] may use this to implement [`TelemetryEvent::event_descs`]. pub fn enum_events() -> impl Iterator> where T: strum::IntoDiscriminant, @@ -128,107 +70,47 @@ where .map(|discriminant| Box::new(discriminant) as Box) } -// Collect adapters for all registered telemetry events. Because `inventory::collect!` requires a -// concrete type, we use `&static dyn Trait` to erase the generics. #[cfg(not(target_family = "wasm"))] inventory::collect!(&'static dyn AnyTelemetryEventRegistration); -/// Returns all registered telemetry events. This is not available in WASM builds, as it relies on -/// the [`inventory`] crate, which does not fully work in our WASM configuration. #[cfg(not(target_family = "wasm"))] pub fn all_events() -> impl Iterator> { inventory::iter::<&'static dyn AnyTelemetryEventRegistration>().flat_map(|meta| meta.events()) } -// Sends a telemetry `track` event to Rudderstack asynchronously. It adds events to the static -// telemetry queue that is periodically flushed to the Rudderstack API. -// This is the recommended way of recording telemetry events. -// You should almost always use this, unless the recording is time-sensitive and cannot be lost. -// To send a telemetry event synchronously, use [`send_telemetry_sync_from_ctx`]. +/// No-op: telemetry has been removed from Galaxy. #[macro_export] macro_rules! send_telemetry_from_ctx { ($event:expr, $ctx:expr) => { - #[allow(unused_imports)] - use galaxy_core::telemetry::TelemetryEvent as _; - let event = $event; - if event.enablement_state().is_enabled() { - let auth_state = - <$crate::telemetry::TelemetryContextModel as galaxyui::SingletonEntity>::handle( - $ctx, - ) - .as_ref($ctx); - let user_id = auth_state.user_id($ctx); - let anonymous_id = auth_state.anonymous_id($ctx); - galaxyui::record_telemetry_from_ctx!( - user_id, - anonymous_id, - event.name().into(), - event.payload(), - event.contains_ugc(), - $ctx - ); - } + let _ = &$event; + let _ = &$ctx; }; } -/// Sends telemetry `track` event to Rudderstack API asynchronously. This is the same as the -/// [`send_telemetry_from_ctx`], except it can be called in instances where you only have -/// a `AppContext` rather than a `ViewContext`/`ModelContext`. -/// -/// If possible, use [`send_telemetry_from_ctx`]. +/// No-op: telemetry has been removed from Galaxy. #[macro_export] macro_rules! send_telemetry_from_app_ctx { ($event:expr, $app_ctx:expr) => { - let event = $event; - if event.enablement_state().is_enabled() { - let auth_state = - <$crate::telemetry::TelemetryContextModel as galaxyui::SingletonEntity>::handle( - $app_ctx, - ) - .as_ref($app_ctx); - let user_id = auth_state.user_id($app_ctx.as_ref()); - let anonymous_id = auth_state.anonymous_id($app_ctx.as_ref()); - galaxyui::record_telemetry_on_executor!( - user_id, - anonymous_id, - event.name().into(), - event.payload(), - event.contains_ugc(), - $app_ctx.background_executor() - ); - } + let _ = &$event; + let _ = &$app_ctx; }; } -/// Gives information about when a telemetry event is enabled. #[derive(Debug)] pub enum EnablementState { Always, - /// The telemetry event is enabled when a particular feature flag is enabled. Flag(FeatureFlag), - /// The event is enabled if the app is running in one of the contained channels. - ChannelSpecific { - channels: Vec, - }, + ChannelSpecific { channels: Vec }, } impl EnablementState { pub fn is_enabled(&self) -> bool { - match self { - EnablementState::Always => true, - EnablementState::Flag(flag) => flag.is_enabled(), - EnablementState::ChannelSpecific { channels } => { - let app_channel = ChannelState::channel(); - channels.contains(&app_channel) - } - } + false } } -/// Trait for the context provider that allows us to send telemetry payloads. pub trait TelemetryContextProvider { fn user_id(&self, ctx: &AppContext) -> Option; - fn anonymous_id(&self, ctx: &AppContext) -> String; } diff --git a/crates/galaxy_core/src/ui/appearance.rs b/crates/galaxy_core/src/ui/appearance.rs index 415f5bb4..827ed81e 100644 --- a/crates/galaxy_core/src/ui/appearance.rs +++ b/crates/galaxy_core/src/ui/appearance.rs @@ -3,7 +3,7 @@ use galaxyui::{ Entity, ModelContext, SingletonEntity, }; -use super::{builder::UiBuilder, theme::WarpTheme}; +use super::{builder::UiBuilder, theme::GalaxyTheme}; /// The standard font size to use for headers (e.g.: in dialogs). const HEADER_FONT_SIZE: f32 = 18.; @@ -17,7 +17,7 @@ pub const DEFAULT_COMMAND_PALETTE_FONT_SIZE: f32 = 14.0; /// to individually listen for changes. The most prominent examples are /// settings related to themes and fonts. pub struct Appearance { - theme: WarpTheme, + theme: GalaxyTheme, monospace_font_family: FamilyId, monospace_font_size: f32, monospace_font_weight: Weight, @@ -71,7 +71,7 @@ pub enum AppearanceEvent { impl Appearance { #[allow(clippy::too_many_arguments)] pub fn new( - theme: WarpTheme, + theme: GalaxyTheme, monospace_font_family: FamilyId, monospace_font_size: f32, monospace_font_weight: Weight, @@ -105,7 +105,7 @@ impl Appearance { use crate::ui::theme::{mock_terminal_colors, Details, Fill}; - let mock_theme = WarpTheme::new( + let mock_theme = GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x000000ff)), ColorU::from_u32(0xffffffff), Fill::Solid(ColorU::new(18, 123, 156, 255)), @@ -137,7 +137,7 @@ impl Appearance { } } - pub fn set_theme(&mut self, new_theme: WarpTheme, ctx: &mut ModelContext) { + pub fn set_theme(&mut self, new_theme: GalaxyTheme, ctx: &mut ModelContext) { self.theme = new_theme; self.ui_builder = UiBuilder::new( self.theme.clone(), @@ -274,7 +274,7 @@ impl Appearance { &self.ui_builder } - pub fn theme(&self) -> &WarpTheme { + pub fn theme(&self) -> &GalaxyTheme { &self.theme } diff --git a/crates/galaxy_core/src/ui/builder.rs b/crates/galaxy_core/src/ui/builder.rs index fa82fbaf..4469c2cb 100644 --- a/crates/galaxy_core/src/ui/builder.rs +++ b/crates/galaxy_core/src/ui/builder.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use super::color::{blend::Blend, contrast::MinimumAllowedContrast, ContrastingColor}; use super::theme::color::internal_colors::{self, text_main}; -use super::theme::{Fill, WarpTheme}; +use super::theme::{Fill, GalaxyTheme}; use galaxyui::color::ColorU; use galaxyui::elements::{ ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, Hoverable, @@ -59,7 +59,7 @@ pub const DEFAULT_KEYBOARD_SHORTCUT_HEIGHT: f32 = 24.; #[derive(Clone, Debug)] pub struct UiBuilder { - warp_theme: WarpTheme, + warp_theme: GalaxyTheme, ui_font_family: FamilyId, ui_font_size: f32, command_palette_font_size: f32, @@ -68,7 +68,7 @@ pub struct UiBuilder { impl UiBuilder { pub fn new( - warp_theme: WarpTheme, + warp_theme: GalaxyTheme, ui_font_family: FamilyId, ui_font_size: f32, command_palette_font_size: f32, @@ -1196,7 +1196,7 @@ impl UiBuilder { self.command_palette_font_size } - pub fn warp_theme(&self) -> &WarpTheme { + pub fn warp_theme(&self) -> &GalaxyTheme { &self.warp_theme } diff --git a/crates/galaxy_core/src/ui/theme/color.rs b/crates/galaxy_core/src/ui/theme/color.rs index ff675fc6..d1d0c39d 100644 --- a/crates/galaxy_core/src/ui/theme/color.rs +++ b/crates/galaxy_core/src/ui/theme/color.rs @@ -8,7 +8,7 @@ use self::internal_colors::{ neutral_4, }; -use super::{AnsiColor, AnsiColorIdentifier, Fill, TerminalColors, WarpTheme}; +use super::{AnsiColor, AnsiColorIdentifier, Fill, TerminalColors, GalaxyTheme}; use crate::ui::color::{ blend::Blend, @@ -88,7 +88,7 @@ impl Default for CustomDetails { } // Core colors -impl WarpTheme { +impl GalaxyTheme { pub fn accent(&self) -> Fill { self.accent } @@ -225,7 +225,7 @@ impl WarpTheme { } // Feature-specific theme colors -impl WarpTheme { +impl GalaxyTheme { pub fn foreground_button_color(&self) -> Fill { let details = self.details(); self.background.blend( @@ -362,7 +362,7 @@ impl WarpTheme { } // ANSI color blends -impl WarpTheme { +impl GalaxyTheme { pub fn ansi_bg(&self, ansi_color: AnsiColor) -> ColorU { let ansi_fill = Fill::from(ansi_color); self.background() @@ -419,30 +419,30 @@ impl WarpTheme { } /// Internal color system tokens, defined in "Colors" [Figma project](https://www.figma.com/design/dnvTdLbfFaosFSP00F30S0/Colors). -/// Should not be used directly outside of reusable components. Use color methods on `WarpTheme` instead. +/// Should not be used directly outside of reusable components. Use color methods on `GalaxyTheme` instead. pub mod internal_colors { use galaxyui::color::ColorU; - use super::{Fill, WarpTheme}; + use super::{Fill, GalaxyTheme}; use crate::ui::color::blend::Blend; use crate::ui::color::coloru_with_opacity; /// Calculates the font color based on contrast needs for text legibility. /// The font color is a mixture of the `warp_theme`'s background and foreground /// colors, and the supplied `background` color. - fn font_color(warp_theme: &WarpTheme, background: impl Into) -> ColorU { + fn font_color(warp_theme: &GalaxyTheme, background: impl Into) -> ColorU { warp_theme.font_color(background).into_solid() } /// Used for UI elements like buttons to which we want to call attention. /// Allows gradients so shouldn't be used for small elements. - pub fn accent(warp_theme: &WarpTheme) -> Fill { + pub fn accent(warp_theme: &GalaxyTheme) -> Fill { warp_theme.accent() } /// Hover state for UI elements like buttons to which we want to call attention. /// Allows gradients so shouldn't be used for small elements. - pub fn accent_hover(warp_theme: &WarpTheme) -> Fill { + pub fn accent_hover(warp_theme: &GalaxyTheme) -> Fill { warp_theme .accent() .blend(&warp_theme.foreground().with_opacity(40)) @@ -452,148 +452,148 @@ pub mod internal_colors { /// to which we want to call attention. /// Allows gradients so shouldn't be used for small elements. #[allow(dead_code)] - pub fn accent_pressed(warp_theme: &WarpTheme) -> Fill { + pub fn accent_pressed(warp_theme: &GalaxyTheme) -> Fill { warp_theme .accent() .blend(&warp_theme.background().with_opacity(30)) } /// The color of most text throughout the UI. - pub fn text_main(warp_theme: &WarpTheme, background: impl Into) -> ColorU { + pub fn text_main(warp_theme: &GalaxyTheme, background: impl Into) -> ColorU { coloru_with_opacity(font_color(warp_theme, background), 90) } /// The color of subheaders and similar lower priority text. - pub fn text_sub(warp_theme: &WarpTheme, background: impl Into) -> ColorU { + pub fn text_sub(warp_theme: &GalaxyTheme, background: impl Into) -> ColorU { coloru_with_opacity(font_color(warp_theme, background), 60) } /// The color of text elements that are disabled or the lowest priority. - pub fn text_disabled(warp_theme: &WarpTheme, background: impl Into) -> ColorU { + pub fn text_disabled(warp_theme: &GalaxyTheme, background: impl Into) -> ColorU { coloru_with_opacity(font_color(warp_theme, background), 40) } // TODO (roland): evaluate whether text_disabled above is intentionally different or if it should be consolidated with this // which matches figma mocks. - pub fn semantic_text_disabled(warp_theme: &WarpTheme) -> ColorU { + pub fn semantic_text_disabled(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&fg_overlay_5(warp_theme)) .into() } - pub fn neutral_1(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_1(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(5)) .into_solid() } - pub fn neutral_2(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_2(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(10)) .into_solid() } - pub fn neutral_3(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_3(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(15)) .into_solid() } - pub fn neutral_4(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_4(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(20)) .into_solid() } - pub fn neutral_5(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_5(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(40)) .into_solid() } - pub fn neutral_6(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_6(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(60)) .into_solid() } - pub fn neutral_7(warp_theme: &WarpTheme) -> ColorU { + pub fn neutral_7(warp_theme: &GalaxyTheme) -> ColorU { warp_theme .background() .blend(&warp_theme.foreground().with_opacity(90)) .into_solid() } - pub fn fg_overlay_1(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_1(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(5) } - pub fn fg_overlay_2(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_2(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(10) } - pub fn fg_overlay_3(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_3(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(15) } - pub fn fg_overlay_4(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_4(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(20) } - pub fn fg_overlay_5(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_5(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(40) } - pub fn fg_overlay_6(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_6(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(60) } - pub fn fg_overlay_7(warp_theme: &WarpTheme) -> Fill { + pub fn fg_overlay_7(warp_theme: &GalaxyTheme) -> Fill { warp_theme.foreground().with_opacity(90) } - pub fn accent_bg_strong(warp_theme: &WarpTheme) -> Fill { + pub fn accent_bg_strong(warp_theme: &GalaxyTheme) -> Fill { Fill::Solid(warp_theme.background().into_solid()) .blend(&warp_theme.accent().with_opacity(60)) } - pub fn accent_bg(warp_theme: &WarpTheme) -> Fill { + pub fn accent_bg(warp_theme: &GalaxyTheme) -> Fill { Fill::Solid(warp_theme.background().into_solid()) .blend(&warp_theme.accent().with_opacity(40)) } - pub fn accent_fg_strong(warp_theme: &WarpTheme) -> Fill { + pub fn accent_fg_strong(warp_theme: &GalaxyTheme) -> Fill { warp_theme .foreground() .blend(&warp_theme.accent().with_opacity(60)) } - pub fn accent_fg(warp_theme: &WarpTheme) -> Fill { + pub fn accent_fg(warp_theme: &GalaxyTheme) -> Fill { warp_theme .foreground() .blend(&warp_theme.accent().with_opacity(40)) } - pub fn accent_overlay_1(warp_theme: &WarpTheme) -> Fill { + pub fn accent_overlay_1(warp_theme: &GalaxyTheme) -> Fill { warp_theme.accent().with_opacity(10) } - pub fn accent_overlay_2(warp_theme: &WarpTheme) -> Fill { + pub fn accent_overlay_2(warp_theme: &GalaxyTheme) -> Fill { warp_theme.accent().with_opacity(25) } - pub fn accent_overlay_3(warp_theme: &WarpTheme) -> Fill { + pub fn accent_overlay_3(warp_theme: &GalaxyTheme) -> Fill { warp_theme.accent().with_opacity(40) } - pub fn accent_overlay_4(warp_theme: &WarpTheme) -> Fill { + pub fn accent_overlay_4(warp_theme: &GalaxyTheme) -> Fill { warp_theme.accent().with_opacity(60) } } diff --git a/crates/galaxy_core/src/ui/theme/mod.rs b/crates/galaxy_core/src/ui/theme/mod.rs index d97b1adc..4bffc3b6 100644 --- a/crates/galaxy_core/src/ui/theme/mod.rs +++ b/crates/galaxy_core/src/ui/theme/mod.rs @@ -599,7 +599,7 @@ impl TerminalColors { } #[derive(Serialize, Clone, Debug, Deserialize, PartialEq, Eq)] -pub struct WarpTheme { +pub struct GalaxyTheme { background: Fill, accent: Fill, #[serde(with = "hex_color")] @@ -617,7 +617,7 @@ pub struct WarpTheme { name: Option, } -impl WarpTheme { +impl GalaxyTheme { #[allow(clippy::too_many_arguments)] pub fn new( bg: Fill, @@ -629,7 +629,7 @@ impl WarpTheme { background_image: Option, name: Option, ) -> Self { - WarpTheme { + GalaxyTheme { background: bg, foreground, accent, diff --git a/crates/galaxy_core/src/ui/theme/theme_tests.rs b/crates/galaxy_core/src/ui/theme/theme_tests.rs index cfc9fdf9..dc9368a6 100644 --- a/crates/galaxy_core/src/ui/theme/theme_tests.rs +++ b/crates/galaxy_core/src/ui/theme/theme_tests.rs @@ -2,7 +2,7 @@ use super::*; #[test] fn serialize_test() { - let theme = WarpTheme::new( + let theme = GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x20A5BAFF)), ColorU::from_u32(0x20A5BAFF), Fill::Solid(ColorU::from_u32(0x20A5BAFF)), @@ -45,7 +45,7 @@ name: test_theme #[test] fn deserialize_with_name_test() { - let theme = serde_yaml::from_str::( + let theme = serde_yaml::from_str::( r##"--- background: "#20a5ba" accent: "#20a5ba" @@ -75,7 +75,7 @@ name: test_theme ) .expect("Couldn't deserialize"); - let expected_theme = WarpTheme::new( + let expected_theme = GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x20A5BAFF)), ColorU::from_u32(0x20A5BAFF), Fill::Solid(ColorU::from_u32(0x20A5BAFF)), @@ -91,7 +91,7 @@ name: test_theme #[test] fn deserialize_without_name_test() { - let theme = serde_yaml::from_str::( + let theme = serde_yaml::from_str::( r##"--- background: "#20a5ba" accent: "#20a5ba" @@ -120,7 +120,7 @@ terminal_colors: ) .expect("Couldn't deserialize"); - let expected_theme = WarpTheme::new( + let expected_theme = GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x20A5BAFF)), ColorU::from_u32(0x20A5BAFF), Fill::Solid(ColorU::from_u32(0x20A5BAFF)), diff --git a/crates/galaxy_features/src/lib.rs b/crates/galaxy_features/src/lib.rs index 0ceca833..5046b6a1 100644 --- a/crates/galaxy_features/src/lib.rs +++ b/crates/galaxy_features/src/lib.rs @@ -232,7 +232,7 @@ pub enum FeatureFlag { KittyImages, /// Enables support for Warp Packs. - WarpPacks, + GalaxyPacks, /// Enables the revised AI analytics policy banner. /// @@ -582,7 +582,7 @@ pub enum FeatureFlag { CloudModeHostSelector, /// Enables Warp Managed Secrets functionality. - WarpManagedSecrets, + GalaxyManagedSecrets, /// Enables support for AM file diffs backed by the V4A patch format. V4AFileDiffs, diff --git a/crates/galaxy_logging/src/wasm.rs b/crates/galaxy_logging/src/wasm.rs index 981bd456..5065a4a8 100644 --- a/crates/galaxy_logging/src/wasm.rs +++ b/crates/galaxy_logging/src/wasm.rs @@ -171,7 +171,7 @@ impl Log for WasmLogger { ); // Send error logs to Sentry. galaxy_web_event_bus::emit_event( - galaxy_web_event_bus::WarpEvent::ErrorLogged { error }, + galaxy_web_event_bus::GalaxyEvent::ErrorLogged { error }, ); console::error_4( diff --git a/crates/galaxy_web_event_bus/src/lib.rs b/crates/galaxy_web_event_bus/src/lib.rs index 37f0d862..698b71ba 100644 --- a/crates/galaxy_web_event_bus/src/lib.rs +++ b/crates/galaxy_web_event_bus/src/lib.rs @@ -6,10 +6,10 @@ use wasm_bindgen::JsCast; /// Events emitted from Warp on Web to the host JavaScript app. /// -/// These must stay in sync with the [`WarpEvent` TypeScript type](https://github.com/warpdotdev/warp-server/blob/develop/client/src/warp-client/index.ts). +/// These must stay in sync with the [`GalaxyEvent` TypeScript type](https://github.com/warpdotdev/warp-server/blob/develop/client/src/warp-client/index.ts). #[derive(Debug, Clone, Serialize)] #[serde(tag = "kind", rename_all = "SCREAMING_SNAKE_CASE")] -pub enum WarpEvent { +pub enum GalaxyEvent { LoggedOut, SessionJoined, ErrorLogged { error: String }, @@ -42,7 +42,7 @@ mod ffi { } /// Emit an event to the host JavaScript app. -pub fn emit_event(event: WarpEvent) { +pub fn emit_event(event: GalaxyEvent) { let serialized = serde_wasm_bindgen::to_value(&event).expect("Event must convert to JavaScript"); match ffi::emit_event(serialized) { diff --git a/crates/galaxyui_core/src/accessibility.rs b/crates/galaxyui_core/src/accessibility.rs index a1a37d32..ad913eaf 100644 --- a/crates/galaxyui_core/src/accessibility.rs +++ b/crates/galaxyui_core/src/accessibility.rs @@ -70,7 +70,7 @@ pub struct AccessibilityContent { /// for example, when the “Command Input” is focused, it announces with a `TextareaRole`. /// This is another helper field that lets the user understand what they can potentially do, /// or what object is in focus. - pub role: WarpA11yRole, + pub role: GalaxyA11yRole, } /// Verbosity level of a11y announcements. By default, all announcements include both the value @@ -148,14 +148,14 @@ fn string_announcement(s: String) -> String { impl AccessibilityContent { // TODO add frame support - pub fn new_without_help(value: T, role: WarpA11yRole) -> Self + pub fn new_without_help(value: T, role: GalaxyA11yRole) -> Self where T: Into, { Self::new_internal::(value, None, role) } - pub fn new(value: V, help: H, role: WarpA11yRole) -> Self + pub fn new(value: V, help: H, role: GalaxyA11yRole) -> Self where V: Into, H: Into, @@ -163,7 +163,7 @@ impl AccessibilityContent { Self::new_internal(value, Some(help), role) } - fn new_internal(value: V, help: Option, role: WarpA11yRole) -> Self + fn new_internal(value: V, help: Option, role: GalaxyA11yRole) -> Self where V: Into, H: Into, @@ -203,7 +203,7 @@ impl AccessibilityContent { } #[derive(Default, Debug, Clone, Copy)] -pub enum WarpA11yRole { +pub enum GalaxyA11yRole { ButtonRole, CheckboxRole, HelpRole, @@ -222,9 +222,9 @@ pub enum WarpA11yRole { UserAction, } -impl std::fmt::Display for WarpA11yRole { +impl std::fmt::Display for GalaxyA11yRole { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - use WarpA11yRole::*; + use GalaxyA11yRole::*; let word = match self { ButtonRole => "Button", CheckboxRole => "Checkbox", @@ -257,7 +257,7 @@ pub enum ActionAccessibilityContent { impl ActionAccessibilityContent { pub fn from_debug() -> Self { Self::CustomFn(|action| { - AccessibilityContent::new_without_help(format!("{action:?}."), WarpA11yRole::UserAction) + AccessibilityContent::new_without_help(format!("{action:?}."), GalaxyA11yRole::UserAction) }) } } diff --git a/crates/galaxyui_core/src/notification.rs b/crates/galaxyui_core/src/notification.rs index 78aaf144..732d0d88 100644 --- a/crates/galaxyui_core/src/notification.rs +++ b/crates/galaxyui_core/src/notification.rs @@ -112,8 +112,8 @@ pub enum NotificationSendError { impl NotificationSendError { pub fn notifications_error_banner_title(&self) -> &str { match self { - NotificationSendError::PermissionsDenied | NotificationSendError::PermissionsNotYetGranted => "Warp tried to send you a notification for the last block but does not have permission.", - NotificationSendError::Other { .. } => "Warp tried to send you a notification for the last block, but something went wrong.", + NotificationSendError::PermissionsDenied | NotificationSendError::PermissionsNotYetGranted => "Galaxy tried to send you a notification for the last block but does not have permission.", + NotificationSendError::Other { .. } => "Galaxy tried to send you a notification for the last block, but something went wrong.", } } } diff --git a/crates/integration/src/test.rs b/crates/integration/src/test.rs index 95df1a42..eb60e4db 100644 --- a/crates/integration/src/test.rs +++ b/crates/integration/src/test.rs @@ -286,7 +286,7 @@ pub fn test_add_workflows_to_warp_config() -> Builder { workflows.read(app, |workflows, _| { // Note that this can be a synchronous assertion because unlike the next test step, - // we don't have concurrency with a WarpConfig watcher thread + // we don't have concurrency with a GalaxyConfig watcher thread assert_eq!( workflows.local_workflows().count(), 0, diff --git a/crates/integration/src/test/launch_configs.rs b/crates/integration/src/test/launch_configs.rs index 70205a63..39fcdca1 100644 --- a/crates/integration/src/test/launch_configs.rs +++ b/crates/integration/src/test/launch_configs.rs @@ -50,7 +50,7 @@ pub fn test_add_launch_config_to_warp_config() -> Builder { .clone(); launch_config_data_source.read(app, |palette, app| { // Note that this can be a synchronous assertion because unlike the next test step, - // we don't have concurrency with a WarpConfig watcher thread + // we don't have concurrency with a GalaxyConfig watcher thread assert_eq!( palette.run_query(&Query::from(""), app).unwrap().len(), 0, diff --git a/crates/integration/src/test/workflows.rs b/crates/integration/src/test/workflows.rs index b19d45d0..f99340fe 100644 --- a/crates/integration/src/test/workflows.rs +++ b/crates/integration/src/test/workflows.rs @@ -104,7 +104,7 @@ pub fn test_loading_project_workflows() -> Builder { workflows.read(app, |workflows, _| { // Note that this can be a synchronous assertion because unlike the next assertion, - // we don't have concurrency with a WarpConfig watcher thread + // we don't have concurrency with a GalaxyConfig watcher thread async_assert_eq!( workflows.project_workflows().count(), 0, diff --git a/crates/managed_secrets/src/manager.rs b/crates/managed_secrets/src/manager.rs index 1f78996d..7b50f30d 100644 --- a/crates/managed_secrets/src/manager.rs +++ b/crates/managed_secrets/src/manager.rs @@ -49,7 +49,7 @@ impl ManagedSecretManager { let client = self.client.clone(); let actor_provider = self.actor_provider.clone(); async move { - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { return Err(anyhow::anyhow!("This feature is not enabled")); } // We retrieve all upload keys on demand. These should potentially be fetched and stored @@ -91,7 +91,7 @@ impl ManagedSecretManager { ) -> impl Future> + use<> { let client = self.client.clone(); async move { - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { return Err(anyhow::anyhow!("This feature is not enabled")); } @@ -110,7 +110,7 @@ impl ManagedSecretManager { let client = self.client.clone(); let actor_provider = self.actor_provider.clone(); async move { - if !FeatureFlag::WarpManagedSecrets.is_enabled() { + if !FeatureFlag::GalaxyManagedSecrets.is_enabled() { return Err(anyhow::anyhow!("This feature is not enabled")); } diff --git a/crates/onboarding/examples/callout.rs b/crates/onboarding/examples/callout.rs index 63345420..fd0ae8c6 100644 --- a/crates/onboarding/examples/callout.rs +++ b/crates/onboarding/examples/callout.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Result}; 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, TerminalColors, GalaxyTheme}; use galaxyui::color::ColorU; use galaxyui::elements::{Rect, Stack}; use galaxyui::fonts::{Cache, FamilyId, Weight}; @@ -115,7 +115,7 @@ impl TypedActionView for RootView { fn handle_action(&mut self, _action: &Self::Action, _ctx: &mut ViewContext) {} } -fn mock_theme() -> WarpTheme { +fn mock_theme() -> GalaxyTheme { let normal = AnsiColors::new( AnsiColor::from_u32(0x121212FF), AnsiColor::from_u32(0xC76156FF), @@ -138,7 +138,7 @@ fn mock_theme() -> WarpTheme { AnsiColor::from_u32(0xFFFFFFFF), ); - WarpTheme::new( + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x1D2022FF)), ColorU::from_u32(0xE4EEF5FF), Fill::Solid(ColorU::from_u32(0x6C96B4FF)), @@ -151,7 +151,7 @@ fn mock_theme() -> WarpTheme { } fn build_appearance( - theme: WarpTheme, + theme: GalaxyTheme, ui_font_family: FamilyId, ctx: &mut ModelContext, ) -> Appearance { diff --git a/crates/onboarding/examples/callout_flow.rs b/crates/onboarding/examples/callout_flow.rs index 05d44667..096d4d27 100644 --- a/crates/onboarding/examples/callout_flow.rs +++ b/crates/onboarding/examples/callout_flow.rs @@ -1,6 +1,6 @@ use anyhow::Result; 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, TerminalColors, GalaxyTheme}; use galaxyui::fonts::{Cache, FamilyId, Weight}; use galaxyui::platform; use galaxyui::prelude::CrossAxisAlignment; @@ -220,8 +220,8 @@ fn adeberry_colors() -> TerminalColors { TerminalColors::new(ADEBERRY_NORMAL_COLORS, ADEBERRY_BRIGHT_COLORS) } -fn adeberry() -> WarpTheme { - WarpTheme::new( +fn adeberry() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x1D2022FF)), ColorU::from_u32(0xE4EEF5FF), Fill::Solid(ColorU::from_u32(0x6C96B4FF)), @@ -233,7 +233,7 @@ fn adeberry() -> WarpTheme { ) } -fn build_appearance(theme: WarpTheme, ctx: &mut AppContext) -> Appearance { +fn build_appearance(theme: GalaxyTheme, ctx: &mut AppContext) -> Appearance { let ui_font_family = load_default_ui_font_family(ctx).expect("unable to load default ui font family"); diff --git a/crates/onboarding/src/agent_onboarding_view.rs b/crates/onboarding/src/agent_onboarding_view.rs index 1f960b7d..7fc46bdc 100644 --- a/crates/onboarding/src/agent_onboarding_view.rs +++ b/crates/onboarding/src/agent_onboarding_view.rs @@ -22,7 +22,7 @@ use std::time::Duration; const APP_BECAME_ACTIVE_DEBOUNCE: Duration = Duration::from_secs(15); -use galaxy_core::ui::{appearance::Appearance, theme::WarpTheme}; +use galaxy_core::ui::{appearance::Appearance, theme::GalaxyTheme}; use galaxyui::elements::Rect; use galaxyui::{ elements::{ @@ -111,7 +111,7 @@ impl AgentOnboardingView { /// Creates a new AgentOnboardingView. #[allow(clippy::too_many_arguments)] pub fn new( - theme_picker_themes: [WarpTheme; 4], + theme_picker_themes: [GalaxyTheme; 4], skippable: bool, models: Vec, default_model_id: LLMId, diff --git a/crates/onboarding/src/bin/main.rs b/crates/onboarding/src/bin/main.rs index d8616532..34c88a3b 100644 --- a/crates/onboarding/src/bin/main.rs +++ b/crates/onboarding/src/bin/main.rs @@ -4,7 +4,7 @@ use ai::LLMId; use anyhow::Result; use galaxy_core::ui::icons::Icon; use galaxy_core::ui::theme::{AnsiColor, AnsiColors, Details, Fill, Image, TerminalColors}; -use galaxy_core::ui::{appearance::Appearance, theme::WarpTheme}; +use galaxy_core::ui::{appearance::Appearance, theme::GalaxyTheme}; use galaxyui::assets::asset_cache::AssetSource; use galaxyui::platform; use galaxyui::{ @@ -385,8 +385,8 @@ fn adeberry_colors() -> TerminalColors { TerminalColors::new(ADEBERRY_NORMAL_COLORS, ADEBERRY_BRIGHT_COLORS) } -fn dark_theme() -> WarpTheme { - WarpTheme::new( +fn dark_theme() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x000000FF)), ColorU::from_u32(0xffffffff), Fill::Solid(ColorU::from_u32(0x19AAD8FF)), @@ -398,8 +398,8 @@ fn dark_theme() -> WarpTheme { ) } -fn light_theme() -> WarpTheme { - WarpTheme::new( +fn light_theme() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::white()), ColorU::new(17, 17, 17, 0xFF), Fill::Solid(ColorU::from_u32(0x00c2ffff)), @@ -411,8 +411,8 @@ fn light_theme() -> WarpTheme { ) } -fn phenomenon() -> WarpTheme { - WarpTheme::new( +fn phenomenon() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x121212FF)), ColorU::from_u32(0xFAF9F6FF), Fill::Solid(ColorU::from_u32(0x2E5D9EFF)), @@ -430,8 +430,8 @@ fn phenomenon() -> WarpTheme { ) } -fn adeberry() -> WarpTheme { - WarpTheme::new( +fn adeberry() -> GalaxyTheme { + GalaxyTheme::new( Fill::Solid(ColorU::from_u32(0x1D2022FF)), ColorU::from_u32(0xE4EEF5FF), Fill::Solid(ColorU::from_u32(0x6C96B4FF)), @@ -443,7 +443,7 @@ fn adeberry() -> WarpTheme { ) } -fn build_appearance(theme: WarpTheme, ctx: &mut AppContext) -> Appearance { +fn build_appearance(theme: GalaxyTheme, ctx: &mut AppContext) -> Appearance { let ui_font_family = load_default_ui_font_family(ctx).expect("unable to load default ui font family"); diff --git a/crates/onboarding/src/slides/theme_picker_slide.rs b/crates/onboarding/src/slides/theme_picker_slide.rs index d7173379..06098409 100644 --- a/crates/onboarding/src/slides/theme_picker_slide.rs +++ b/crates/onboarding/src/slides/theme_picker_slide.rs @@ -6,7 +6,7 @@ use crate::visuals::theme_picker_visual; use crate::OnboardingIntention; use galaxy_core::features::FeatureFlag; use galaxy_core::send_telemetry_from_ctx; -use galaxy_core::ui::{appearance::Appearance, theme::color::internal_colors, theme::WarpTheme}; +use galaxy_core::ui::{appearance::Appearance, theme::color::internal_colors, theme::GalaxyTheme}; use galaxyui::{ elements::{ Border, ClippedScrollStateHandle, ConstrainedBox, Container, CornerRadius, @@ -54,7 +54,7 @@ const TOS_URL: &str = "https://www.warp.dev/terms-of-service"; #[derive(Debug, Clone)] struct ThemeOption { - theme: WarpTheme, + theme: GalaxyTheme, mouse_state: MouseStateHandle, } @@ -73,7 +73,7 @@ pub struct ThemePickerSlide { impl ThemePickerSlide { pub(crate) fn new( - themes: [WarpTheme; 4], + themes: [GalaxyTheme; 4], onboarding_state: ModelHandle, ctx: &mut ViewContext, ) -> Self { @@ -222,7 +222,7 @@ impl ThemePickerSlide { fn render_theme_options( &self, appearance: &Appearance, - chrome_theme: &WarpTheme, + chrome_theme: &GalaxyTheme, ) -> Box { let options = (0..self.theme_options.len()) .map(|index| { @@ -316,10 +316,10 @@ impl ThemePickerSlide { fn render_theme_option( &self, appearance: &Appearance, - chrome_theme: &WarpTheme, + chrome_theme: &GalaxyTheme, index: usize, theme_name: String, - option_theme: &WarpTheme, + option_theme: &GalaxyTheme, mouse_state: MouseStateHandle, interactive: bool, ) -> Box { diff --git a/crates/repo_metadata/src/entry.rs b/crates/repo_metadata/src/entry.rs index 9f920a31..a4724142 100644 --- a/crates/repo_metadata/src/entry.rs +++ b/crates/repo_metadata/src/entry.rs @@ -99,7 +99,7 @@ impl Entry { let curr_path: PathBuf = path.into(); let is_dir = curr_path.is_dir(); - // Only ignore symlinks to directories. Symlinks to files are preserved (e.g. WARP.md). + // Only ignore symlinks to directories. Symlinks to files are preserved (e.g. GALAXY.md). if curr_path.is_symlink() && is_dir { return Err(BuildTreeError::Symlink); }