tui/exec: show effective workspace roots in summaries

This commit is contained in:
Michael Bolin
2026-05-14 11:39:36 -07:00
parent f42586d9aa
commit 2a7104fdb2
5 changed files with 120 additions and 13 deletions

View File

@@ -423,6 +423,7 @@ fn config_summary_entries(
config: &Config,
session_configured_event: &SessionConfiguredEvent,
) -> Vec<(&'static str, String)> {
let permission_profile = config.permissions.effective_permission_profile();
let mut entries = vec![
("workdir", config.cwd.display().to_string()),
("model", session_configured_event.model.clone()),
@@ -436,10 +437,7 @@ fn config_summary_entries(
),
(
"sandbox",
summarize_permission_profile(
&config.permissions.effective_permission_profile(),
config.cwd.as_path(),
),
summarize_permission_profile(&permission_profile, config.cwd.as_path()),
),
];
if config.model_provider.wire_api == WireApi::Responses {

View File

@@ -2,18 +2,24 @@ use codex_app_server_protocol::ServerNotification;
use codex_app_server_protocol::ThreadItem;
use codex_app_server_protocol::Turn;
use codex_app_server_protocol::TurnStatus;
use codex_core::config::ConfigBuilder;
use codex_protocol::SessionId;
use codex_protocol::ThreadId;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::SessionConfiguredEvent;
use codex_utils_absolute_path::test_support::PathBufExt;
use codex_utils_absolute_path::test_support::test_path_buf;
use owo_colors::Style;
use pretty_assertions::assert_eq;
use super::EventProcessorWithHumanOutput;
use super::config_summary_entries;
use super::final_message_from_turn_items;
use super::paths_match_after_canonicalization;
use super::reasoning_text;
@@ -162,6 +168,70 @@ fn summarizes_managed_read_only_permission_profile() {
);
}
#[tokio::test]
async fn config_summary_entries_include_runtime_workspace_roots() {
let codex_home = tempfile::tempdir().expect("create codex home");
let cwd = tempfile::tempdir().expect("create cwd");
let extra_root = tempfile::tempdir().expect("create extra root");
let mut config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.fallback_cwd(Some(cwd.path().to_path_buf()))
.build()
.await
.expect("build default config");
let cwd = cwd.path().to_path_buf().abs();
let extra_root = extra_root.path().to_path_buf().abs();
let expected_extra_root =
std::fs::canonicalize(extra_root.as_path()).expect("canonicalize extra root");
config.cwd = cwd.clone();
config.workspace_roots = vec![cwd.clone(), extra_root];
config
.permissions
.set_workspace_roots(config.workspace_roots.clone());
config
.permissions
.set_permission_profile(PermissionProfile::workspace_write_with(
&[],
NetworkSandboxPolicy::Restricted,
/*exclude_tmpdir_env_var*/ true,
/*exclude_slash_tmp*/ true,
))
.expect("set permission profile");
let session_configured_event = SessionConfiguredEvent {
session_id: SessionId::new(),
thread_id: ThreadId::new(),
forked_from_id: None,
thread_source: None,
thread_name: None,
model: "gpt-5.4".to_string(),
model_provider_id: config.model_provider_id.clone(),
service_tier: None,
approval_policy: AskForApproval::Never,
approvals_reviewer: config.approvals_reviewer,
permission_profile: config.permissions.effective_permission_profile(),
active_permission_profile: None,
cwd,
reasoning_effort: None,
initial_messages: None,
network_proxy: None,
rollout_path: None,
};
let summary_entries = config_summary_entries(&config, &session_configured_event);
assert!(
summary_entries.iter().any(|(key, value)| {
*key == "sandbox"
&& *value
== format!(
"workspace-write [workdir, {}]",
expected_extra_root.display()
)
}),
"expected runtime workspace root in sandbox summary: {summary_entries:?}"
);
}
#[test]
fn distinct_missing_paths_do_not_match_after_canonicalization() {
assert!(!paths_match_after_canonicalization(