diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index ec151265df..9493e28f54 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -1874,7 +1874,7 @@ impl Session { fn build_workspace_configuration( cwd: &Path, git_info: Option<&codex_protocol::protocol::GitInfo>, - remote_urls: Option<&Vec>, + remote_urls: Option<&BTreeMap>, ) -> Option { let latest_git_commit_hash = git_info.and_then(|info| info.commit_hash.clone()); let associated_remote_urls = remote_urls.cloned(); diff --git a/codex-rs/core/src/environment_context.rs b/codex-rs/core/src/environment_context.rs index 482cec4b97..0a2a3ab02d 100644 --- a/codex-rs/core/src/environment_context.rs +++ b/codex-rs/core/src/environment_context.rs @@ -72,7 +72,7 @@ pub(crate) struct WorkspaceConfiguration { pub(crate) struct WorkspaceEntry { pub hint: String, #[serde(skip_serializing_if = "Option::is_none")] - pub associated_remote_urls: Option>, + pub associated_remote_urls: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub latest_git_commit_hash: Option, } @@ -97,12 +97,31 @@ impl EnvironmentContext { let shell_name = self.shell.name(); lines.push(format!(" {shell_name}")); - if let Some(workspace_configuration) = self.workspace_configuration - && let Ok(json) = serde_json::to_string_pretty(&workspace_configuration) - { + if let Some(workspace_configuration) = self.workspace_configuration { lines.push(" ".to_string()); - for line in json.lines() { - lines.push(format!(" {line}")); + for (path, workspace) in workspace_configuration.workspaces { + lines.push(format!( + " ", + workspace.hint + )); + + if let Some(latest_git_commit_hash) = workspace.latest_git_commit_hash { + lines.push(format!( + " {latest_git_commit_hash}" + )); + } + + if let Some(associated_remote_urls) = workspace.associated_remote_urls + && !associated_remote_urls.is_empty() + { + lines.push(" ".to_string()); + for (name, url) in associated_remote_urls { + lines.push(format!(" {url}")); + } + lines.push(" ".to_string()); + } + + lines.push(" ".to_string()); } lines.push(" ".to_string()); } @@ -257,9 +276,10 @@ mod tests { cwd.to_string_lossy().to_string(), WorkspaceEntry { hint: "repo".to_string(), - associated_remote_urls: Some(vec![ - "origin: https://example.com/repo.git".to_string(), - ]), + associated_remote_urls: Some(BTreeMap::from([( + "origin".to_string(), + "https://example.com/repo.git".to_string(), + )])), latest_git_commit_hash: Some("abc123".to_string()), }, ); @@ -274,17 +294,12 @@ mod tests { /repo bash - { - "workspaces": { - "/repo": { - "hint": "repo", - "associated_remote_urls": [ - "origin: https://example.com/repo.git" - ], - "latest_git_commit_hash": "abc123" - } - } - } + + abc123 + + https://example.com/repo.git + + "#; diff --git a/codex-rs/core/src/git_info.rs b/codex-rs/core/src/git_info.rs index a363bb4e7b..e6e128399b 100644 --- a/codex-rs/core/src/git_info.rs +++ b/codex-rs/core/src/git_info.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeSet; +use std::collections::BTreeMap; use std::collections::HashSet; use std::path::Path; use std::path::PathBuf; @@ -110,8 +110,8 @@ pub async fn collect_git_info(cwd: &Path) -> Option { Some(git_info) } -/// Collect fetch remotes in a multi-root-friendly format: ["origin: https://..."]. -pub async fn get_git_remote_urls(cwd: &Path) -> Option> { +/// Collect fetch remotes in a multi-root-friendly format: {"origin": "https://..."}. +pub async fn get_git_remote_urls(cwd: &Path) -> Option> { let is_git_repo = run_git_command_with_timeout(&["rev-parse", "--git-dir"], cwd) .await? .status @@ -126,21 +126,21 @@ pub async fn get_git_remote_urls(cwd: &Path) -> Option> { } let stdout = String::from_utf8(output.stdout).ok()?; - let mut remotes = BTreeSet::new(); + let mut remotes = BTreeMap::new(); for line in stdout.lines() { if !line.contains("(fetch)") { continue; } let mut parts = line.split_whitespace(); if let (Some(name), Some(url)) = (parts.next(), parts.next()) { - remotes.insert(format!("{name}: {url}")); + remotes.insert(name.to_string(), url.to_string()); } } if remotes.is_empty() { None } else { - Some(remotes.into_iter().collect()) + Some(remotes) } }