first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+1 -1
View File
@@ -4,6 +4,6 @@ mod view;
pub use model::{FinalState, OnboardingQuery};
pub use view::{OnboardingCalloutView, OnboardingCalloutViewEvent, OnboardingKeybindings};
pub fn init(app: &mut galaxyui::AppContext) {
pub fn init(app: &mut galaxyui_core::AppContext) {
view::init(app);
}
+28 -53
View File
@@ -1,7 +1,8 @@
use galaxy_core::send_telemetry_from_ctx;
use galaxyui_core::{Entity, ModelContext};
use crate::telemetry::OnboardingEvent;
use crate::OnboardingIntention;
use galaxy_core::send_telemetry_from_ctx;
use galaxyui::{Entity, ModelContext};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FinalState {
@@ -64,14 +65,10 @@ pub(super) enum UniversalInputCalloutState {
pub(super) enum AgentModalityCalloutState {
#[default]
Off,
/// Step 1: "Meet your terminal input" / "Meet your updated terminal input"
MeetTerminalInput,
/// Step 2: "Natural language support" with checkbox
NaturalLanguageSupport,
/// Step 3: "Introducing Warp's new agent experience" (Agent intention only)
IntroducingAgentExperience,
/// Step 4: "Updated agent input" (Agent intention only)
UpdatedAgentInput,
/// Step 1: terminal input with natural language support.
TerminalMode,
/// Step 2: "Agent Mode" (Agent intention only).
AgentMode,
/// Terminal state
Complete(FinalState),
}
@@ -187,13 +184,9 @@ impl OnboardingCalloutModel {
) {
let (next_state, emit_enter_agent_modality) = match state {
AgentModalityCalloutState::Off => {
(Some(AgentModalityCalloutState::MeetTerminalInput), false)
(Some(AgentModalityCalloutState::TerminalMode), false)
}
AgentModalityCalloutState::MeetTerminalInput => (
Some(AgentModalityCalloutState::NaturalLanguageSupport),
false,
),
AgentModalityCalloutState::NaturalLanguageSupport => {
AgentModalityCalloutState::TerminalMode => {
// For Terminal intention, finish here
// For Agent intention, continue to IntroducingAgentExperience
match self.intention {
@@ -203,17 +196,11 @@ impl OnboardingCalloutModel {
),
OnboardingIntention::AgentDrivenDevelopment => {
// Signal to enter agent modality when showing the agent experience slide
(
Some(AgentModalityCalloutState::IntroducingAgentExperience),
true,
)
(Some(AgentModalityCalloutState::AgentMode), true)
}
}
}
AgentModalityCalloutState::IntroducingAgentExperience => {
(Some(AgentModalityCalloutState::UpdatedAgentInput), false)
}
AgentModalityCalloutState::UpdatedAgentInput => {
AgentModalityCalloutState::AgentMode => {
// For Agent with project: Initialize
// For Agent without project: Finish
let final_state = if self.has_project {
@@ -246,7 +233,9 @@ impl OnboardingCalloutModel {
ctx,
);
}
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode)
if self.has_project =>
{
// Skip initialization
self.set_state(
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
@@ -272,9 +261,7 @@ impl OnboardingCalloutModel {
ctx,
);
}
OnboardingCalloutState::AgentModality(
AgentModalityCalloutState::NaturalLanguageSupport,
) => {
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::TerminalMode) => {
// Terminal intention finishes here
self.set_state(
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
@@ -283,7 +270,9 @@ impl OnboardingCalloutModel {
ctx,
);
}
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode)
if !self.has_project =>
{
// Agent without project finishes here
self.set_state(
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
@@ -296,10 +285,10 @@ impl OnboardingCalloutModel {
}
}
/// Handle "Back to terminal" action (ESC in UpdatedAgentInput without project)
/// Handle "Back to terminal" action (ESC in IntroducingAgentExperience).
pub fn back_to_terminal(&mut self, ctx: &mut ModelContext<Self>) {
match &self.state {
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode) => {
self.set_state(
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
FinalState::BackToTerminal,
@@ -342,17 +331,11 @@ impl OnboardingCalloutModel {
OnboardingCalloutState::UniversalInput(UniversalInputCalloutState::TalkToAgent) => {
Some("talk_to_agent")
}
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::MeetTerminalInput) => {
Some("meet_terminal_input")
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::TerminalMode) => {
Some("natural_language_support")
}
OnboardingCalloutState::AgentModality(
AgentModalityCalloutState::NaturalLanguageSupport,
) => Some("natural_language_support"),
OnboardingCalloutState::AgentModality(
AgentModalityCalloutState::IntroducingAgentExperience,
) => Some("introducing_agent_experience"),
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
Some("updated_agent_input")
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode) => {
Some("introducing_agent_experience")
}
_ => None,
};
@@ -435,16 +418,10 @@ impl OnboardingCalloutModel {
fn prompt_for_agent_modality(&self, state: AgentModalityCalloutState) -> OnboardingQuery {
match state {
AgentModalityCalloutState::Off => OnboardingQuery::None,
AgentModalityCalloutState::MeetTerminalInput => {
AgentModalityCalloutState::TerminalMode => {
OnboardingQuery::TerminalCommand("Run a command...".to_string())
}
AgentModalityCalloutState::NaturalLanguageSupport => {
OnboardingQuery::AgentPrompt("help me terraform my Gcloud setup".to_string())
}
AgentModalityCalloutState::IntroducingAgentExperience => {
OnboardingQuery::AgentPrompt("Tell the agent what to build...".to_string())
}
AgentModalityCalloutState::UpdatedAgentInput => {
AgentModalityCalloutState::AgentMode => {
if self.has_project {
OnboardingQuery::AgentPrompt("/init".to_string())
} else {
@@ -470,11 +447,9 @@ impl OnboardingCalloutModel {
);
}
OnboardingCalloutState::AgentModality(_) => {
log::info!("Transitioning to AgentModality::MeetTerminalInput");
log::info!("Transitioning to AgentModality::NaturalLanguageSupport");
self.set_state(
OnboardingCalloutState::AgentModality(
AgentModalityCalloutState::MeetTerminalInput,
),
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::TerminalMode),
ctx,
);
}
+33 -64
View File
@@ -1,11 +1,12 @@
use ui_components::Component;
use galaxy_core::ui::appearance::Appearance;
use galaxyui::{
elements::Empty,
keymap::{macros::*, FixedBinding, Keystroke},
use galaxyui_core::elements::Empty;
use galaxyui_core::keymap::macros::*;
use galaxyui_core::keymap::{FixedBinding, Keystroke};
use galaxyui_core::{
AppContext, Element, Entity, EventContext, ModelHandle, SingletonEntity, TypedActionView, View,
ViewContext,
};
use ui_components::Component;
/// Display strings for keybindings shown in the onboarding callout.
#[derive(Clone, Debug)]
@@ -16,16 +17,16 @@ pub struct OnboardingKeybindings {
pub submit_to_local_agent: String,
/// Display string for submitting to cloud agent (e.g., "⌘⌥⏎")
pub submit_to_cloud_agent: String,
/// Display string for returning to terminal mode (e.g., "Esc")
pub return_to_terminal_mode: String,
}
use crate::{
callout::model::{
AgentModalityCalloutState, FinalState, OnboardingCalloutModel, OnboardingCalloutModelEvent,
OnboardingCalloutState, OnboardingQuery, UniversalInputCalloutState,
},
components::onboarding_callout::{self, Button, StepStatus},
OnboardingIntention,
use crate::callout::model::{
AgentModalityCalloutState, FinalState, OnboardingCalloutModel, OnboardingCalloutModelEvent,
OnboardingCalloutState, OnboardingQuery, UniversalInputCalloutState,
};
use crate::components::onboarding_callout::{self, Button, StepStatus};
use crate::OnboardingIntention;
/// Options for rendering a callout.
struct CalloutOptions {
@@ -105,46 +106,23 @@ fn get_agent_modality_callout_options(
keybindings: &OnboardingKeybindings,
) -> Option<CalloutOptions> {
let total_steps = match intention {
OnboardingIntention::Terminal => 2,
OnboardingIntention::AgentDrivenDevelopment => 4,
OnboardingIntention::Terminal => 1,
OnboardingIntention::AgentDrivenDevelopment => 2,
};
match state {
AgentModalityCalloutState::MeetTerminalInput => {
let title: &'static str = if has_project || intention == OnboardingIntention::Terminal {
"Meet your terminal input"
} else {
"Meet your updated terminal input"
};
Some(CalloutOptions {
title,
text: format!(
"Run commands from the terminal, or use {} or {} to start or send to a local or cloud agent respectively.",
keybindings.submit_to_local_agent,
keybindings.submit_to_cloud_agent
),
step: StepStatus::new(0, total_steps),
left_button: None,
right_button: ButtonOptions {
text: "Next",
action: OnboardingCalloutViewAction::NextClicked,
keystroke: Some(Keystroke::parse("enter").unwrap_or_default()),
},
checkbox: None,
})
}
AgentModalityCalloutState::NaturalLanguageSupport => {
AgentModalityCalloutState::TerminalMode => {
let is_final_step = intention == OnboardingIntention::Terminal;
// Show different callout content based on initial NL detection state
if initial_natural_language_detection_enabled {
// NL detection was already enabled - show simpler "overrides" callout without checkbox
Some(CalloutOptions {
title: "Natural language overrides",
title: "Welcome to terminal mode",
text: format!(
"You can always override any auto-detection using {}.",
"Run commands here, just like a regular terminal. If you type a question or task using natural language, Warp can suggest opening it in agent mode. You can always override using {}.",
keybindings.toggle_input_mode
),
step: StepStatus::new(1, total_steps),
step: StepStatus::new(0, total_steps),
left_button: None,
right_button: ButtonOptions {
text: if is_final_step { "Finish" } else { "Next" },
@@ -156,12 +134,12 @@ fn get_agent_modality_callout_options(
} else {
// NL detection was disabled - show full explanation with checkbox to enable
Some(CalloutOptions {
title: "Natural language support",
title: "Youre in terminal mode",
text: format!(
"Natural language input is off by default. If enabled, you can type requests in plain English and Warp will autodetect queries for the agent. You can always override them using {}.",
"Run commands here, just like a regular terminal. If you type a question or task using natural language, Warp can suggest opening it in agent mode. You can always override using {}.",
keybindings.toggle_input_mode
),
step: StepStatus::new(1, total_steps),
step: StepStatus::new(0, total_steps),
left_button: None,
right_button: ButtonOptions {
text: if is_final_step { "Finish" } else { "Next" },
@@ -175,24 +153,12 @@ fn get_agent_modality_callout_options(
})
}
}
AgentModalityCalloutState::IntroducingAgentExperience => Some(CalloutOptions {
title: "Introducing Warp's new agent experience",
text: "Agent conversations are now their own scoped view outside of your terminal. Simply hit ESC to return to the terminal at any point.".to_string(),
step: StepStatus::new(2, total_steps),
left_button: None,
right_button: ButtonOptions {
text: "Next",
action: OnboardingCalloutViewAction::NextClicked,
keystroke: Some(Keystroke::parse("enter").unwrap_or_default()),
},
checkbox: None,
}),
AgentModalityCalloutState::UpdatedAgentInput => {
AgentModalityCalloutState::AgentMode => {
if has_project {
Some(CalloutOptions {
title: "Updated agent input",
text: "Your agent input will detect natural language as well as commands by default. Use ! to lock the input in bash mode to write commands.\n\nSubmit the query below to have the agent initialize this project, or ⊗ to clear the input and start your own!".to_string(),
step: StepStatus::new(3, total_steps),
title: "You're in agent mode",
text: "Agent mode gives your questions and tasks their own conversation, so you can ask follow-ups without leaving your terminal workflow.\n\nSubmit the query below to have the agent initialize this project, or ⊗ to clear the input and start your own!".to_string(),
step: StepStatus::new(1, total_steps),
left_button: Some(ButtonOptions {
text: "Skip initialization",
action: OnboardingCalloutViewAction::SkipClicked,
@@ -207,9 +173,12 @@ fn get_agent_modality_callout_options(
})
} else {
Some(CalloutOptions {
title: "Updated agent input",
text: "Your agent input will detect natural language as well as commands by default. Use ! to lock the input in bash mode to write commands.".to_string(),
step: StepStatus::new(3, total_steps),
title: "You're in agent mode",
text: format!(
"Agent mode gives your questions and tasks their own conversation, so you can ask follow-ups without leaving your terminal workflow. Press {} to return to terminal mode at any point.",
keybindings.return_to_terminal_mode
),
step: StepStatus::new(1, total_steps),
left_button: Some(ButtonOptions {
text: "Back to terminal",
action: OnboardingCalloutViewAction::BackToTerminalClicked,
@@ -378,11 +347,11 @@ impl OnboardingCalloutView {
}
/// Returns true if the callout should be positioned above the zero state.
/// For UpdatedAgentInput state, always position relative to the input box instead.
/// For the agent experience state, always position relative to the input box instead.
pub fn should_position_above_zero_state(&self, app: &AppContext) -> bool {
!matches!(
self.model.as_ref(app).state(),
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput)
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode)
)
}