mirror of
https://github.com/openai/codex.git
synced 2026-11-01 00:15:56 +00:00
## Summary Fixes #24411. `/status` currently has no way to show when the TUI is talking to Codex through a remote transport. That makes embedded local sessions, local daemon sessions, and true remote sessions look the same, and it hides the remote server version when debugging connection-specific behavior. This PR adds a single `Remote` row for non-embedded connections only. The row shows the sanitized connection address and a dimmed version parenthetical, preserving the existing status output for embedded local sessions. <img width="791" height="144" alt="image" src="https://github.com/user-attachments/assets/529d7940-1c45-4586-8b06-f20a1f04b771" /> ## Verification - Manually validated when connecting remotely (either implicitly to local daemon or explicitly)
87 lines
2.9 KiB
Rust
87 lines
2.9 KiB
Rust
use crate::AppServerTarget;
|
|
use crate::RemoteAppServerEndpoint;
|
|
use url::Url;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub(crate) struct RemoteConnectionStatus {
|
|
pub(crate) address: String,
|
|
pub(crate) version: String,
|
|
}
|
|
|
|
pub(crate) fn remote_connection_status_value(
|
|
app_server_target: &AppServerTarget,
|
|
server_version: Option<&str>,
|
|
) -> Option<RemoteConnectionStatus> {
|
|
let endpoint = match app_server_target {
|
|
AppServerTarget::Embedded => return None,
|
|
AppServerTarget::LocalDaemon { endpoint } | AppServerTarget::Remote { endpoint } => {
|
|
endpoint
|
|
}
|
|
};
|
|
let address = match endpoint {
|
|
RemoteAppServerEndpoint::WebSocket { websocket_url, .. } => {
|
|
sanitized_websocket_display_address(websocket_url)
|
|
.unwrap_or_else(|| "<invalid websocket URL>".to_string())
|
|
}
|
|
RemoteAppServerEndpoint::UnixSocket { socket_path } => {
|
|
format!("unix://{}", socket_path.display())
|
|
}
|
|
};
|
|
let version = server_version
|
|
.map(|version| format!("v{version}"))
|
|
.unwrap_or_else(|| "unknown".to_string());
|
|
Some(RemoteConnectionStatus { address, version })
|
|
}
|
|
|
|
fn sanitized_websocket_display_address(raw: &str) -> Option<String> {
|
|
let mut url = Url::parse(raw).ok()?;
|
|
let _ = url.set_username("");
|
|
let _ = url.set_password(None);
|
|
url.set_query(None);
|
|
url.set_fragment(None);
|
|
Some(url.to_string())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
|
|
|
#[test]
|
|
fn remote_connection_status_value_formats_display_value() -> color_eyre::Result<()> {
|
|
assert_eq!(
|
|
remote_connection_status_value(&AppServerTarget::Embedded, Some("1.2.3")),
|
|
None
|
|
);
|
|
|
|
let websocket_target = AppServerTarget::Remote {
|
|
endpoint: RemoteAppServerEndpoint::WebSocket {
|
|
websocket_url: "ws://user:secret@127.0.0.1:4500/?token=abc#frag".to_string(),
|
|
auth_token: Some("abc".to_string()),
|
|
},
|
|
};
|
|
assert_eq!(
|
|
remote_connection_status_value(&websocket_target, Some("1.2.3")),
|
|
Some(RemoteConnectionStatus {
|
|
address: "ws://127.0.0.1:4500/".to_string(),
|
|
version: "v1.2.3".to_string(),
|
|
})
|
|
);
|
|
|
|
let socket_path = AbsolutePathBuf::relative_to_current_dir("codex.sock")?;
|
|
let daemon_target = AppServerTarget::LocalDaemon {
|
|
endpoint: RemoteAppServerEndpoint::UnixSocket {
|
|
socket_path: socket_path.clone(),
|
|
},
|
|
};
|
|
assert_eq!(
|
|
remote_connection_status_value(&daemon_target, /*server_version*/ None),
|
|
Some(RemoteConnectionStatus {
|
|
address: format!("unix://{}", socket_path.display()),
|
|
version: "unknown".to_string(),
|
|
})
|
|
);
|
|
Ok(())
|
|
}
|
|
}
|