mirror of
https://github.com/openai/codex.git
synced 2026-04-30 09:26:44 +00:00
[codex] Add marketplace/remove app-server RPC (#17751)
## Summary Add a new app-server `marketplace/remove` RPC on top of the shared marketplace-remove implementation. This change: - adds `MarketplaceRemoveParams` / `MarketplaceRemoveResponse` to the app-server protocol - wires the new request through `codex_message_processor` - reuses the shared core marketplace-remove flow from the stacked refactor PR - updates generated schema files and adds focused app-server coverage ## Validation - `just write-app-server-schema` - `just fmt` - heavy compile/test coverage deferred to GitHub CI per request
This commit is contained in:
105
codex-rs/app-server/tests/suite/v2/marketplace_remove.rs
Normal file
105
codex-rs/app-server/tests/suite/v2/marketplace_remove.rs
Normal file
@@ -0,0 +1,105 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use app_test_support::McpProcess;
|
||||
use app_test_support::to_response;
|
||||
use codex_app_server_protocol::JSONRPCResponse;
|
||||
use codex_app_server_protocol::MarketplaceRemoveParams;
|
||||
use codex_app_server_protocol::MarketplaceRemoveResponse;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_config::MarketplaceConfigUpdate;
|
||||
use codex_config::record_user_marketplace;
|
||||
use codex_core::plugins::marketplace_install_root;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use pretty_assertions::assert_eq;
|
||||
use tempfile::TempDir;
|
||||
use tokio::time::timeout;
|
||||
|
||||
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
|
||||
fn configured_marketplace_update() -> MarketplaceConfigUpdate<'static> {
|
||||
MarketplaceConfigUpdate {
|
||||
last_updated: "2026-04-13T00:00:00Z",
|
||||
last_revision: None,
|
||||
source_type: "git",
|
||||
source: "https://github.com/owner/repo.git",
|
||||
ref_name: Some("main"),
|
||||
sparse_paths: &[],
|
||||
}
|
||||
}
|
||||
|
||||
fn write_installed_marketplace(codex_home: &std::path::Path, marketplace_name: &str) -> Result<()> {
|
||||
let root = marketplace_install_root(codex_home).join(marketplace_name);
|
||||
std::fs::create_dir_all(root.join(".agents/plugins"))?;
|
||||
std::fs::write(root.join(".agents/plugins/marketplace.json"), "{}")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn marketplace_remove_deletes_config_and_installed_root() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
record_user_marketplace(codex_home.path(), "debug", &configured_marketplace_update())?;
|
||||
write_installed_marketplace(codex_home.path(), "debug")?;
|
||||
let installed_root = marketplace_install_root(codex_home.path())
|
||||
.join("debug")
|
||||
.canonicalize()?;
|
||||
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let request_id = mcp
|
||||
.send_marketplace_remove_request(MarketplaceRemoveParams {
|
||||
marketplace_name: "debug".to_string(),
|
||||
})
|
||||
.await?;
|
||||
|
||||
let response: JSONRPCResponse = timeout(
|
||||
DEFAULT_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(request_id)),
|
||||
)
|
||||
.await??;
|
||||
let response: MarketplaceRemoveResponse = to_response(response)?;
|
||||
assert_eq!(
|
||||
response,
|
||||
MarketplaceRemoveResponse {
|
||||
marketplace_name: "debug".to_string(),
|
||||
installed_root: Some(AbsolutePathBuf::try_from(installed_root)?),
|
||||
}
|
||||
);
|
||||
|
||||
let config = std::fs::read_to_string(codex_home.path().join("config.toml"))?;
|
||||
assert!(!config.contains("[marketplaces.debug]"));
|
||||
assert!(
|
||||
!marketplace_install_root(codex_home.path())
|
||||
.join("debug")
|
||||
.exists()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn marketplace_remove_rejects_unknown_marketplace() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let request_id = mcp
|
||||
.send_marketplace_remove_request(MarketplaceRemoveParams {
|
||||
marketplace_name: "debug".to_string(),
|
||||
})
|
||||
.await?;
|
||||
|
||||
let err = timeout(
|
||||
DEFAULT_TIMEOUT,
|
||||
mcp.read_stream_until_error_message(RequestId::Integer(request_id)),
|
||||
)
|
||||
.await??;
|
||||
|
||||
assert_eq!(err.error.code, -32600);
|
||||
assert_eq!(
|
||||
err.error.message,
|
||||
"marketplace `debug` is not configured or installed",
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -17,6 +17,7 @@ mod external_agent_config;
|
||||
mod fs;
|
||||
mod initialize;
|
||||
mod marketplace_add;
|
||||
mod marketplace_remove;
|
||||
mod mcp_resource;
|
||||
mod mcp_server_elicitation;
|
||||
mod mcp_server_status;
|
||||
|
||||
Reference in New Issue
Block a user