Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9372,6 +9372,12 @@
},
"PluginMarketplaceEntry": {
"properties": {
"displayName": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6160,6 +6160,12 @@
},
"PluginMarketplaceEntry": {
"properties": {
"displayName": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@
},
"PluginMarketplaceEntry": {
"properties": {
"displayName": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
import type { PluginSummary } from "./PluginSummary";

export type PluginMarketplaceEntry = { name: string, path: AbsolutePathBuf, plugins: Array<PluginSummary>, };
export type PluginMarketplaceEntry = { name: string, path: AbsolutePathBuf, displayName: string | null, plugins: Array<PluginSummary>, };
1 change: 1 addition & 0 deletions codex-rs/app-server-protocol/src/protocol/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3276,6 +3276,7 @@ pub struct SkillsListEntry {
pub struct PluginMarketplaceEntry {
pub name: String,
pub path: AbsolutePathBuf,
pub display_name: Option<String>,
pub plugins: Vec<PluginSummary>,
}

Expand Down
1 change: 1 addition & 0 deletions codex-rs/app-server/src/codex_message_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5439,6 +5439,7 @@ impl CodexMessageProcessor {
.map(|marketplace| PluginMarketplaceEntry {
name: marketplace.name,
path: marketplace.path,
display_name: marketplace.display_name,
plugins: marketplace
.plugins
.into_iter()
Expand Down
5 changes: 5 additions & 0 deletions codex-rs/app-server/tests/suite/v2/plugin_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ async fn plugin_list_includes_install_and_enabled_state_from_config() -> Result<
repo_root.path().join(".agents/plugins/marketplace.json"),
r#"{
"name": "codex-curated",
"display_name": "ChatGPT Official",
"plugins": [
{
"name": "enabled-plugin",
Expand Down Expand Up @@ -220,6 +221,10 @@ enabled = false
.expect("expected repo marketplace entry");

assert_eq!(marketplace.name, "codex-curated");
assert_eq!(
marketplace.display_name.as_deref(),
Some("ChatGPT Official")
);
assert_eq!(marketplace.plugins.len(), 3);
assert_eq!(marketplace.plugins[0].id, "enabled-plugin@codex-curated");
assert_eq!(marketplace.plugins[0].name, "enabled-plugin");
Expand Down
2 changes: 2 additions & 0 deletions codex-rs/core/src/plugins/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ pub struct PluginDetailSummary {
pub struct ConfiguredMarketplaceSummary {
pub name: String,
pub path: AbsolutePathBuf,
pub display_name: Option<String>,
pub plugins: Vec<ConfiguredMarketplacePluginSummary>,
}

Expand Down Expand Up @@ -797,6 +798,7 @@ impl PluginsManager {
(!plugins.is_empty()).then_some(ConfiguredMarketplaceSummary {
name: marketplace.name,
path: marketplace.path,
display_name: marketplace.display_name,
plugins,
})
})
Expand Down
4 changes: 4 additions & 0 deletions codex-rs/core/src/plugins/manager_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,7 @@ enabled = false
tmp.path().join("repo/.agents/plugins/marketplace.json"),
)
.unwrap(),
display_name: None,
plugins: vec![
ConfiguredMarketplacePluginSummary {
id: "enabled-plugin@debug".to_string(),
Expand Down Expand Up @@ -1043,6 +1044,7 @@ async fn list_marketplaces_includes_curated_repo_marketplace() {
curated_root.join(".agents/plugins/marketplace.json"),
r#"{
"name": "openai-curated",
"display_name": "ChatGPT Official",
"plugins": [
{
"name": "linear",
Expand Down Expand Up @@ -1077,6 +1079,7 @@ async fn list_marketplaces_includes_curated_repo_marketplace() {
name: "openai-curated".to_string(),
path: AbsolutePathBuf::try_from(curated_root.join(".agents/plugins/marketplace.json"))
.unwrap(),
display_name: Some("ChatGPT Official".to_string()),
plugins: vec![ConfiguredMarketplacePluginSummary {
id: "linear@openai-curated".to_string(),
name: "linear".to_string(),
Expand Down Expand Up @@ -1281,6 +1284,7 @@ enabled = true
tmp.path().join("repo/.agents/plugins/marketplace.json"),
)
.unwrap(),
display_name: None,
plugins: vec![ConfiguredMarketplacePluginSummary {
id: "sample-plugin@debug".to_string(),
name: "sample-plugin".to_string(),
Expand Down
5 changes: 5 additions & 0 deletions codex-rs/core/src/plugins/marketplace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct ResolvedMarketplacePlugin {
pub struct MarketplaceSummary {
pub name: String,
pub path: AbsolutePathBuf,
pub display_name: Option<String>,
pub plugins: Vec<MarketplacePluginSummary>,
}

Expand Down Expand Up @@ -212,6 +213,7 @@ pub(crate) fn load_marketplace_summary(
Ok(MarketplaceSummary {
name: marketplace.name,
path: path.clone(),
display_name: marketplace.display_name,
plugins,
})
}
Expand Down Expand Up @@ -367,6 +369,9 @@ fn marketplace_root_dir(
#[derive(Debug, Deserialize)]
struct MarketplaceFile {
name: String,
#[serde(default)]
#[serde(alias = "displayName")]
display_name: Option<String>,
plugins: Vec<MarketplacePlugin>,
}

Expand Down
40 changes: 40 additions & 0 deletions codex-rs/core/src/plugins/marketplace_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ fn list_marketplaces_returns_home_and_repo_marketplaces() {
path:
AbsolutePathBuf::try_from(home_root.join(".agents/plugins/marketplace.json"),)
.unwrap(),
display_name: None,
plugins: vec![
MarketplacePluginSummary {
name: "shared-plugin".to_string(),
Expand All @@ -163,6 +164,7 @@ fn list_marketplaces_returns_home_and_repo_marketplaces() {
path:
AbsolutePathBuf::try_from(repo_root.join(".agents/plugins/marketplace.json"),)
.unwrap(),
display_name: None,
plugins: vec![
MarketplacePluginSummary {
name: "shared-plugin".to_string(),
Expand Down Expand Up @@ -245,6 +247,7 @@ fn list_marketplaces_keeps_distinct_entries_for_same_name() {
MarketplaceSummary {
name: "codex-curated".to_string(),
path: AbsolutePathBuf::try_from(home_marketplace).unwrap(),
display_name: None,
plugins: vec![MarketplacePluginSummary {
name: "local-plugin".to_string(),
source: MarketplacePluginSourceSummary::Local {
Expand All @@ -258,6 +261,7 @@ fn list_marketplaces_keeps_distinct_entries_for_same_name() {
MarketplaceSummary {
name: "codex-curated".to_string(),
path: AbsolutePathBuf::try_from(repo_marketplace.clone()).unwrap(),
display_name: None,
plugins: vec![MarketplacePluginSummary {
name: "local-plugin".to_string(),
source: MarketplacePluginSourceSummary::Local {
Expand Down Expand Up @@ -324,6 +328,7 @@ fn list_marketplaces_dedupes_multiple_roots_in_same_repo() {
name: "codex-curated".to_string(),
path: AbsolutePathBuf::try_from(repo_root.join(".agents/plugins/marketplace.json"))
.unwrap(),
display_name: None,
plugins: vec![MarketplacePluginSummary {
name: "local-plugin".to_string(),
source: MarketplacePluginSourceSummary::Local {
Expand All @@ -337,6 +342,41 @@ fn list_marketplaces_dedupes_multiple_roots_in_same_repo() {
);
}

#[test]
fn list_marketplaces_reads_marketplace_display_name() {
let tmp = tempdir().unwrap();
let repo_root = tmp.path().join("repo");

fs::create_dir_all(repo_root.join(".git")).unwrap();
fs::create_dir_all(repo_root.join(".agents/plugins")).unwrap();
fs::write(
repo_root.join(".agents/plugins/marketplace.json"),
r#"{
"name": "openai-curated",
"display_name": "ChatGPT Official",
"plugins": [
{
"name": "local-plugin",
"source": {
"source": "local",
"path": "./plugin"
}
}
]
}"#,
)
.unwrap();

let marketplaces =
list_marketplaces_with_home(&[AbsolutePathBuf::try_from(repo_root).unwrap()], None)
.unwrap();

assert_eq!(
marketplaces[0].display_name,
Some("ChatGPT Official".to_string())
);
}

#[test]
fn list_marketplaces_resolves_plugin_interface_paths_to_absolute() {
let tmp = tempdir().unwrap();
Expand Down
Loading