feat: Split shared workspace plugins by discoverability (#22425)

- Keep shared-with-me as the plugin/list request kind, but return
private plugins under workspace-shared-with-me-private.
- Add workspace-shared-with-me-unlisted for installed workspace plugins
with UNLISTED discoverability,
This commit is contained in:
xl-openai
2026-05-12 21:11:19 -07:00
committed by GitHub
parent 104fc14956
commit 7bf95b39aa
6 changed files with 177 additions and 51 deletions
@@ -1,6 +1,7 @@
use super::REMOTE_GLOBAL_MARKETPLACE_NAME;
use super::REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME;
use super::REMOTE_WORKSPACE_MARKETPLACE_NAME;
use super::REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME;
use super::REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME;
use super::RemotePluginCatalogError;
use super::RemotePluginScope;
use super::RemotePluginServiceConfig;
@@ -153,7 +154,11 @@ pub async fn sync_remote_installed_plugin_bundles_once(
BTreeSet::new(),
),
(
REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME.to_string(),
REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME.to_string(),
BTreeSet::new(),
),
(
REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME.to_string(),
BTreeSet::new(),
),
]);
@@ -298,7 +303,8 @@ fn remove_stale_remote_plugin_caches(
for marketplace_name in [
REMOTE_GLOBAL_MARKETPLACE_NAME,
REMOTE_WORKSPACE_MARKETPLACE_NAME,
REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME,
REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME,
REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME,
] {
let marketplace_root = codex_home.join(PLUGINS_CACHE_DIR).join(marketplace_name);
if !marketplace_root.exists() {
@@ -457,7 +463,11 @@ mod tests {
BTreeSet::new(),
),
(
REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME.to_string(),
REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME.to_string(),
BTreeSet::new(),
),
(
REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME.to_string(),
BTreeSet::new(),
),
]);
@@ -500,12 +510,12 @@ mod tests {
}
#[test]
fn stale_remote_plugin_cleanup_removes_shared_with_me_cache() {
fn stale_remote_plugin_cleanup_removes_private_shared_with_me_cache() {
let codex_home = tempfile::tempdir().expect("create codex home");
let cached_manifest = codex_home
.path()
.join(PLUGINS_CACHE_DIR)
.join(REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME)
.join(REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME)
.join("private-plugin")
.join("1.2.3")
.join(".codex-plugin")
@@ -522,7 +532,11 @@ mod tests {
BTreeSet::new(),
),
(
REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME.to_string(),
REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME.to_string(),
BTreeSet::new(),
),
(
REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME.to_string(),
BTreeSet::new(),
),
]);
@@ -531,9 +545,12 @@ mod tests {
codex_home.path(),
&installed_plugin_names_by_marketplace,
)
.expect("cleanup shared-with-me cache");
.expect("cleanup private shared-with-me cache");
assert_eq!(removed, vec!["private-plugin@shared-with-me".to_string()]);
assert_eq!(
removed,
vec!["private-plugin@workspace-shared-with-me-private".to_string()]
);
assert!(!cached_manifest.exists());
}
}
@@ -586,7 +586,7 @@ async fn list_remote_plugin_shares_fetches_created_workspace_plugins() {
vec![
RemotePluginShareSummary {
summary: RemotePluginSummary {
id: "demo-plugin@shared-with-me".to_string(),
id: "demo-plugin@workspace-shared-with-me-private".to_string(),
remote_plugin_id: "plugins_123".to_string(),
name: "demo-plugin".to_string(),
share_context: Some(RemotePluginShareContext {
@@ -625,7 +625,7 @@ async fn list_remote_plugin_shares_fetches_created_workspace_plugins() {
},
RemotePluginShareSummary {
summary: RemotePluginSummary {
id: "demo-plugin@shared-with-me".to_string(),
id: "demo-plugin@workspace-shared-with-me-private".to_string(),
remote_plugin_id: "plugins_456".to_string(),
name: "demo-plugin".to_string(),
share_context: Some(RemotePluginShareContext {