rename Desktop distribution crate to installation

This commit is contained in:
Abhinav Vedmala
2026-06-15 05:30:26 +00:00
parent 27541e9ef8
commit 9b2efe0c3a
14 changed files with 73 additions and 72 deletions
+2 -2
View File
@@ -2291,7 +2291,7 @@ dependencies = [
"codex-config",
"codex-core",
"codex-core-plugins",
"codex-desktop-distribution",
"codex-desktop-installation",
"codex-exec",
"codex-exec-server",
"codex-execpolicy",
@@ -2784,7 +2784,7 @@ dependencies = [
]
[[package]]
name = "codex-desktop-distribution"
name = "codex-desktop-installation"
version = "0.0.0"
dependencies = [
"codex-utils-absolute-path",
+2 -2
View File
@@ -33,7 +33,7 @@ members = [
"connectors",
"config",
"context-fragments",
"desktop-distribution",
"desktop-installation",
"shell-command",
"shell-escalation",
"skills",
@@ -166,7 +166,7 @@ codex-home = { path = "codex-home" }
codex-config = { path = "config" }
codex-connectors = { path = "connectors" }
codex-context-fragments = { path = "context-fragments" }
codex-desktop-distribution = { path = "desktop-distribution" }
codex-desktop-installation = { path = "desktop-installation" }
codex-core = { path = "core" }
codex-core-api = { path = "core-api" }
codex-core-plugins = { path = "core-plugins" }
+1 -1
View File
@@ -31,7 +31,7 @@ codex-chatgpt = { workspace = true }
codex-cloud-tasks = { path = "../cloud-tasks" }
codex-utils-cli = { workspace = true }
codex-config = { workspace = true }
codex-desktop-distribution = { workspace = true }
codex-desktop-installation = { workspace = true }
codex-core = { workspace = true }
codex-core-plugins = { workspace = true }
codex-home = { workspace = true }
+8 -8
View File
@@ -1,6 +1,6 @@
use anyhow::Context as _;
use codex_desktop_distribution::discover_installed_distribution;
use codex_desktop_distribution::validate_installed_distribution_at;
use codex_desktop_installation::discover_desktop_installation;
use codex_desktop_installation::validate_desktop_installation_at;
use std::ffi::CString;
use std::path::Path;
use std::path::PathBuf;
@@ -66,10 +66,10 @@ fn is_apple_silicon_mac() -> bool {
}
async fn find_existing_codex_app_path() -> anyhow::Result<Option<PathBuf>> {
let distribution = tokio::task::spawn_blocking(discover_installed_distribution)
let installation = tokio::task::spawn_blocking(discover_desktop_installation)
.await
.context("Desktop discovery task failed")??;
Ok(distribution.map(|distribution| distribution.app_root().to_path_buf()))
Ok(installation.map(|installation| installation.app_root().to_path_buf()))
}
async fn open_codex_app(app_path: &Path, workspace: &Path) -> anyhow::Result<()> {
@@ -174,15 +174,15 @@ async fn install_codex_app_bundle(app_in_volume: &Path) -> anyhow::Result<PathBu
async fn validate_installed_codex_app(app_path: PathBuf) -> anyhow::Result<PathBuf> {
let candidate = app_path.clone();
let distribution =
tokio::task::spawn_blocking(move || validate_installed_distribution_at(candidate))
let installation =
tokio::task::spawn_blocking(move || validate_desktop_installation_at(candidate))
.await
.context("Desktop validation task failed")??;
let app_path_display = app_path.display();
let distribution = distribution.with_context(|| {
let installation = installation.with_context(|| {
format!("refusing to launch unverified Codex Desktop at {app_path_display}")
})?;
Ok(distribution.app_root().to_path_buf())
Ok(installation.app_root().to_path_buf())
}
fn candidate_applications_dirs() -> anyhow::Result<Vec<PathBuf>> {
+2 -2
View File
@@ -1,5 +1,5 @@
use anyhow::Context as _;
use codex_desktop_distribution::discover_installed_distribution;
use codex_desktop_installation::discover_desktop_installation;
use std::path::Path;
use std::path::PathBuf;
use tokio::process::Command;
@@ -32,7 +32,7 @@ pub async fn run_windows_app_open_or_install(
}
async fn codex_app_is_installed() -> anyhow::Result<bool> {
Ok(tokio::task::spawn_blocking(discover_installed_distribution)
Ok(tokio::task::spawn_blocking(discover_desktop_installation)
.await
.context("Desktop discovery task failed")??
.is_some())
@@ -1,6 +0,0 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "desktop-distribution",
crate_name = "codex_desktop_distribution",
)
@@ -1,6 +0,0 @@
use crate::DesktopDistributionError;
use crate::InstalledDesktop;
pub(crate) fn discover() -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
Ok(None)
}
@@ -0,0 +1,6 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "desktop-installation",
crate_name = "codex_desktop_installation",
)
@@ -1,11 +1,11 @@
[package]
name = "codex-desktop-distribution"
name = "codex-desktop-installation"
version.workspace = true
edition.workspace = true
license.workspace = true
[lib]
name = "codex_desktop_distribution"
name = "codex_desktop_installation"
path = "src/lib.rs"
doctest = false
@@ -22,10 +22,10 @@ mod platform;
const DESKTOP_RESOURCES_PATH_ENV_VAR: &str = "CODEX_DESKTOP_RESOURCES_PATH";
#[derive(Debug, thiserror::Error)]
pub enum DesktopDistributionError {
pub enum DesktopInstallationError {
/// No launcher hint was provided and no installed Codex Desktop app was found. This can
/// happen, for example, when Desktop was uninstalled after installing a bundled plugin.
#[error("no installed Codex Desktop distribution was found")]
#[error("no Codex Desktop installation was found")]
NotFound,
/// The platform app-discovery mechanism could not be queried successfully.
#[error("Codex Desktop discovery failed: {0}")]
@@ -52,19 +52,19 @@ impl DesktopResources {
pub fn contained_file(
&self,
relative_path: impl AsRef<Path>,
) -> Result<AbsolutePathBuf, DesktopDistributionError> {
) -> Result<AbsolutePathBuf, DesktopInstallationError> {
contained_path(&self.root, relative_path.as_ref(), ResourceKind::File)
}
pub fn contained_directory(
&self,
relative_path: impl AsRef<Path>,
) -> Result<AbsolutePathBuf, DesktopDistributionError> {
) -> Result<AbsolutePathBuf, DesktopInstallationError> {
contained_path(&self.root, relative_path.as_ref(), ResourceKind::Directory)
}
/// Uses a resources directory supplied by the trusted Desktop launcher.
pub fn from_trusted_path(root: PathBuf) -> Result<Self, DesktopDistributionError> {
pub fn from_trusted_path(root: PathBuf) -> Result<Self, DesktopInstallationError> {
let root = canonical(&root, "resources root")?;
if !root.as_path().is_dir() {
return Err(containment("expected the resources root to be a directory"));
@@ -74,12 +74,12 @@ impl DesktopResources {
}
#[derive(Debug)]
pub struct InstalledDesktop {
pub struct VerifiedDesktopInstallation {
app_root: AbsolutePathBuf,
resources: DesktopResources,
}
impl InstalledDesktop {
impl VerifiedDesktopInstallation {
pub fn app_root(&self) -> &Path {
self.app_root.as_path()
}
@@ -88,7 +88,7 @@ impl InstalledDesktop {
fn from_paths(
app_root: PathBuf,
resources_root: PathBuf,
) -> Result<Self, DesktopDistributionError> {
) -> Result<Self, DesktopInstallationError> {
let app_root = canonical(&app_root, "application root")?;
let resources = DesktopResources::from_trusted_path(resources_root)?;
if resources.root == app_root || !resources.root.as_path().starts_with(app_root.as_path()) {
@@ -104,29 +104,29 @@ impl InstalledDesktop {
}
/// Uses resources supplied by Desktop, otherwise discovers the installed stable app.
pub fn locate_current_or_installed_resources() -> Result<DesktopResources, DesktopDistributionError>
pub fn locate_current_or_installed_resources() -> Result<DesktopResources, DesktopInstallationError>
{
if let Some(resources_root) = std::env::var_os(DESKTOP_RESOURCES_PATH_ENV_VAR) {
return DesktopResources::from_trusted_path(PathBuf::from(resources_root));
}
discover_installed_distribution()?
.map(|distribution| distribution.resources)
.ok_or(DesktopDistributionError::NotFound)
discover_desktop_installation()?
.map(|installation| installation.resources)
.ok_or(DesktopInstallationError::NotFound)
}
/// Discovers an installed Desktop app without consulting the launcher resources hint.
pub fn discover_installed_distribution()
-> Result<Option<InstalledDesktop>, DesktopDistributionError> {
pub fn discover_desktop_installation()
-> Result<Option<VerifiedDesktopInstallation>, DesktopInstallationError> {
platform::discover()
}
/// Validates a macOS Codex app bundle at a known path using the same identity and containment
/// checks as installed-app discovery. Returns `Ok(None)` when the path is not a trusted Codex
/// Desktop distribution.
/// Desktop installation.
#[cfg(target_os = "macos")]
pub fn validate_installed_distribution_at(
pub fn validate_desktop_installation_at(
app_root: impl AsRef<Path>,
) -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
) -> Result<Option<VerifiedDesktopInstallation>, DesktopInstallationError> {
platform::validate_candidate(app_root.as_ref())
}
@@ -145,7 +145,7 @@ fn contained_path(
root: &AbsolutePathBuf,
relative_path: &Path,
kind: ResourceKind,
) -> Result<AbsolutePathBuf, DesktopDistributionError> {
) -> Result<AbsolutePathBuf, DesktopInstallationError> {
if relative_path.as_os_str().is_empty()
|| relative_path
.components()
@@ -162,7 +162,7 @@ fn contained_path(
));
}
let metadata =
fs::metadata(path.as_path()).map_err(|source| DesktopDistributionError::Filesystem {
fs::metadata(path.as_path()).map_err(|source| DesktopInstallationError::Filesystem {
stage: "resource metadata",
source,
})?;
@@ -182,14 +182,14 @@ fn contained_path(
fn canonical(
path: &Path,
stage: &'static str,
) -> Result<AbsolutePathBuf, DesktopDistributionError> {
) -> Result<AbsolutePathBuf, DesktopInstallationError> {
AbsolutePathBuf::from_absolute_path_checked(path)
.and_then(|path| path.canonicalize())
.map_err(|source| DesktopDistributionError::Filesystem { stage, source })
.map_err(|source| DesktopInstallationError::Filesystem { stage, source })
}
fn containment(message: impl Into<String>) -> DesktopDistributionError {
DesktopDistributionError::Containment(message.into())
fn containment(message: impl Into<String>) -> DesktopInstallationError {
DesktopInstallationError::Containment(message.into())
}
#[cfg(test)]
@@ -1,10 +1,10 @@
use pretty_assertions::assert_eq;
use std::fs;
use super::DesktopDistributionError;
use super::DesktopInstallationError;
use super::DesktopResources;
#[cfg(unix)]
use super::InstalledDesktop;
use super::VerifiedDesktopInstallation;
use super::canonical;
#[test]
@@ -41,12 +41,12 @@ fn rejects_non_normal_and_wrong_kind_paths() {
for path in ["", ".", "../resources/plugins", "/tmp"] {
assert!(matches!(
resources.contained_directory(path),
Err(DesktopDistributionError::Containment(_))
Err(DesktopInstallationError::Containment(_))
));
}
assert!(matches!(
resources.contained_file("plugins"),
Err(DesktopDistributionError::Containment(_))
Err(DesktopInstallationError::Containment(_))
));
}
@@ -66,7 +66,7 @@ fn rejects_symlink_traversal() {
assert!(matches!(
resources.contained_file("plugins/hook.json"),
Err(DesktopDistributionError::Containment(_))
Err(DesktopInstallationError::Containment(_))
));
let app_root = temp.path().join("Codex.app");
@@ -75,7 +75,7 @@ fn rejects_symlink_traversal() {
.expect("create app contents");
symlink(&outside, &resources_link).expect("create resources symlink");
assert!(matches!(
InstalledDesktop::from_paths(app_root, resources_link),
Err(DesktopDistributionError::Containment(_))
VerifiedDesktopInstallation::from_paths(app_root, resources_link),
Err(DesktopInstallationError::Containment(_))
));
}
@@ -2,19 +2,19 @@ use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use crate::DesktopDistributionError;
use crate::InstalledDesktop;
use crate::DesktopInstallationError;
use crate::VerifiedDesktopInstallation;
const BUNDLE_IDENTIFIER: &str = "com.openai.codex";
const TEAM_IDENTIFIER: &str = "2DC432GLL2";
/// Asks LaunchServices for the signed stable Codex app, independent of name or location.
pub(crate) fn discover() -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
pub(crate) fn discover() -> Result<Option<VerifiedDesktopInstallation>, DesktopInstallationError> {
let script = format!(r#"POSIX path of (path to application id "{BUNDLE_IDENTIFIER}")"#);
let output = Command::new("/usr/bin/osascript")
.args(["-e", &script])
.output()
.map_err(|error| DesktopDistributionError::Discovery(error.to_string()))?;
.map_err(|error| DesktopInstallationError::Discovery(error.to_string()))?;
if !output.status.success() {
return Ok(None);
}
@@ -24,18 +24,19 @@ pub(crate) fn discover() -> Result<Option<InstalledDesktop>, DesktopDistribution
pub(crate) fn validate_candidate(
app_root: &Path,
) -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
) -> Result<Option<VerifiedDesktopInstallation>, DesktopInstallationError> {
let resources_root = app_root.join("Contents/Resources");
if app_root.extension().is_some_and(|value| value == "app")
&& resources_root.is_dir()
&& has_openai_signature(app_root)?
{
return InstalledDesktop::from_paths(app_root.to_path_buf(), resources_root).map(Some);
return VerifiedDesktopInstallation::from_paths(app_root.to_path_buf(), resources_root)
.map(Some);
}
Ok(None)
}
fn has_openai_signature(app_root: &std::path::Path) -> Result<bool, DesktopDistributionError> {
fn has_openai_signature(app_root: &std::path::Path) -> Result<bool, DesktopInstallationError> {
let requirement = format!(
r#"=identifier "{BUNDLE_IDENTIFIER}" and anchor apple generic and certificate leaf[subject.OU] = "{TEAM_IDENTIFIER}""#
);
@@ -43,6 +44,6 @@ fn has_openai_signature(app_root: &std::path::Path) -> Result<bool, DesktopDistr
.args(["--verify", "--strict", "-R", &requirement])
.arg(app_root)
.status()
.map_err(|error| DesktopDistributionError::Discovery(error.to_string()))?;
.map_err(|error| DesktopInstallationError::Discovery(error.to_string()))?;
Ok(verification.success())
}
@@ -0,0 +1,6 @@
use crate::DesktopInstallationError;
use crate::VerifiedDesktopInstallation;
pub(crate) fn discover() -> Result<Option<VerifiedDesktopInstallation>, DesktopInstallationError> {
Ok(None)
}
@@ -1,13 +1,13 @@
use std::path::PathBuf;
use std::process::Command;
use crate::DesktopDistributionError;
use crate::InstalledDesktop;
use crate::DesktopInstallationError;
use crate::VerifiedDesktopInstallation;
const STORE_PUBLISHER_ID: &str = "2p2nqsd0c76g0";
/// Queries the signed stable MSIX identity and uses the package location as the app root.
pub(crate) fn discover() -> Result<Option<InstalledDesktop>, DesktopDistributionError> {
pub(crate) fn discover() -> Result<Option<VerifiedDesktopInstallation>, DesktopInstallationError> {
let script = format!(
r#"
$location = Get-AppxPackage -Name 'OpenAI.Codex' -ErrorAction SilentlyContinue |
@@ -22,7 +22,7 @@ if ($location) {{ $location }}
.arg("-Command")
.arg(script)
.output()
.map_err(|error| DesktopDistributionError::Discovery(error.to_string()))?;
.map_err(|error| DesktopInstallationError::Discovery(error.to_string()))?;
if !output.status.success() {
return Ok(None);
}
@@ -32,5 +32,5 @@ if ($location) {{ $location }}
}
let app_root = PathBuf::from(install_location);
let resources_root = app_root.join("app/resources");
InstalledDesktop::from_paths(app_root, resources_root).map(Some)
VerifiedDesktopInstallation::from_paths(app_root, resources_root).map(Some)
}