feat(tui): polish cwd workspace summary

This commit is contained in:
Felipe Coury
2026-06-12 00:33:59 -07:00
parent f7eb951ee2
commit 43734ec5c9
+59 -23
View File
@@ -7,28 +7,51 @@ use super::resize_reflow::trailing_run_start;
use super::*;
use crate::config_update::format_config_error;
use crate::external_agent_config_migration_flow::ExternalAgentConfigMigrationFlowOutcome;
use crate::render::highlight::foreground_style_for_scopes;
use crate::style::accent_style;
use crate::style::table_separator_style;
use codex_app_server_protocol::ThreadWorkspaceReadResponse;
use codex_app_server_protocol::WorkspaceMutationOperation;
#[cfg(target_os = "windows")]
use codex_config::types::WindowsSandboxModeToml;
use ratatui::style::Styled;
use ratatui::text::Line;
const SHUTDOWN_FIRST_EXIT_TIMEOUT: Duration = Duration::from_secs(/*secs*/ 2);
fn format_thread_workspace(response: &ThreadWorkspaceReadResponse) -> String {
let workspace_roots = if response.runtime_workspace_roots.is_empty() {
" (none)".to_string()
} else {
response
.runtime_workspace_roots
.iter()
.map(|root| format!(" {}", root.as_path().display()))
.collect::<Vec<_>>()
.join("\n")
};
format!(
"Working directory:\n {}\n\nWorkspace roots:\n{workspace_roots}",
response.cwd.as_path().display()
)
fn thread_workspace_lines(response: &ThreadWorkspaceReadResponse) -> Vec<Line<'static>> {
let accent_style = accent_style();
let label_style =
foreground_style_for_scopes(&["entity.name.type", "support.type", "variable"])
.unwrap_or(accent_style);
let separator_style = table_separator_style();
let mut lines = vec![
vec![
"• ".set_style(separator_style),
"Workspace".set_style(accent_style),
]
.into(),
vec![
" cwd ".set_style(label_style),
response.cwd.as_path().display().to_string().into(),
]
.into(),
];
let mut roots = response.runtime_workspace_roots.iter();
let first_root = roots
.next()
.map(|root| root.as_path().display().to_string())
.unwrap_or_else(|| "(none)".to_string());
lines.push(vec![" roots ".set_style(label_style), first_root.into()].into());
lines.extend(roots.map(|root| {
vec![
" ".set_style(separator_style),
root.as_path().display().to_string().into(),
]
.into()
}));
lines
}
impl App {
@@ -429,7 +452,7 @@ impl App {
match app_server.thread_workspace_read(thread_id).await {
Ok(response) => self
.chat_widget
.add_info_message(format_thread_workspace(&response), /*hint*/ None),
.add_plain_history_lines(thread_workspace_lines(&response)),
Err(err) => self
.chat_widget
.add_error_message(format!("Failed to read workspace: {err}")),
@@ -2381,9 +2404,10 @@ mod tests {
use super::*;
use codex_utils_absolute_path::test_support::PathBufExt;
use codex_utils_absolute_path::test_support::test_path_buf;
use pretty_assertions::assert_eq;
#[test]
fn format_thread_workspace_lists_cwd_and_roots_snapshot() {
fn thread_workspace_lines_list_cwd_and_roots_snapshot() {
let response = ThreadWorkspaceReadResponse {
cwd: test_path_buf("/tmp/current").abs(),
runtime_workspace_roots: vec![
@@ -2392,13 +2416,25 @@ mod tests {
],
};
insta::assert_snapshot!(format_thread_workspace(&response), @r"
Working directory:
/tmp/current
let lines = thread_workspace_lines(&response);
assert_eq!(lines[0].spans[1].style, accent_style());
assert_eq!(
lines[1].spans[0].style,
foreground_style_for_scopes(&["entity.name.type", "support.type", "variable"])
.unwrap_or_else(accent_style)
);
assert_eq!(lines[0].spans[0].style, table_separator_style());
Workspace roots:
/tmp/current
/tmp/shared
let text = lines
.into_iter()
.map(|line| line.to_string())
.collect::<Vec<_>>()
.join("\n");
insta::assert_snapshot!(text, @r"
• Workspace
cwd /tmp/current
roots /tmp/current
/tmp/shared
");
}
}