Skip to content

Commit 1259cbf

Browse files
Show cloud agent env name and setup status for vertical tabs pwd (#11006)
## Summary There was a weird UI pattern where, after kicking off a cloud run, the directory and branch (which falls back to the directory when there's no branch info) in the vertical tabs would be empty. This looked especially bad if the directory was your vertical tabs title, as then the title would just be empty. The fix is to show: * "Environment <dot> setup status text" while the environment is starting up and * "Environment <dot> pwd" when the environment is set up (this isn't solving the first problem, but it's nice to know what env you're in from vertical tabs so @zachbai and I figured it made sense to add) ## Demo https://www.loom.com/share/1104c17370df4e0f9e1f8e7adfe20b93 --- _Conversation: https://staging.warp.dev/conversation/f142b97d-c442-4ec1-ac77-653ace48f2e2_ _This PR was generated with [Oz](https://warp.dev/oz)._ --------- Co-authored-by: Oz <oz-agent@warp.dev>
1 parent 33f3284 commit 1259cbf

4 files changed

Lines changed: 61 additions & 28 deletions

File tree

app/src/ai/blocklist/block/status_bar.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -890,13 +890,7 @@ impl BlocklistAIStatusBar {
890890
.map(|ambient_agent_view_model| ambient_agent_view_model.as_ref(app))?;
891891

892892
let progress = ambient_agent_model.agent_progress()?;
893-
let progress_text = if progress.harness_started_at.is_some() {
894-
"Starting Environment (Step 3/3)"
895-
} else if progress.claimed_at.is_some() {
896-
"Creating Environment (Step 2/3)"
897-
} else {
898-
"Connecting to Host (Step 1/3)"
899-
};
893+
let progress_text = progress.setup_status_text();
900894
Some(render_warping_indicator_base(
901895
WarpingIndicatorProps {
902896
icon: None,

app/src/terminal/view/ambient_agent/model.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ impl AgentProgress {
7070
stopped_at: None,
7171
}
7272
}
73+
74+
pub fn setup_status_text(&self) -> &'static str {
75+
if self.harness_started_at.is_some() {
76+
"Starting Environment (Step 3/3)"
77+
} else if self.claimed_at.is_some() {
78+
"Creating Environment (Step 2/3)"
79+
} else {
80+
"Connecting to Host (Step 1/3)"
81+
}
82+
}
7383
}
7484

7585
/// Identifies what kind of session startup the model is currently waiting on.

app/src/terminal/view/ambient_agent/view_impl.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -849,13 +849,7 @@ impl TerminalView {
849849
)
850850
} else {
851851
// Show loading screen - determine the message based on progress state
852-
let message = if progress.harness_started_at.is_some() {
853-
"Starting Environment (Step 3/3)"
854-
} else if progress.claimed_at.is_some() {
855-
"Creating Environment (Step 2/3)"
856-
} else {
857-
"Connecting to Host (Step 1/3)"
858-
};
852+
let message = progress.setup_status_text();
859853

860854
render_cloud_mode_loading_screen(
861855
message,

app/src/workspace/view/vertical_tabs.rs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ pub mod telemetry;
22

33
use crate::ai::agent::conversation::{ConversationStatus, StatusColorStyle};
44
use crate::ai::agent_management::AgentNotificationsModel;
5+
use crate::ai::cloud_environments::CloudAmbientAgentEnvironment;
56
use crate::ai::conversation_status_ui::render_status_element;
7+
use crate::cloud_object::model::generic_string_model::StringModel;
68
use crate::code::editor::{add_color, remove_color};
79
use crate::code::icon_from_file_path;
810
use crate::safe_triangle::SafeTriangle;
@@ -2732,7 +2734,7 @@ fn build_vertical_tabs_summary_data(
27322734
let terminal_view = terminal_pane.terminal_view(app);
27332735
let terminal_view = terminal_view.as_ref(app);
27342736
let title_text = terminal_view.terminal_title_from_shell();
2735-
let working_directory = terminal_view.display_working_directory(app);
2737+
let working_directory = resolved_terminal_working_directory(terminal_view, app);
27362738
let working_directory_text = working_directory
27372739
.clone()
27382740
.filter(|wd| !wd.trim().is_empty())
@@ -2992,9 +2994,7 @@ fn terminal_pane_search_text_fragments(
29922994
let terminal_view = terminal_pane.terminal_view(app);
29932995
let terminal_view = terminal_view.as_ref(app);
29942996
let title_text = terminal_view.terminal_title_from_shell();
2995-
let working_directory = terminal_view
2996-
.display_working_directory(app)
2997-
.filter(|wd| !wd.trim().is_empty())
2997+
let working_directory = resolved_terminal_working_directory(terminal_view, app)
29982998
.unwrap_or_else(|| title_text.clone());
29992999
let agent_text = terminal_agent_text(terminal_view, app);
30003000
let (conversation_display_title, cli_agent_title) =
@@ -3258,6 +3258,47 @@ impl PaneGroup {
32583258
}
32593259
}
32603260

3261+
/// Returns the best available working-directory string for a terminal pane,
3262+
/// incorporating cloud environment name and setup status for ambient agent sessions.
3263+
fn resolved_terminal_working_directory(
3264+
terminal_view: &TerminalView,
3265+
app: &AppContext,
3266+
) -> Option<String> {
3267+
let working_directory = terminal_view
3268+
.display_working_directory(app)
3269+
.filter(|wd| !wd.trim().is_empty());
3270+
cloud_agent_working_directory_and_env(terminal_view, working_directory.as_deref(), app)
3271+
.or(working_directory)
3272+
}
3273+
3274+
/// For cloud agent panes, builds a composite string from the environment name,
3275+
/// setup status, and/or working directory. Returns `None` for non-cloud sessions.
3276+
fn cloud_agent_working_directory_and_env(
3277+
terminal_view: &TerminalView,
3278+
working_directory: Option<&str>,
3279+
app: &AppContext,
3280+
) -> Option<String> {
3281+
if !terminal_view.is_ambient_agent_session(app) {
3282+
return None;
3283+
}
3284+
let model_ref = terminal_view.ambient_agent_view_model()?.as_ref(app);
3285+
3286+
let env_name = model_ref
3287+
.selected_environment_id()
3288+
.and_then(|id| CloudAmbientAgentEnvironment::get_by_id(id, app))
3289+
.map(|env| env.model().string_model.display_name());
3290+
3291+
let setup_status: Option<&str> = model_ref.agent_progress().map(|p| p.setup_status_text());
3292+
3293+
match (env_name, setup_status, working_directory) {
3294+
(Some(env), Some(status), _) => Some(format!("{env} · {status}")),
3295+
(Some(env), None, Some(wd)) => Some(format!("{env} · {wd}")),
3296+
(Some(env), None, None) => Some(env),
3297+
(None, Some(status), _) => Some(status.to_string()),
3298+
(None, None, _) => None,
3299+
}
3300+
}
3301+
32613302
fn render_terminal_row_content(
32623303
props: &PaneProps<'_>,
32633304
terminal_view: &TerminalView,
@@ -3270,9 +3311,7 @@ fn render_terminal_row_content(
32703311
let primary_info = *TabSettings::as_ref(app).vertical_tabs_primary_info.value();
32713312

32723313
let title_text = terminal_view.terminal_title_from_shell();
3273-
let working_directory = terminal_view
3274-
.display_working_directory(app)
3275-
.filter(|wd| !wd.trim().is_empty())
3314+
let working_directory = resolved_terminal_working_directory(terminal_view, app)
32763315
.unwrap_or_else(|| title_text.clone());
32773316

32783317
let git_branch = terminal_view.current_git_branch(app);
@@ -4071,9 +4110,7 @@ fn render_terminal_primary_line_for_view(
40714110
app: &AppContext,
40724111
) -> Box<dyn Element> {
40734112
let title_text = terminal_view.terminal_title_from_shell();
4074-
let working_directory = terminal_view
4075-
.display_working_directory(app)
4076-
.filter(|wd| !wd.trim().is_empty())
4113+
let working_directory = resolved_terminal_working_directory(terminal_view, app)
40774114
.unwrap_or_else(|| title_text.clone());
40784115
let agent_text = terminal_agent_text(terminal_view, app);
40794116
let (conversation_display_title, cli_agent_title) =
@@ -5596,7 +5633,7 @@ fn render_terminal_detail_section(
55965633
) -> Box<dyn Element> {
55975634
let theme = appearance.theme();
55985635
let text_colors = detail_sidecar_text_colors(theme);
5599-
let working_directory = terminal_view.display_working_directory(app);
5636+
let working_directory = resolved_terminal_working_directory(terminal_view, app);
56005637
let git_branch = terminal_view.current_git_branch(app);
56015638
let cli_agent_session = CLIAgentSessionsModel::as_ref(app).session(terminal_view.id());
56025639
let agent_text = terminal_agent_text(terminal_view, app);
@@ -6060,9 +6097,7 @@ fn render_compact_pane_row(props: PaneProps<'_>, app: &AppContext) -> Box<dyn El
60606097
let terminal_view = terminal_pane.terminal_view(app).as_ref(app);
60616098
let terminal_title = terminal_view.terminal_title_from_shell();
60626099
let git_branch = terminal_view.current_git_branch(app);
6063-
let working_directory = terminal_view
6064-
.display_working_directory(app)
6065-
.filter(|wd| !wd.trim().is_empty());
6100+
let working_directory = resolved_terminal_working_directory(terminal_view, app);
60666101
let working_directory_text = working_directory
60676102
.clone()
60686103
.unwrap_or_else(|| terminal_title.clone());

0 commit comments

Comments
 (0)