mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
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:
committed by
GitHub
Unverified
parent
104fc14956
commit
7bf95b39aa
@@ -47,10 +47,15 @@ pub use share::update_remote_plugin_share_targets;
|
||||
|
||||
pub const REMOTE_GLOBAL_MARKETPLACE_NAME: &str = "chatgpt-global";
|
||||
pub const REMOTE_WORKSPACE_MARKETPLACE_NAME: &str = "workspace-directory";
|
||||
pub const REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME: &str = "shared-with-me";
|
||||
pub const REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME: &str =
|
||||
"workspace-shared-with-me-private";
|
||||
pub const REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME: &str =
|
||||
"workspace-shared-with-me-unlisted";
|
||||
pub const REMOTE_GLOBAL_MARKETPLACE_DISPLAY_NAME: &str = "ChatGPT Plugins";
|
||||
pub const REMOTE_WORKSPACE_MARKETPLACE_DISPLAY_NAME: &str = "Workspace Directory";
|
||||
pub const REMOTE_SHARED_WITH_ME_MARKETPLACE_DISPLAY_NAME: &str = "Shared with me";
|
||||
pub const REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_DISPLAY_NAME: &str = "Shared with me";
|
||||
pub const REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_DISPLAY_NAME: &str =
|
||||
"Shared with me (unlisted)";
|
||||
|
||||
const REMOTE_PLUGIN_CATALOG_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
const REMOTE_PLUGIN_LIST_PAGE_LIMIT: u32 = 200;
|
||||
@@ -286,9 +291,9 @@ impl RemotePluginScope {
|
||||
fn from_marketplace_name(name: &str) -> Option<Self> {
|
||||
match name {
|
||||
REMOTE_GLOBAL_MARKETPLACE_NAME => Some(Self::Global),
|
||||
REMOTE_WORKSPACE_MARKETPLACE_NAME | REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME => {
|
||||
Some(Self::Workspace)
|
||||
}
|
||||
REMOTE_WORKSPACE_MARKETPLACE_NAME
|
||||
| REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME
|
||||
| REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME => Some(Self::Workspace),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -388,9 +393,11 @@ fn remote_plugin_canonical_marketplace_name(
|
||||
RemotePluginScope::Global => Ok(REMOTE_GLOBAL_MARKETPLACE_NAME),
|
||||
RemotePluginScope::Workspace => match workspace_plugin_discoverability(plugin)? {
|
||||
RemotePluginShareDiscoverability::Listed => Ok(REMOTE_WORKSPACE_MARKETPLACE_NAME),
|
||||
RemotePluginShareDiscoverability::Unlisted
|
||||
| RemotePluginShareDiscoverability::Private => {
|
||||
Ok(REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME)
|
||||
RemotePluginShareDiscoverability::Unlisted => {
|
||||
Ok(REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME)
|
||||
}
|
||||
RemotePluginShareDiscoverability::Private => {
|
||||
Ok(REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -462,43 +469,81 @@ pub async fn fetch_remote_marketplaces(
|
||||
};
|
||||
|
||||
for source in sources {
|
||||
let marketplace = match source {
|
||||
match source {
|
||||
RemoteMarketplaceSource::Global => {
|
||||
let scope = RemotePluginScope::Global;
|
||||
let (directory_plugins, installed_plugins) = tokio::try_join!(
|
||||
fetch_directory_plugins_for_scope(config, auth, scope),
|
||||
fetch_installed_plugins_for_scope(config, auth, scope),
|
||||
)?;
|
||||
build_remote_marketplace(
|
||||
if let Some(marketplace) = build_remote_marketplace(
|
||||
scope.marketplace_name(),
|
||||
scope.marketplace_display_name(),
|
||||
directory_plugins,
|
||||
installed_plugins,
|
||||
/*include_installed_only*/ true,
|
||||
)?
|
||||
)? {
|
||||
marketplaces.push(marketplace);
|
||||
}
|
||||
}
|
||||
RemoteMarketplaceSource::WorkspaceDirectory => {
|
||||
let scope = RemotePluginScope::Workspace;
|
||||
let directory_plugins =
|
||||
fetch_directory_plugins_for_scope(config, auth, scope).await?;
|
||||
build_remote_marketplace(
|
||||
if let Some(marketplace) = build_remote_marketplace(
|
||||
scope.marketplace_name(),
|
||||
scope.marketplace_display_name(),
|
||||
directory_plugins,
|
||||
workspace_installed_plugins.clone().unwrap_or_default(),
|
||||
/*include_installed_only*/ false,
|
||||
)?
|
||||
)? {
|
||||
marketplaces.push(marketplace);
|
||||
}
|
||||
}
|
||||
RemoteMarketplaceSource::SharedWithMe => {
|
||||
let private_plugins = fetch_shared_workspace_plugins(config, auth)
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter_map(|plugin| match workspace_plugin_discoverability(&plugin) {
|
||||
Ok(RemotePluginShareDiscoverability::Private) => Some(Ok(plugin)),
|
||||
Ok(RemotePluginShareDiscoverability::Listed)
|
||||
| Ok(RemotePluginShareDiscoverability::Unlisted) => None,
|
||||
Err(err) => Some(Err(err)),
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
if let Some(marketplace) = build_remote_marketplace(
|
||||
REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME,
|
||||
REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_DISPLAY_NAME,
|
||||
private_plugins,
|
||||
workspace_installed_plugins.clone().unwrap_or_default(),
|
||||
/*include_installed_only*/ false,
|
||||
)? {
|
||||
marketplaces.push(marketplace);
|
||||
}
|
||||
|
||||
let unlisted_installed_plugins = workspace_installed_plugins
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.filter_map(
|
||||
|plugin| match workspace_plugin_discoverability(&plugin.plugin) {
|
||||
Ok(RemotePluginShareDiscoverability::Unlisted) => Some(Ok(plugin)),
|
||||
Ok(RemotePluginShareDiscoverability::Listed)
|
||||
| Ok(RemotePluginShareDiscoverability::Private) => None,
|
||||
Err(err) => Some(Err(err)),
|
||||
},
|
||||
)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
if let Some(marketplace) = build_remote_marketplace(
|
||||
REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME,
|
||||
REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_DISPLAY_NAME,
|
||||
Vec::new(),
|
||||
unlisted_installed_plugins,
|
||||
/*include_installed_only*/ true,
|
||||
)? {
|
||||
marketplaces.push(marketplace);
|
||||
}
|
||||
}
|
||||
RemoteMarketplaceSource::SharedWithMe => build_remote_marketplace(
|
||||
REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME,
|
||||
REMOTE_SHARED_WITH_ME_MARKETPLACE_DISPLAY_NAME,
|
||||
fetch_shared_workspace_plugins(config, auth).await?,
|
||||
workspace_installed_plugins.clone().unwrap_or_default(),
|
||||
/*include_installed_only*/ false,
|
||||
)?,
|
||||
};
|
||||
if let Some(marketplace) = marketplace {
|
||||
marketplaces.push(marketplace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user