mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
## Summary - Add `iconAssets` and `iconDarkAssets` to the app-list protocol. - Preserve structured icons through directory merging and the connector, app- server, and TUI boundaries. - Keep legacy logo URLs unchanged as compatibility fallbacks. - Update generated protocol schemas and TypeScript types.
123 lines
3.2 KiB
Rust
123 lines
3.2 KiB
Rust
use codex_app_server_protocol::AppBranding as ApiAppBranding;
|
|
use codex_app_server_protocol::AppInfo as ApiAppInfo;
|
|
use codex_app_server_protocol::AppMetadata as ApiAppMetadata;
|
|
use codex_app_server_protocol::AppReview as ApiAppReview;
|
|
use codex_app_server_protocol::AppScreenshot as ApiAppScreenshot;
|
|
use codex_connectors::AppBranding;
|
|
use codex_connectors::AppInfo;
|
|
use codex_connectors::AppMetadata;
|
|
use codex_connectors::AppReview;
|
|
use codex_connectors::AppScreenshot;
|
|
|
|
/// Converts connector-domain app metadata owned by `codex-connectors` into the app-server wire
|
|
/// type owned by `codex-app-server-protocol`.
|
|
///
|
|
/// The types stay separate so app-server protocol ownership does not leak into the connector
|
|
/// domain crate. Because this crate owns neither type, Rust's orphan rules require an explicit
|
|
/// conversion function instead of a `From` implementation.
|
|
pub(crate) fn app_info_to_api(app: AppInfo) -> ApiAppInfo {
|
|
let AppInfo {
|
|
id,
|
|
name,
|
|
description,
|
|
logo_url,
|
|
logo_url_dark,
|
|
icon_assets,
|
|
icon_dark_assets,
|
|
distribution_channel,
|
|
branding,
|
|
app_metadata,
|
|
labels,
|
|
install_url,
|
|
is_accessible,
|
|
is_enabled,
|
|
plugin_display_names,
|
|
} = app;
|
|
ApiAppInfo {
|
|
id,
|
|
name,
|
|
description,
|
|
logo_url,
|
|
logo_url_dark,
|
|
icon_assets,
|
|
icon_dark_assets,
|
|
distribution_channel,
|
|
branding: branding.map(app_branding_to_api),
|
|
app_metadata: app_metadata.map(app_metadata_to_api),
|
|
labels,
|
|
install_url,
|
|
is_accessible,
|
|
is_enabled,
|
|
plugin_display_names,
|
|
}
|
|
}
|
|
|
|
fn app_branding_to_api(branding: AppBranding) -> ApiAppBranding {
|
|
let AppBranding {
|
|
category,
|
|
developer,
|
|
website,
|
|
privacy_policy,
|
|
terms_of_service,
|
|
is_discoverable_app,
|
|
} = branding;
|
|
ApiAppBranding {
|
|
category,
|
|
developer,
|
|
website,
|
|
privacy_policy,
|
|
terms_of_service,
|
|
is_discoverable_app,
|
|
}
|
|
}
|
|
|
|
fn app_review_to_api(review: AppReview) -> ApiAppReview {
|
|
let AppReview { status } = review;
|
|
ApiAppReview { status }
|
|
}
|
|
|
|
fn app_screenshot_to_api(screenshot: AppScreenshot) -> ApiAppScreenshot {
|
|
let AppScreenshot {
|
|
url,
|
|
file_id,
|
|
user_prompt,
|
|
} = screenshot;
|
|
ApiAppScreenshot {
|
|
url,
|
|
file_id,
|
|
user_prompt,
|
|
}
|
|
}
|
|
|
|
fn app_metadata_to_api(metadata: AppMetadata) -> ApiAppMetadata {
|
|
let AppMetadata {
|
|
review,
|
|
categories,
|
|
sub_categories,
|
|
seo_description,
|
|
screenshots,
|
|
developer,
|
|
version,
|
|
version_id,
|
|
version_notes,
|
|
first_party_type,
|
|
first_party_requires_install,
|
|
show_in_composer_when_unlinked,
|
|
} = metadata;
|
|
ApiAppMetadata {
|
|
review: review.map(app_review_to_api),
|
|
categories,
|
|
sub_categories,
|
|
seo_description,
|
|
screenshots: screenshots
|
|
.map(|screenshots| screenshots.into_iter().map(app_screenshot_to_api).collect()),
|
|
developer,
|
|
version,
|
|
version_id,
|
|
version_notes,
|
|
first_party_type,
|
|
first_party_requires_install,
|
|
show_in_composer_when_unlinked,
|
|
}
|
|
}
|