feat: support remote_sync for plugin install/uninstall. (#14878)

- Added forceRemoteSync to plugin/install and plugin/uninstall.
- With forceRemoteSync=true, we update the remote plugin status first,
then apply the local change only if the backend call succeeds.
- Kept plugin/list(forceRemoteSync=true) as the main recon path, and for
now it treats remote enabled=false as uninstall. We
will eventually migrate to plugin/installed for more precise state
handling.
This commit is contained in:
xl-openai
2026-03-16 21:37:27 -07:00
committed by GitHub
parent 49c2b66ece
commit 1d85fe79ed
17 changed files with 743 additions and 101 deletions

View File

@@ -1312,6 +1312,11 @@ async fn sync_plugins_from_remote_reconciles_cache_and_config() {
"linear/local",
"linear",
);
write_plugin(
&tmp.path().join("plugins/cache/openai-curated"),
"gmail/local",
"gmail",
);
write_plugin(
&tmp.path().join("plugins/cache/openai-curated"),
"calendar/local",
@@ -1325,6 +1330,9 @@ plugins = true
[plugins."linear@openai-curated"]
enabled = false
[plugins."gmail@openai-curated"]
enabled = false
[plugins."calendar@openai-curated"]
enabled = true
"#,
@@ -1358,10 +1366,13 @@ enabled = true
assert_eq!(
result,
RemotePluginSyncResult {
installed_plugin_ids: vec!["gmail@openai-curated".to_string()],
installed_plugin_ids: Vec::new(),
enabled_plugin_ids: vec!["linear@openai-curated".to_string()],
disabled_plugin_ids: vec!["gmail@openai-curated".to_string()],
uninstalled_plugin_ids: vec!["calendar@openai-curated".to_string()],
disabled_plugin_ids: Vec::new(),
uninstalled_plugin_ids: vec![
"gmail@openai-curated".to_string(),
"calendar@openai-curated".to_string(),
],
}
);
@@ -1371,11 +1382,9 @@ enabled = true
.is_dir()
);
assert!(
tmp.path()
.join(format!(
"plugins/cache/openai-curated/gmail/{TEST_CURATED_PLUGIN_SHA}"
))
.is_dir()
!tmp.path()
.join("plugins/cache/openai-curated/gmail")
.exists()
);
assert!(
!tmp.path()
@@ -1385,9 +1394,8 @@ enabled = true
let config = fs::read_to_string(tmp.path().join(CONFIG_TOML_FILE)).unwrap();
assert!(config.contains(r#"[plugins."linear@openai-curated"]"#));
assert!(config.contains(r#"[plugins."gmail@openai-curated"]"#));
assert!(config.contains("enabled = true"));
assert!(config.contains("enabled = false"));
assert!(!config.contains(r#"[plugins."gmail@openai-curated"]"#));
assert!(!config.contains(r#"[plugins."calendar@openai-curated"]"#));
let synced_config = load_config(tmp.path(), tmp.path()).await;
@@ -1405,7 +1413,7 @@ enabled = true
.collect::<Vec<_>>(),
vec![
("linear@openai-curated".to_string(), true, true),
("gmail@openai-curated".to_string(), true, false),
("gmail@openai-curated".to_string(), false, false),
("calendar@openai-curated".to_string(), false, false),
]
);