mirror of
https://github.com/openai/codex.git
synced 2026-09-09 15:58:47 +00:00
Materialize curated marketplace with known marketplaces
This commit is contained in:
@@ -19,7 +19,10 @@ use crate::config::Config;
|
||||
use codex_login::AuthManager;
|
||||
use codex_login::default_client::build_reqwest_client;
|
||||
|
||||
use super::OPENAI_CURATED_MARKETPLACE_NAME;
|
||||
use super::PluginsManager;
|
||||
use super::marketplace_install_root;
|
||||
use super::record_installed_marketplace_root;
|
||||
|
||||
const GITHUB_API_BASE_URL: &str = "https://api.github.com";
|
||||
const GITHUB_API_ACCEPT_HEADER: &str = "application/vnd.github+json";
|
||||
@@ -28,7 +31,6 @@ const CURATED_PLUGINS_BACKUP_ARCHIVE_API_URL: &str =
|
||||
"https://chatgpt.com/backend-api/plugins/export/curated";
|
||||
const OPENAI_PLUGINS_OWNER: &str = "openai";
|
||||
const OPENAI_PLUGINS_REPO: &str = "plugins";
|
||||
const CURATED_PLUGINS_RELATIVE_DIR: &str = ".tmp/plugins";
|
||||
const CURATED_PLUGINS_SHA_FILE: &str = ".tmp/plugins.sha";
|
||||
const CURATED_PLUGINS_BACKUP_ARCHIVE_FALLBACK_VERSION: &str = "export-backup";
|
||||
const CURATED_PLUGINS_GIT_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
@@ -60,7 +62,7 @@ struct CuratedPluginsBackupArchiveResponse {
|
||||
}
|
||||
|
||||
pub(crate) fn curated_plugins_repo_path(codex_home: &Path) -> PathBuf {
|
||||
codex_home.join(CURATED_PLUGINS_RELATIVE_DIR)
|
||||
marketplace_install_root(codex_home).join(OPENAI_CURATED_MARKETPLACE_NAME)
|
||||
}
|
||||
|
||||
pub(crate) fn read_curated_plugins_sha(codex_home: &Path) -> Option<String> {
|
||||
@@ -88,6 +90,7 @@ fn sync_openai_plugins_repo_with_transport_overrides(
|
||||
) -> Result<String, String> {
|
||||
match sync_openai_plugins_repo_via_git(codex_home, git_binary) {
|
||||
Ok(remote_sha) => {
|
||||
record_curated_marketplace_root(codex_home)?;
|
||||
emit_curated_plugins_startup_sync_metric("git", "success");
|
||||
emit_curated_plugins_startup_sync_final_metric("git", "success");
|
||||
Ok(remote_sha)
|
||||
@@ -101,6 +104,7 @@ fn sync_openai_plugins_repo_with_transport_overrides(
|
||||
);
|
||||
match sync_openai_plugins_repo_via_http(codex_home, api_base_url) {
|
||||
Ok(remote_sha) => {
|
||||
record_curated_marketplace_root(codex_home)?;
|
||||
emit_curated_plugins_startup_sync_metric("http", "success");
|
||||
emit_curated_plugins_startup_sync_final_metric("http", "success");
|
||||
Ok(remote_sha)
|
||||
@@ -131,11 +135,15 @@ fn sync_openai_plugins_repo_with_transport_overrides(
|
||||
let status = if result.is_ok() { "success" } else { "failure" };
|
||||
emit_curated_plugins_startup_sync_metric("export_archive", status);
|
||||
emit_curated_plugins_startup_sync_final_metric("export_archive", status);
|
||||
result.map_err(|export_err| {
|
||||
format!(
|
||||
match result {
|
||||
Ok(remote_sha) => {
|
||||
record_curated_marketplace_root(codex_home)?;
|
||||
Ok(remote_sha)
|
||||
}
|
||||
Err(export_err) => Err(format!(
|
||||
"git sync failed for curated plugin sync: {err}; GitHub HTTP sync failed for curated plugin sync: {http_err}; export archive sync failed for curated plugin sync: {export_err}"
|
||||
)
|
||||
})
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,6 +298,17 @@ fn startup_remote_plugin_sync_marker_path(codex_home: &Path) -> PathBuf {
|
||||
codex_home.join(STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE)
|
||||
}
|
||||
|
||||
fn record_curated_marketplace_root(codex_home: &Path) -> Result<(), String> {
|
||||
let repo_path = curated_plugins_repo_path(codex_home);
|
||||
record_installed_marketplace_root(codex_home, OPENAI_CURATED_MARKETPLACE_NAME, &repo_path)
|
||||
.map_err(|err| {
|
||||
format!(
|
||||
"failed to record curated marketplace root {}: {err}",
|
||||
repo_path.display()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn has_local_curated_plugins_snapshot(codex_home: &Path) -> bool {
|
||||
curated_plugins_repo_path(codex_home)
|
||||
.join(".agents/plugins/marketplace.json")
|
||||
|
||||
@@ -144,7 +144,7 @@ fn curated_plugins_repo_path_uses_codex_home_tmp_dir() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
assert_eq!(
|
||||
curated_plugins_repo_path(tmp.path()),
|
||||
tmp.path().join(".tmp/plugins")
|
||||
tmp.path().join(".tmp/marketplaces/openai-curated")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -254,6 +254,10 @@ exit 1
|
||||
assert!(repo_path.join(".git").is_dir());
|
||||
assert_curated_gmail_repo(&repo_path);
|
||||
assert_eq!(read_curated_plugins_sha(tmp.path()).as_deref(), Some(sha));
|
||||
let registry =
|
||||
std::fs::read_to_string(tmp.path().join(".tmp/known_marketplaces.json")).unwrap();
|
||||
assert!(registry.contains(r#""name": "openai-curated""#));
|
||||
assert!(registry.contains(r#""installLocation""#));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
|
||||
Reference in New Issue
Block a user