[codex] Add created-by-me remote plugin marketplace (#28203)

## Summary
- add the `created-by-me-remote` marketplace backed by paginated
`scope=USER` plugin directory and installed-plugin requests
- include USER plugins in installed-plugin caching, bundle sync, and
stale-cache cleanup without client-side discoverability filtering
- expose the marketplace through app-server v2 and regenerate the
protocol schemas

## Testing
- `cargo build -p codex-app-server --bin codex-app-server`
- production-auth `plugin/list` smoke test for `created-by-me-remote`
(returned the expected USER plugin as installed and enabled)
- `just test -p codex-core-plugins` (221 passed)
- `just test -p codex-app-server-protocol` (231 passed)
- `just test -p codex-app-server suite::v2::plugin_list::` (37 passed)
- `just fix -p codex-core-plugins -p codex-app-server-protocol -p
codex-app-server`
- `just fmt`
This commit is contained in:
Eric Ning
2026-06-15 22:07:07 +00:00
committed by GitHub
parent 040dafa32d
commit 709f19e111
15 changed files with 431 additions and 17 deletions
@@ -8,6 +8,7 @@ use codex_app_server_protocol::PluginShareTargetRole;
use codex_config::types::McpServerConfig;
use codex_core_plugins::OPENAI_CURATED_MARKETPLACE_NAME;
use codex_core_plugins::PluginListBackgroundTaskOptions;
use codex_core_plugins::remote::REMOTE_CREATED_BY_ME_MARKETPLACE_NAME;
use codex_core_plugins::remote::REMOTE_GLOBAL_MARKETPLACE_NAME;
use codex_core_plugins::remote::REMOTE_WORKSPACE_MARKETPLACE_NAME;
use codex_core_plugins::remote::REMOTE_WORKSPACE_SHARED_WITH_ME_MARKETPLACE_NAME;
@@ -156,6 +157,7 @@ fn remote_installed_plugin_visible_marketplaces(config: &Config) -> Vec<&'static
let mut marketplaces = Vec::new();
if config.features.enabled(Feature::RemotePlugin) {
marketplaces.push(REMOTE_GLOBAL_MARKETPLACE_NAME);
marketplaces.push(REMOTE_CREATED_BY_ME_MARKETPLACE_NAME);
}
marketplaces.push(REMOTE_WORKSPACE_MARKETPLACE_NAME);
if config.features.enabled(Feature::PluginSharing) {
@@ -552,6 +554,9 @@ impl PluginRequestProcessor {
let plugins_input = config.plugins_config_input();
let include_shared_with_me =
marketplace_kinds.contains(&PluginListMarketplaceKind::SharedWithMe);
let include_created_by_me_remote = marketplace_kinds
.contains(&PluginListMarketplaceKind::CreatedByMeRemote)
&& config.features.enabled(Feature::RemotePlugin);
let include_global_remote =
!explicit_marketplace_kinds && config.features.enabled(Feature::RemotePlugin);
let remote_plugin_service_config = RemotePluginServiceConfig {
@@ -667,6 +672,9 @@ impl PluginRequestProcessor {
if include_global_remote {
remote_sources.push(RemoteMarketplaceSource::Global);
}
if include_created_by_me_remote {
remote_sources.push(RemoteMarketplaceSource::CreatedByMeRemote);
}
if marketplace_kinds.contains(&PluginListMarketplaceKind::WorkspaceDirectory) {
remote_sources.push(RemoteMarketplaceSource::WorkspaceDirectory);
}
@@ -717,7 +725,11 @@ impl PluginRequestProcessor {
}
}
}
if include_local || include_shared_with_me || include_global_remote {
if include_local
|| include_created_by_me_remote
|| include_shared_with_me
|| include_global_remote
{
plugins_manager.maybe_start_plugin_list_background_tasks_for_config(
&plugins_input,
auth.clone(),